电商网站开发的职责,wordpress 本地建站教程,电影网站的建设,铜官山区建设局网站博主历时三年精心创作的《大数据平台架构与原型实现#xff1a;数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行#xff0c;点击《重磅推荐#xff1a;建大数据平台太难了#xff01;给我发个工程原型吧#xff01;》了解图书详情#xff0c;…博主历时三年精心创作的《大数据平台架构与原型实现数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行点击《重磅推荐建大数据平台太难了给我发个工程原型吧》了解图书详情京东购书链接https://item.jd.com/12677623.html扫描左侧二维码进入京东手机购书页面。
题记
根据过去在流上维持状态的编程经验我们可以深刻地体会到Dynamic Table 的本质其实是基于 changelog 数据流维持的一个流上的状态Streaming State
动态表是 Flink 能以 SQL 驱动和操纵流式处理的基础也是 Flink 实现 ”批流一体“ 的一项内在的技术支撑。简单地说它的思想就是将一个”流“抽象成一张”无界”的数据表这样就可以在上面施加 SQL 操作了。静态的关系表和数据流有可以类比的地方这是能将两者映射在一起的理论基础同时它们之间也有难以弥合的差异所以在某些方面要进行限制或做出适当的妥协。文本将以 Flink 官方文档动态表 (Dynamic Table) 为基底给出一些批注式的解读。
对齐“概念” 首先让我们来统一一些概念对于一张动态表的查询可以有两个层面的解读从上层应用的角度看它就是一条 SQL在查询一张表只不过这张表是动态的它的查询结果会一直在变不同时间查结果是不一样的相应地这条SQL其实是一直在跑的不是反复查询而是是一个持续运行 streaming job)从底层实现的角度看这条 SQL 其实是被翻译成了一个Streaming 作业从源端不停地读取 changelog 数据然后在流上维持一个”状态“数据状态数据就是 SQL 要表达的结果表。所以
查询动态表就是生成一个连续查询一个 Streaming Job一个连续查询是不会终止的流是不会自行终止的动态表是“无界”的结果会生成一个动态表 (Streaming 上的 ”状态“)查询会不断更新这张结果表更新状态实时地反映新流入的数据后对结果表的影响同样的条件不同时间查询结果也可能不同结果表里的数据可能一直在变。
为了方便描述我们可能会交替使用以下称谓或术语它们指得都是同一件事情
流式 SQL 查询 查询动态表 连续查询
”动态表“ 两例 Flink 官方文档给出的两个张”动态表“的图示还是非常形象的也是后面解释关联问题的基础所以这里先列出来
第一个示例 第二个示例 结果表的状态更新中… 或 追加中… 既然连续查询是永不停止的那么结果表自然也是一直在变化的它要么是在持续“更新”记录中要么是在持续 “追加”记录中至于是更新还是追加取决于中间的处理逻辑也就是 SQL 本身。官方文档给出的两个示例恰好一个是更细另一个是追加
第一个查询的结果表是需要”持续更新“的有 UPSERT 操作以 Mary 为例她的 cnt 从 1 到 2 时就是一次更新第二个查询只附加到结果表即结果表的 changelog 流只包含 INSERT 操作。
一个查询是产生一个只追加的表还是一个更新的表有一些含义:
产生更新更改的查询通常必须维护更多的状态。将 append-only 的表转换为流与将已更新的表转换为流是不同的(参阅表到流的转换章节)。
查询限制 尽管动态表的概念在语义上能将SQL二维关系模型比较好地映射到流上但还是会有一些“力所不能及”的地方这主要体现在对查询的一些“限制”上。有两类典型的限制 维持了过多/过大的“状态”这一点比较好理解如果你的流式查询的结果表每一条都是一个”状态“那流就需要一直维持这个状态表的结果集绝大维持的状态就越大/越大直到程序因资源不足最后报错。此类案例就是在第一个查询示例中如果结果表中的每一条用户数据都是一个”状态“可被 Upsert 如果用户数量巨大这个 SQL 就会报错因为维持的 ”状态“ 负担太大 -- 若用户数量过多则维持的状态就会过多过大可能会消耗大量资源
SELECT user, COUNT(url) FROM clicks GROUP BY user;更新的数据量过大通俗一点说就是更新牵涉的数量太大这一点在基于静态表的批量查询中并不会体现出来但基于动态表的流式 SQL 查询是”连续查询“它会不停地查询不停地更新结果表此时如果查询每次都要更新大量已输出的结果行那么查询成本就会被叠加”放大“变得非常高此类案例就是官方文档给出的示例每此有新记录产生都要重新进行排名更新所有已输出的行对于不停刷新的动态表来说这一操作成本太大。 -- 每此有新记录产生都要重新进行排名更新所有已输出的行对于不停刷新的动态表来说这一操作成本太大
SELECT user, RANK() OVER (ORDER BY lastAction)
FROM (SELECT user, MAX(cTime) AS lastAction FROM clicks GROUP BY user
);