導讀:自從宣佈Firefox下載統計是由SQLstream提供支援後,SQLstream團隊收到了很多關於SQLstream如何與Firefox下載統計整合的問題,SQLstream團隊成員Gary Gilbert專門寫了一篇博文,由伯樂線上整理編譯,希望本文能夠解答相關的一些疑問。
SQLstream伺服器執行SQL語句時與標準SQL一樣,只有當SQLstream頻繁執行查詢時才會實時分析到來的輸入資料。通過JDBC或者內建JDBC易於使用的工具向SQLstream提供SQL語句,接著SQL語句被編譯/預處理,通過排程器/優化器選擇一個存取計劃接入方案,然後由一個執行時引擎來執行該方案。SQLstream通過一些擴充套件與SQL2003以及SQL2008標準相容。其中的一個擴充套件在SELECT語句中包含了STREAM關鍵字。STREAM關鍵字表明這個語句的結果是一個連續的資料流而不是代表TIME表中的一個點。
SQLstream中的應用程式通過一組SQL CREATE STREAM 語句和非資料流的SQL VIEWS以及其他檢視組成。那些語句組合成一個管道。當描述一個管道時,我們使用上游來代表發起端的語句,下游代表離目的端接近語句.
在管道的中間,我們定了一個叫做FirefoxDownloadStream的流,這個資料流包含了被解析並有條件的下載事件相關的資料。這個資料流的宣告在一個表中是唯一的,不同的是這裡的物件型別是一個STREAM而不是TABLE。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
CREATE STREAM "FirefoxDownloadStream_" ( "download_type"VARCHAR(15), "utc_timestamp"TIMESTAMP, "product_name"VARCHAR(12), "product_version"VARCHAR(12), "product_major_version"VARCHAR(12), "product_os"VARCHAR(10), "locale_code"VARCHAR(5), "country_code"VARCHAR(2), "city_name"VARCHAR(32), "region_code"VARCHAR(2), "longitude"VARCHAR(8), "latitude"VARCHAR(8) ); |
這個資料流由SQL INSERT-SELECT 語句填充資料,這裡又一次使用了標準SQL語句。WHERE子句定義了Firefox的下載型別,包括第一次全新下載,對早期版本的完全升級,或是對早期版本的部分升級。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
INSERT INTO "FirefoxDownloadStream_" ("download_type", "utc_timestamp", "product_name", "product_version", "product_major_version", "product_os", "locale_code", "country_code", "city_name", "region_code", "longitude", "latitude" ) SELECT STREAM "dlType"AS "download_type", "dlTime"AS "utc_timestamp", "product"AS "product_name", "version"AS "product_version", "GetMajorVersion"("version") AS "product_major_version", "os"AS "product_os", "lang",AS "locale_code", "cc",AS "country_code", "city",AS "city_name", "rg",AS "region_code", CAST("latitude" AS VARCHAR(10)) AS "latitude", CAST("longitude" AS VARCHAR(10)) AS "longitude" FROM "FirefoxCountryFilter" WHERE (("dlType" IS NULL) OR ("dlType" = 'complete') OR ("dlType" = 'partial')); |
下載事件包含了每一次下載的用時。Mozilla有很多下載伺服器,為來自世界各地的Firefox下載請求提供服務。每個伺服器向一個公共的日誌檔案提供下載請求記錄,該日誌檔案由SQLstream“跟蹤”。每個下載需要的時間由客戶端的網路頻寬不同而有所差別,下載請求的先後順序可能會顛倒。在實際環境中,我們遇到的最大時間差會達到4秒。由於我們在一個很長的時間段來統計下載,所以我們確信將最後的下載請求到達的時間與最近的一次下載時間匹配是足夠的。
下面的SQL語句就是做這樣的調整。
1 2 3 4 5 |
CREATE OR REPLACE VIEW "FirefoxDownloadStream" AS SELECT STREAM MAX("utc_timestamp") OVER(ROWS UNBOUNDED PRECEDING) AS ROWTIME, * FROM "FirefoxDownloadStream_"; |
SQLstream將一個STREAM中的所有行都指定了一個ROWTIME。這個ROWTIME是一個單調遞增的SQL時間戳。在預設的情況下,ROWTIME使用UTC表示當前時間。多數應用程式需要將時間定義為與資料本身相關聯的相對時間。這裡AS ROWTIME子句負責為每一行中資料流內容關聯ROWTIME。在Mozilla 管道中,我們將”utc_timestamp”列中的最大值定為資料表中所有行的ROWTIME。管道中的分析部分通過標準的SQL語句實現。例如,每隔10秒依據每個產品、版本、國家、城市或地區等資訊計算下載次數。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
CREATE OR REPLACE VIEW "FirefoxStreamForLocationCounters" DESCRIPTION 'Compute product counters for a minute' AS SELECT STREAM "download_type", "product_name", "product_major_version", "product_version", "country_code", "region_code", "city_name", "latitude", "longitude", count(*) AS "count" FROM "FirefoxDownloadStream" F GROUP BY FLOOR(F.ROWTIME TO MINUTE), FLOOR(F.ROWTIME - INTERVAL '10' SECOND TO MINUTE), FLOOR(F.ROWTIME - INTERVAL '20' SECOND TO MINUTE), FLOOR(F.ROWTIME - INTERVAL '30' SECOND TO MINUTE), FLOOR(F.ROWTIME - INTERVAL '40' SECOND TO MINUTE), FLOOR(F.ROWTIME - INTERVAL '50' SECOND TO MINUTE), "product_name", "download_type", "product_major_version", "product_version", "country_code", "region_code", "city_name", "latitude", "longitude"; |
這裡有一個相似的檢視宣告為每個產品做類似的計算。自週二以後,所有的重心都轉移到Firefox4.0的下載統計。第二個檢視允許Mozilla根據平臺來統計下載的詳細資訊包括之前(以及未來的)Firefox版本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
CREATE OR REPLACE VIEW "FirefoxStreamForProductCounters" DESCRIPTION 'Compute product counters for a minute' AS SELECT STREAM "download_type", "product_name", "product_major_version", "product_version", "product_os", count(*) AS "count" FROM "FirefoxDownloadStream" F GROUP BY FLOOR(F.ROWTIME TO MINUTE), FLOOR(F.ROWTIME - INTERVAL '10' SECOND TO MINUTE), FLOOR(F.ROWTIME - INTERVAL '20' SECOND TO MINUTE), FLOOR(F.ROWTIME - INTERVAL '30' SECOND TO MINUTE), FLOOR(F.ROWTIME - INTERVAL '40' SECOND TO MINUTE), FLOOR(F.ROWTIME - INTERVAL '50' SECOND TO MINUTE), "product_name", "download_type", "product_major_version", "product_version", "product_os"; |
每個檢視(FirefoxStreamForLocationCounters 和 FirefoxStreamForProductCountersview)都是基於 FirefoxDownloadStream。應用程式可以通過已經定義的資料流或檢視、其他VIEW或者INSERT…SELECT來訪問資料。
解決方案中的一個元件是我們叫做“HBaseAgent”的一段程式碼。這個代理使用JDBC介面來訪問SQLstream,向所有提到的包含位置和產品計數器10秒下載計數的檢視發起一個SELECT * FROM查詢。HBaseAgent 將取到的每一行資料對映到Mozilla定義的HBase模式中。
我在Firefox4開始下載後24小時寫下了這篇部落格。到目前為止Firefox4有8百萬次下載(注:截至本文釋出時,火狐4下載量已超過2.18億)。這是Mozilla令人興奮的一天,我向所有的開發者發出真摯的祝賀。我也很開心SQLstream在這裡能夠在其中貢獻自己的一份力。
編注1:UTC是協調世界時(Universal Time Coordinated)的英文縮寫,是由國際無線電諮詢委員會規定和推薦,並由國際時間局(BIH)負責保持的以秒為基礎的時間標度。UTC相當於本初子午線(即經度0°)上的平均太陽時,過去曾用格林威治平均時(GMT)來表示。
編注2:關於原文作者Gary Gilbert,他是NonStop SQL的原始架構師之一。
如需轉載,但請註明原文/譯文出處、譯文超連結和譯者等資訊,否則視為侵權,謝謝合作!