导读:自从宣布是由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。代码:
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的下载类型,包括第一次全新下载,对早期版本的完全升级,或是对早期版本的部分升级。
代码:
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语句就是做这样的调整。代码:
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秒依据每个产品、版本、国家、城市或地区等信息计算下载次数。
代码:
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版本。
代码:
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模式中。Firefox实时下载监控 - 第2天
我在Firefox4开始下载后24小时写下了这篇博客。到目前为止Firefox4有8百万次下载(注:截至本文发布时,火狐4下载量已超过2.18亿)。这是Mozilla令人兴奋的一天,我向所有的开发者发出真挚的祝贺。我也很开心SQLstream在这里能够在其中贡献自己的一份力。
编注1:UTC是协调世界时(Universal Time Coordinated)的英文缩写,是由国际无线电咨询委员会规定和推荐,并由国际时间局(BIH)负责保持的以秒为基础的时间标度。UTC相当于本初子午线(即经度0°)上的平均太阳时,过去曾用格林威治平均时(GMT)来表示。 编注2:关于原文作者Gary Gilbert,他是NonStop SQL的原始架构师之一。
原文地址:。