用SQL分析数据流
越来越多的公司在采用流处理技术,并将现有的批处理应用程序迁移到流处理或者为新的应用设计流处理方案。其中许多应用程序专注于分析流数据。分析的数据流来源广泛,如数据库交易,点击,传感器测量或物联网设备。
Apache Flink非常适合流式分析,因为它提供了事件时间语义支持,恰一次的处理,并同时实现了高吞吐和低延迟。由于这些特性,Flink能够近乎实时地从大量输入流计算确切的和确定性的结果,同时在出现故障时提供恰一次处理的语义。
Flink的流处理核心API,DataStream API,非常具有表现力,并为许多常见操作提供原语。除了其他功能之外,它还提供高度可定制的窗口逻辑,具有不同性能特性的不同状态原语,用于注册和响应定时器的钩子,以及用于向外部系统提供高效异步请求的工具。另一方面,许多流分析应用程序遵循类似的模式,并且不需要DataStream API提供的表达级别。他们可以使用特定领域语言以更自然和简洁的方式表达。众所周知,SQL是数据分析的事实标准。对于流式分析,SQL可以让更多的人在更短的时间内在数据流上开发应用程序。但是,还没有开源流处理器提供全面良好的SQL支持。
为什么Streams上的SQL是一个大问题?
由于许多原因,SQL是数据分析中使用最广泛的语言:
• SQL是声明式的:你指定你想要的,但不知道如何计算它。
• SQL可以得到有效优化:优化器会生成一个良好的执行计划来计算结果。
• 可以高效地评估SQL:处理引擎确切地知道要计算什么以及如何有效地执行此操作。
• 最后,大家都知道,许多工具都会讲SQL。
因此,能够使用SQL处理和分析数据流,使流处理技术可供更多用户使用。此外,由于SQL的声明性和自动优化的潜力,它大大减少了开发高效流分析应用程序的时间和精力。
但是,SQL(以及关系数据模型和代数)设计的时候并没有考虑到流式数据。关系是(多)集合,而不是无限的元组序列。在执行SQL查询时,传统的数据库系统和查询引擎将读取并处理完整可用的数据集,并生成固定大小的结果。相反,数据流不断提供新的记录,使得数据随着时间的推移而到达。因此,流式查询必须持续处理到达的数据,而不是“完整的数据”。
这就是说,用SQL处理流并不是不可能的。一些关系数据库系统具有物化视图的急切维护功能,这类似于评估数据流上的SQL查询。物化视图与常规(虚拟)视图一样被定义为SQL查询。但是,物化视图查询的结果实际上是存储(或物化)在内存或磁盘上的,这样查询不需要在查询时即时计算。为了防止物化视图变旧,数据库系统需要在其基本关系(定义查询中引用的表)被修改时更新视图。如果将视图基础关系的修改视为修改流(或者视为变更日志流),很明显就是在流上的物化视图为何和sql在某种程度上是相关的。
FlinkAPI:表API和SQL
自2016年8月发布1.1.0版本以来,Flink具有两种语义等效的关系API,嵌入语言(language-embedded)的Table API(用于Java和Scala)和标准SQL。这两个API都被设计为实时处理和离线批处理的统一API。这意味着,
无论其输入是静态批量数据还是流式数据,查询都会产生完全相同的结果。
出于多种原因,流和批处理的统一API非常重要。首先,用户只需要学习一个API来处理静态和流式数据。此外,可以使用相同的查询来分析批量和流式数据,从而可以在同一查询中共同时分析历史数据和实时数据。在目前的状态下,我们尚未实现批量和流式语义的完全统一,但社区在实现这一目标方面正取得很好的进展。
以下代码片段显示了两个等效的Table API和SQL查询,这些查询计算温度传感器测量流上简单的窗口集合。SQL查询的语法基于Apache Calcite的分组窗口函数的语法,并将在Flink的1.3.0版中得到支持。