一篇文章带你深入了解Flink SQL流处理中的特殊概念

         Table API 和 SQL,本质上还是基于关系型表的操作方式;而关系型表、关系代数,以及SQL 本身,一般是有界的,更适合批处理的场景。这就导致在进行流处理的过程中,理解会稍微复杂一些,需要引入一些特殊概念。接下来就分别讲一下这几种概念。
在这里插入图片描述

一、流处理和关系代数(表,及 SQL)的区别

表和流式处理的区别
         可以看到,其实关系代数(主要就是指关系型数据库中的表)和 SQL,主要就是针对批处理的,这和流处理有天生的隔阂。

二、动态表(Dynamic Tables)

         因为流处理面对的数据,是连续不断的,这和我们熟悉的关系型数据库中保存的完全不同。所以,如果我们把流数据转换成 Table,然后执行类似于 table 的 select 操作,结果就不是一成不变的,而是随着新数据的到来,会不停更新

         我们可以随着新数据的到来,不停地在之前的基础上更新结果。这样得到的表,在 Flink Table API 概念里,就叫做动态表(Dynamic Tables)

         动态表是 Flink 对流数据的 Table API 和 SQL 支持的核心概念。与表示批处理数据的静态表不同,动态表是随时间变化的。动态表可以像静态的批处理表一样进行查询,查询一个动态表会产生持续查询(Continuous Query)。连续查询永远不会终止,并会生成另一个动态表。查询(Query)会不断更新其动态结果表,以反映其动态输入表上的更改。

三、流式持续查询的过程

动态表和连续查询的关系如下图所示:
动态表和连续查询关系图
流式持续查询的过程为

  • 流被转换为动态表。
  • 对动态表计算连续查询,生成新的动态表。
  • 生成的动态表被转换回流。

3.1 将流转换成表(Table)

         为了处理带有关系查询的流,必须先将其转换为表。

         概念上讲,流的每个数据记录,都被解释为对结果表的插入(Insert)修改。因为流式持续不断的,而且之前的输出结果无法改变。本质上,我们其实是从一个、只有插入操作的 changelog(更新日志)流,来构建一个表。

         为了更好地说明动态表和持续查询的概念,我们来举一个具体的例子。
         比如,我们现在的输入数据,就是用户在网站上的访问行为,数据类型(Schema)如下:

[
user:	VARCHAR,	// 用户名
cTime: TIMESTAMP, // 访问某个 URL 的时间戳
url:	VARCHAR	// 用户访问的 URL
]

下图显示了如何将访问 URL 事件流,或者叫点击事件流(左侧)转换为表(右侧)。

随着插入更多的访问事件流记录,生成的表将不断增长。

3.2 持续查询(Continuous Query)

         持续查询,会在动态表上做计算处理,并作为结果生成新的动态表。与批处理查询不同,连续查询从不终止,并根据输入表上的更新更新其结果表。

         在任何时间点,连续查询的结果在语义上,等同于在输入表的快照上,以批处理模式执行的同一查询的结果。

         在下面的示例中,我们展示了对点击事件流中的一个持续查询。
         这个 Query 很简单,是一个分组聚合做 count 统计的查询。它将用户字段上的 clicks 表分组,并统计访问的 url 数。图中显示了随着时间的推移,当 clicks 表被其他行更新时如何计算查询。

3.3 将动态表转换成流

         与常规的数据库表一样,动态表可以通过插入(Insert)、更新(Update)和删除(Delete)更改,进行持续的修改。将动态表转换为流或将其写入外部系统时,需要对这些更改进行编码。Flink 的Table API 和 SQL 支持三种方式对动态表的更改进行编码

仅追加(Append-only)流
         仅通过插入(Insert)更改,来修改的动态表,可以直接转换为仅追加流。这个流中发出的数据,就是动态表中新增的每一行。
撤回(Retract)流
         Retract 流是包含两类消息的流,添加(Add)消息和撤回(Retract)消息。
         动态表通过将 INSERT 编码为 add 消息、DELETE 编码为 retract 消息、UPDATE 编码为被更改行(前一行)的 retract 消息和更新后行(新行)的 add 消息,转换为 retract 流。
         下图显示了将动态表转换为 Retract 流的过程。

3.3 Upsert(更新插入)流

         Upsert 流包含两种类型的消息:Upsert 消息和 delete 消息。转换为 upsert 流的动态表,需要有唯一的键(key)。
         通过将 INSERT 和 UPDATE 更改编码为 upsert 消息,将 DELETE 更改编码为 DELETE 消息,就可以将具有唯一键(Unique Key)的动态表转换为流。

         下图显示了将动态表转换为 upsert 流的过程。


         这些概念我们之前都已提到过。需要注意的是,在代码里将动态表转换为 DataStream时,仅支持 Append 和 Retract 流。而向外部系统输出动态表的 TableSink 接口,则可以有不同的实现。

总结

         上述文章给大家讲解了一篇关于流出的特殊概念,主要讲解表与流出的区别,流处理查询的过程,以及动态表。这篇主要以理论出发没有什么实质性的代码。这些概念不需要非得记住但是只要了解过。受益的朋友给个三连 喜欢的可以关注我的公众号【大数据老哥】有非常多的资源等你来获取。

微信公众号搜索【大数据老哥】可以获取 200个为你定制的简历模板、大数据面试题、企业面试
题…等等。

资源获取

猜你喜欢

转载自blog.csdn.net/qq_43791724/article/details/111404194