携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 7 天,点击查看活动详情。
上篇文章我们简述了Flink的基础知识,本篇文章我们主要论述一下Flink的核心API--Flink SQL的基础知识和编程。
1. 前言
如果用户需要同时流计算、批处理的场景下,用户需要维护两套业务代码,开发人员也要维护两套技术栈,非常不方便。
Flink 社区很早就设想过将批数据看作一个有界流数据,将批处理看作流计算的一个特例,从而实现流批统一,F经过开发人员的多轮讨论后,基本敲定了 Flink 未来的技术架构。
Apache Flink 有两种关系型 API 来做流批统一处理:Table API 和 SQL。
Table API 是用于 Scala 和 Java 语言的查询API,它可以用一种非常直观的方式来组合使用选取、过滤、join 等关系型算子。
Flink SQL 是基于 Apache Calcite 来实现的标准 SQL。这两种 API 中的查询对于批(DataSet)和流(DataStream)的输入有相同的语义,也会产生同样的计算结果。
Table API 和 SQL 两种 API 是紧密集成的,以及 DataStream 和 DataSet API。你可以在这些 API 之间,以及一些基于这些 API 的库之间轻松的切换。比如,你可以先用 CEP 从 DataStream 中做模式匹配,然后用 Table API 来分析匹配的结果;或者你可以用 SQL 来扫描、过滤、聚合一个批式的表,然后再跑一个 Gelly 图算法 来处理已经预处理好的数据。
2. 核心概念
Flink 的 Table API 和 SQL 是流批统一的 API。这意味着 TableAPI & SQL 在无论有限的批式输入还是无限的流式输入下,都具有相同的语义。因为传统的关系代数以及 SQL 最开始都是为了批式处理而设计的,关系型查询在流式场景下不如在批式场景下容易理解。
2.1 动态表
动态表(Dynamic Tables) 是 Flink 的支持流数据的 Table API和SQL 的核心概念。
与表示批处理数据的静态表不同,动态表是 随时间变化 的。可以像查询 静态批处理表 一样查询它们。查询动态表将生成一个 连续查询(Continuous Query)。一个连续查询永远不会终止,结果会生成一个动态表。查询不断更新其(动态)结果表,以反映其(动态)输入表上的更改。
- 将流转换为动态表。
- 在动态表上计算一个连续查询,生成一个新的动态表。
- 生成的动态表被转换回流。
2.2 在流上定义表(动态表)
为了使用关系查询处理流,必须将其转换成Table。从概念上讲,流的每条记录都被解释为对结果表的 INSERT操作。
假设有如下格式的数据:
[
user: VARCHAR, // 用户名
cTime: TIMESTAMP, // 访问 URL 的时间
url: VARCHAR // 用户访问的 URL
]
下图显示了单击事件流(左侧)如何转换为表(右侧)。当插入更多的单击流记录时,结果表的数据将不断增长。
2.3 连续查询
在动态表上计算一个连续查询,并生成一个新的动态表。与批处理查询不同,连续查询从不终止,并根据其输入表上的更新更新其结果表。
在任何时候,连续查询的结果在语义上与以批处理模式在输入表快照上执行的相同查询的结果相同。