Web 应用程序以惊人的速度产生数据,并且随着 Web 在我们的生活中变得越来越中心,这些速度每年都在复合增长。其他数据来源,如环境监测和基于位置的服务,正迅速扩展成为我们日常体验的一部分。即使吞吐量在增加,用户和企业主也期望以越来越低的延迟看到他们的数据。计算机硬件的进步(更便宜的内存、更便宜的磁盘和更多的处理核心)在一定程度上有所帮助,但不足以跟上吞吐量上升和延迟降低的双重需求。
为 Web 应用程序提供支持的技术需要相当简单,原因有两个:首先,因为必须能够快速发展 Web 应用程序,然后以最小的麻烦大规模部署它;其次,因为编写 Web 应用程序的人员是通才,并且不准备学习系统程序员使用的那种复杂、难以调整的技术。
流式查询引擎是一种新技术,擅长处理快速流动的数据并以低延迟产生结果。它起源于数据库研究社区,因此具有一些使关系数据库流行的特征,但它绝对不是数据库。在数据库中,数据首先到达并存储在磁盘上;然后用户将查询应用于存储的数据。在流式查询引擎中,查询在数据之前到达。数据流经许多持续执行的查询,转换后的数据流出到应用程序。可以说,关系数据库处理静态数据,而流式查询引擎处理动态数据。
表是关系数据库中的关键原语。表填充了记录,每个记录都具有相同的记录类型,由许多命名的、强类型的列定义。记录没有固有的排序。查询(通常用 SQL 表示)从一个或多个表中检索记录,并使用一小组强大的关系运算符转换它们。
流是流式查询引擎中对应的原语。流具有记录类型,就像表一样,但记录流经流而不是被存储。流式系统中的记录本质上是有序的,事实上,每个记录都有一个时间戳,指示它何时创建。关系数据库支持的关系操作在流式系统中具有类似物,并且足够相似,以至于可以使用 SQL 来编写流式查询。
为了说明流式查询引擎如何解决涉及动态数据的问题,请考虑以下示例。
假设我们要监控网站上最受欢迎的页面。每个 Web 服务器请求都会生成一行到 Web 服务器的日志文件中,描述时间、页面的 URI 和请求者的 IP 地址;适配器可以持续解析日志文件,并用记录填充流。此查询计算每分钟每个页面的请求数,如表 1 所示
SELECT STREAM ROWTIME, uri, COUNT(*)
FROM PageRequests
GROUP BY FLOOR(ROWTIME TO MINUTE), uri;
ROWTIME | URI | COUNT(*) |
---|---|---|
10:00:00 | /index.html | 15 |
10:00:00 | /images/logo.png | 19 |
10:00:00 | /orders.html | 6 |
10:01:00 | /index.html | 20 |
10:01:00 | /images/logo.png | 18 |
10:01:00 | /sitemap.html | 2 |
... |
此示例以 SQLstream 的查询语言表示,本文中的其他示例也是如此。该语言是标准 SQL 加上流式扩展。4 其他流式查询引擎具有类似的功能。
此特定查询中使用的唯一 SQL 扩展是 STREAM
关键字和 ROWTIME
系统列。如果删除 STREAM
关键字并将 PageRequests
转换为具有名为 ROWTIME
列的表,则可以在 Oracle 或 MySQL 等传统数据库中执行该查询。该查询将分析直到当前时刻为止发生的所有请求。但是,如果 PageRequests
是流,则 STREAM
关键字告诉 SQLstream 连接到 PageRequests
流并将操作应用于所有未来记录。流式查询永远运行。
每分钟,此查询都会发出一组行,总结该分钟内每个页面的流量。时间戳为 10:00:00 的输出行总结了 10:00 到 10:01 之间的所有请求(包括 10:00 端点但不包括 10:01)。PageRequests
流中的行按其 ROWTIME
系统列排序,因此 10:00:00 输出行实际上是通过时间戳为 10:01:00 或之后的第一个行的到达而推送出来的。流式查询引擎倾向于仅在新数据到达时才处理数据并交付结果,因此据说它使用基于推送的处理。这与关系数据库的基于拉取的处理方法形成对比,在基于拉取的处理方法中,应用程序必须重复轮询以获取新结果。
下一个示例计算请求数远高于正常的 URI。首先,PageRequestsWithCount
视图计算过去一小时内每个 URI 的每小时请求数,以及过去 24 小时的平均值。然后,查询选择过去一小时的速率超过过去 24 小时每小时速率三倍以上的 URI。
CREATE VIEW PageRequestsWithCount AS
SELECT STREAM ROWTIME,
uri,
COUNT(*) OVER lastHour AS hourlyRate,
COUNT(*) OVER lastDay / 24 AS hourlyRateLastDay
FROM PageRequests
WINDOW lastHour AS (
PARTITION BY uri
RANGE INTERVAL '1' HOUR PRECEDING)
lastDay AS (
PARTITION BY uri
RANGE INTERVAL '1' DAY PRECEDING);
SELECT STREAM *
FROM PageRequestsWithCount
WHERE rate > hourlyRateLastDay * 3;
与之前的查询(使用 GROUP BY
子句将许多记录聚合为每个时间段的总数)不同,此查询使用窗口聚合表达式(聚合函数 OVER
窗口)将分析值添加到每一行。由于每一行都用其过去一小时和一天的统计数据进行注释,因此您无需等待一批行完成。您可以使用这样的查询来持续填充您网站上的“最受欢迎页面”列表,或者电子商务网站可以使用它来检测销量高于正常水平的产品。
数据库和流式查询引擎具有相似的 SQL 语义,但如果您将这两个系统用于涉及动态数据的问题,它们的行为会非常不同。为什么流式查询引擎对于此类问题更有效率?为了回答这个问题,了解其渊源有所帮助。
有些人使用术语流式数据库,这会误导性地暗示系统正在存储数据。也就是说,流式查询引擎与数据库有着非常密切的家族联系。流式查询引擎的根源在于数据库研究,特别是斯坦福 STREAMS 项目1、麻省理工学院/布朗大学/布兰代斯大学的 Aurora 项目2 和伯克利的 Telegraph 项目3。流式查询引擎基于关系数据库所基于的关系模型,正如我们将看到的,这些基础为它们提供了力量、灵活性和行业认可。
关系模型最初由 E. F. Codd 于 1970 年描述,是一种描述数据库结构的简单而统一的方式。它由关系(记录的命名集合)和一组用于组合这些关系的简单运算符组成:select, project, join, aggregate,
和 union
。关系数据库自然地强制执行数据独立性,即数据的逻辑结构和物理表示之间的分离。由于查询编写者不知道数据是如何物理组织的,因此查询优化器是关系数据库的基本组件,用于在查询的许多可能算法中进行选择。
SQL 于 1970 年代后期首次推向市场。有些人说它在理论上不够纯粹(并且此后已扩展到包含非关系概念,如对象和嵌套表),但 SQL 仍然体现了关系模型的关键原则。它是声明性的,这使得查询能够被优化,因此您(或系统)可以在不重写应用程序的情况下调整应用程序。因此,您可以将新数据库模式的调整推迟到应用程序基本编写完成之后,并且可以安全地重构现有数据库模式。SQL 简单、可靠且容错性强,并且许多开发人员都理解它。
流将时间维度引入到关系模型中。您仍然可以应用基本运算符(select, project, join,
等等),但您也可以问,“如果我在一秒钟前执行了该 join
查询,而我现在再次执行它,结果会有什么不同?”
这使我们能够以非常不同的方式处理问题。作为一个类比,考虑一下您将如何测量在高速公路上行驶的汽车的速度。您可能会向窗外看一个里程标记,记下时间,当您到达下一个里程标记时,将里程标记之间的距离除以经过的时间。或者,您可以使用速度计,这是一种设备,其中指针的移动基于生成的电流,该电流与汽车车轮的角速度成正比,而角速度又与汽车的速度成正比。里程标记方法将位置和时间转换为速度,而速度计直接使用一组与速度成正比的量来测量速度。
位置和速度是相关的量;用微积分的语言来说,速度是位置相对于时间的微分。类似地,流是表的时微分。正如速度计是测量汽车速度问题的更合适的解决方案一样,对于涉及快速到达的、时间相关的数据的数据处理应用程序,流式查询引擎通常比关系数据库效率更高。
为什么流式查询引擎对于动态数据问题比关系数据库更有效率?
首先,系统表达问题的方式非常不同。数据库存储数据,应用程序向数据触发查询(和事务)。流式查询引擎存储查询,外部世界向查询触发数据。没有真正的事务,只有数据流经系统。
数据库需要加载数据并对其建立索引,对整个数据集运行查询,并减去先前的结果。流式查询系统仅处理新数据。它仅保存它需要的数据(例如,最新的分钟),并且由于这通常很容易放入内存,因此不需要磁盘 I/O。
关系数据库在所有数据都同等重要的假设下运行,但在业务应用程序中,一分钟前发生的事情通常比昨天发生的事情更重要,并且比一年前发生的事情重要得多。随着数据库的增长,它需要将大型数据集分布在磁盘上并创建索引,以便可以在恒定时间内访问所有数据。流式查询引擎的工作集更小,可以保存在内存中;并且由于查询包含窗口规范并且在数据到达之前创建,因此流式查询引擎不必猜测要存储哪些数据。
流式查询引擎对于动态数据还具有其他固有的优势:减少并发控制开销以及异步处理数据带来的效率。由于数据库正在写入其他应用程序可以读取和写入的数据结构,因此它需要并发控制机制;在流式查询引擎中,没有锁争用,因为来自所有应用程序的传入数据都放置在队列中,并在流式查询引擎准备好时进行处理。
换句话说,流式查询引擎异步处理数据。异步处理是许多高性能服务器应用程序(从事务处理到电子邮件处理,以及 Web 爬网和索引编制)的一个特性。它允许系统改变其工作单元——从系统负载较轻时的每次一条记录到负载较重时的多行批处理——以实现诸如引用局部性之类的效率优势。人们可能认为异步系统具有较慢的响应时间,因为它“在它感觉合适时”处理数据,但是异步系统可以在低得多的系统负载下实现给定的吞吐量,因此比同步系统具有更好的响应时间。关系数据库不仅是同步的,而且还倾向于迫使应用程序的其余部分进入每次一条记录的模式。
现在应该清楚的是,基于推送的处理对于动态数据更有效率;但是,流式查询引擎不是实现它的唯一方法。流式 SQL 并没有使以前不可能的事情成为可能。例如,您可以使用消息总线、以 XML 编码的消息和过程语言来实现许多问题,以从总线上获取消息、转换它们并将它们放回总线上。但是,您会遇到性能问题(解析 XML 很昂贵)、可伸缩性问题(如何将问题分解为可以由单独的线程或机器处理的子问题)、算法问题(如何有效地组合两个流、在公共键上关联两个流或聚合流)以及配置问题(如果其中一个规则发生更改,如何通知系统的所有组件)。大多数现代应用程序选择使用关系数据库管理系统来避免直接处理数据文件,而使用流式查询系统的原因非常相似。
正如关系数据库是一种横向技术,用于从服务 Web 页面到事务处理和数据仓库的所有事物一样,流式 SQL 系统正被应用于各种问题。
一个应用领域称为 CEP(复杂事件处理)。CEP 查询在单个流或多个流上查找事件序列,这些事件序列共同匹配一个模式并创建企业感兴趣的“复杂事件”。CEP 的应用包括欺诈检测和电子交易。
CEP 已在行业内被用作描述流式查询系统整个领域的通用术语。这是令人遗憾的,因为它导致了基于 SQL 和非 SQL 供应商之间的宗教战争,并且由于过度关注金融服务应用,导致其他应用领域被忽视。
上面的点击流查询是监控应用程序的一个简单示例。这种应用程序查找代表正在运行的业务的交易中的趋势,并在事情运行不顺畅时向运营人员发出警报。监控查询通过聚合大量记录并查找趋势来发现洞察力,这与 CEP 查询查找各个事件之间的模式形成对比。监控应用程序还可以填充实时仪表板,这是企业的汽车速度计、温度计和油压表的等效物。
由于它们通用的 SQL 语言,流式查询与数据仓库具有天然的协同作用。数据仓库保存了“后视镜”业务分析所需的大量历史数据,而流式查询系统持续填充数据仓库并提供前瞻性洞察力以“引导公司”。
流式查询系统执行与 ETL(提取、转换、加载)工具相同的功能,但持续运行。传统的 ETL 过程是作为批处理作业调用的一系列步骤。ETL 过程的周期时间限制了数据仓库的最新程度,并且很难将该周期时间缩短到几分钟以下。例如,最数据密集型的步骤是通过在数据仓库上发出查询来执行的:在维度表中查找现有值,例如以前购买过的客户,以及填充汇总表。流式查询系统可以缓存执行这些步骤所需的信息,从而卸载数据仓库,而 ETL 过程的生命周期太短,无法从缓存中受益。
图 1 显示了实时商业智能系统的架构。除了执行持续 ETL 之外,流式查询系统还填充业务指标仪表板,在指标超出可接受范围时生成警报,并主动维护基于数据仓库的 OLAP(在线分析处理)服务器的缓存。
如今,许多“动态数据”通过面向消息的中间件传输。与中间件一样,流式查询系统可以可靠地、以高吞吐量和低延迟交付消息;此外,它们可以应用 SQL 操作来路由、组合和转换动态消息。随着流式查询系统的成熟,我们可能会看到它们逐步进入中间件的角色,并通过在整个过程中应用 SQL 来模糊消息传递、持续 ETL 和数据库技术之间的界限。
流式查询引擎基于与关系数据库相同的技术,但旨在处理动态数据。流式查询引擎可以比数据库更有效地解决一些常见问题,因为它们匹配了问题基于时间的性质,它们仅保留解决问题所需的数据工作集,并且它们异步且持续地处理数据。
由于它们共享的 SQL 语言,流式查询引擎和关系数据库可以协作解决监控和实时商业智能中的问题。SQL 使它们能够被大量具有 SQL 专业知识的人员访问。
正如数据库可以应用于从事务处理到数据仓库的广泛问题一样,流式查询系统可以支持诸如企业消息传递、复杂事件处理、持续数据集成和仍在发现的新应用领域等模式。
喜欢它,讨厌它?请告诉我们
Julian Hyde 是 SQLstream 的首席架构师,SQLstream 是一种流式查询引擎。他还是 Mondrian 的首席开发人员,Mondrian 是最流行的开源关系 OLAP 引擎,也是 Pentaho 开源 BI 套件的一部分。作为关系技术(包括查询优化和流式执行)的专家,他将位图索引引入 Oracle,并领导了 Broadbase 分析 DBMS 的开发。他拥有剑桥大学的学位
© 2009 1542-7730/09/1200 $10.00
最初发表于 Queue vol. 7, no. 11—
在 数字图书馆 中评论本文
Qian Li, Peter Kraft - 事务和无服务器天生一对
数据库支持的应用程序是无服务器计算令人兴奋的新领域。通过紧密集成应用程序执行和数据管理,事务性无服务器平台实现了许多在现有无服务器平台或基于服务器的部署中不可能实现的新功能。
Pat Helland - 身份的各种称谓
新兴的系统和协议都在收紧和放松我们对身份的概念,这很好!它们使完成工作变得更容易。REST、IoT、大数据和机器学习都围绕着有意保持灵活且有时模糊的身份概念。身份的概念是我们分布式系统的基本机制的基础,包括可互换性、幂等性和不变性。
Raymond Blum, Betsy Beyer - 实现数字永恒
当今的信息时代正在为世界依赖的数据创造新的用途和新的管理方式。世界正在远离熟悉的物理人工制品,转向更接近本质信息的新表示手段。我们需要流程来确保知识的完整性和可访问性,以保证历史将被知晓和真实。
Graham Cormode - 数据速写
您是否曾经感到被源源不断的信息淹没?似乎不断涌入的新电子邮件和短信需要持续关注,还有电话要接听、文章要阅读、敲门声要回应。将这些碎片组合在一起以跟踪重要内容可能是一个真正的挑战。为了应对这一挑战,流式数据处理模型越来越受欢迎。其目标不再是捕获、存储和索引每一分钟的事件,而是快速处理每个观察结果,以便创建当前状态的摘要。