Flink--Streaming Warehouse 流式数仓的概念、目标及实现路径

Flink--Streaming Warehouse 流式数仓的概念、目标及实现路径,第1张

Flink--Streaming Warehouse 流式数仓的概念、目标及实现路径

在 Flink Forward Asia 2021 的主题演讲中,Apache Flink 中文社区发起人、阿里巴巴开源大数据平台负责人王峰提出了 Flink 下一步的发展方向——流式数仓(Streaming Warehouse,简称 Streamhouse)

本文针对流式数仓的概念,实现的目标,实现的方式进行梳理,讲解。

流式数仓(Streaming Warehouse) Streaming Warehouse概念

make data warehouse streaming,就是让整个数仓的数据全实时地流动起来,且是以纯流的方式而不是微批(mini-batch)的方式流动

目标是实现一个具备端到端实时性的纯流服务(Streaming Service),用一套 API 分析所有流动中的数据,当源头数据发生变化,比如捕捉到在线服务的 Log 或数据库的 Binlog 以后,就按照提前定义好的 Query 逻辑或数据处理逻辑,对数据进行分析,分析后的数据落到数仓的某一个分层,再从第一个分层向下一个分层流动,然后数仓所有分层会全部流动起来,最终流到一个在线系统里,用户可以看到整个数仓的全实时流动效果。

在这个过程中,数据是主动的,而查询是被动的,分析由数据的变化来驱动。同时在垂直方向上,对每一个数据明细层,用户都可以执行 Query 进行主动查询,并且能实时获得查询结果。此外,它还能兼容离线分析场景,API 依然是同一套,实现真正的一体化。

流式数仓是终态,要达成这个目标,Flink 需要一个配套的流批一体存储支持,为此,Flink 社区提出了新的 Dynamic Table Storage,即具备流表二象性的存储方案。

解决什么问题

主要解决大数据经典架构–Lambda架构: 将大数据处理划分为实时计算和离线计算
Lambda架构从实际业务使用来看,在在如下问题:

实时链路和离线链路使用的技术栈不同,必定会有两套 API,那么就需要两套开发流程,增加了开发成本;实时离线技术栈不同,无法保证数据口径的一致性;实时链路的中间队列数据不利于分析。如果用户想要分析实时链路中一个明细层的数据,其实非常不方便,很多用户目前采用的办法可能是先把这个明细层中的数据导出来,比如导到 Hive 做离线分析,但这个时效性会大幅下降,或者为了加速查询,把数据导入到其他 OLAP 引擎中,但这又会增加系统复杂度,且数据一致性同样很难保证。
什么是Dynamic table

动态表是Flink的Table API和SQL对流数据支持的核心概念,动态表是一个逻辑概念,它有两种不同的物理表示:更改日志和表

与静态表相比,动态表的数据会随时间而变化,但可以像静态表一样查询动态表查询动态表产生一个连续查询。连续查询永远不会终止,并产生动态结果【另一个动态表】查询不断更新其(动态)结果表,以反映其(动态)输入表上的更改从本质上讲,对动态表的连续查询与定义物化视图的查询非常相似。

高级关系数据库系统提供称为"物化视图"的功能。物化视图定义为SQL查询,就像常规虚拟视图一样。
物化视图缓存查询的结果,使得在访问视图时不需要执行查询。
缓存的一个常见挑战是避免缓存提供过时的结果。物化视图在修改其定义查询的基表时会过时。
Eager View Maintenance是一种在更新基表后立即更新实例化视图的技术。
如果我们考虑以下内容,Eager View Maintenance和流上的SQL查询之间的联系就变得很明显:

数据库表是INSERT,UPDATE和DELETEDML语句流的结果,通常被称为更新日志流。物化视图定义为SQL查询。为了更新视图,查询需要持续处理视图源表的更改日志流。物化视图是流式SQL查询的结果。

通过Dynamic Table Storage来提供针对Eager View Maintenance的支持,Dynamic Table类似于clickhouse等数据库中物化视图,当源数据发生更新时,Dynamic Table中的数据会被立即更新。

注意:

连续查询输出在语义上始终等同于在输入表的快照上以批处理模式执行的相同查询的结果。动态表首先是一个逻辑概念。在查询执行期间,动态表不一定(完全)物化。

与常规数据库表一样,可以通过INSERT、UPDATE和DELETE修改动态表
在将动态表转换为流或将其写入外部系统时,需要对这些更改进行编码。Flink的Table API和SQL支持三种方法来编码动态表的更改:Append-only stream:只包含insert *** 作,Retract stream:包含add 消息和retract 消息Upsert stream: 包含Upsert消息和Delete消息。转换为upsert流的动态表需要一个(可能是复合的)唯一键,与撤回流的主要区别在于UPDATE更改使用单个消息进行编码,因此效率更高
流批一体的存储方案 什么是Dynamic Table Storage

详见FLIP-188: Introduce Built-in Dynamic Table Storage

Dynamic Table Storage可以理解为一套流批一体的存储,并无缝对接 Flink SQL。可以理解为物化视图对应的物理存储。

目前 Flink 本身有内置的分布式 RocksDB 作为 State 存储,但这个存储只能解决任务内部流数据状态的存储问题,且数据状态的数据不能太大,所以Dynamic Table需要一个配套的存储支持。

用户倾向于使用kafka来存储日志,使用hudi/iceberg/clickhouse作为表,但这样无法做到真正的统一。所以通过Dynamic Table Storage,Flink提供对动态表的内置存储支持,这是一个真正统一的更改日志和表表示。

流式数仓的分层数据可以全部放到 Flink Dynamic Table 中,通过 Flink SQL 就能实时地串联起整个数仓的分层,既可以对 Dynamic Table 中不同明细层的数据做实时查询和分析,也可以对不同分层做批量 ETL 处理

核心存储组件

从数据结构上看,Dynamic Table 内部有两个核心存储组件:

File Store

存储 Table 的文件存储形式,采用经典的 LSM 架构,支持流式的更新、删除、增加等采用开放的列存结构,支持压缩等优化对应 Flink SQL 的批模式,支持全量批式读取对 Flie Store 的写入被封装在内置的 Sink 中,屏蔽了写入的复杂性。同时 Flink 的 Checkpoint 机制和 Exactly once 机制能够保证数据的一致性。 Log Store

存储的是 Table 的 *** 作记录,是一个不可变更序列对应 Flink SQL 的流模式通过 Flink SQL 订阅 Dynamic Table 的增量变化做实时分析,目前支持插件化实现。日志存储依赖于日志系统。默认情况下,使用Kafka作为底层存储。LogStore中的Bucket是Kafka分区,这意味着记录被散列到不同的Kafka分区,根据主键(如果有)或整行(没有主键)。默认情况下,数据只在检查点之后可见,这意味着logStore具有事务一致性。

特性

Flink SQL的内置存储

提高可用性问题Flink DDL不再仅仅是一个映射,而是这些表的实际创建(即有对应的物理存储)将底层的技术细节进行抽象和隐藏,去除恼人的选项 Supports subsecond streaming write & consumption

它可以由面向服务的消息队列支持(如Kafka) 高吞吐量扫描能力

像iceberg/hudi一样,带有列式存储格式的文件系统是一个理想的选择。 更重要的是,为了解决认知障碍,存储需要自动处理各种Insert/Update/Delete输入和表定义

接收任何类型的变更日志,接收任何类型的数据类型表可以有主键,也可以没有主键 为什么FileStore不直接使用Hudi ?

Hudi的目标是支持upsert的更新,因此需要强制定义主键和时间列。但支持所有的变更日志类型并不容易Hudi的更新是基于索引的(目前有BloomFilter和Hbase)。桶内数据无序。每次合并都需要重新读取和重写,这是昂贵的。我们需要快速更新存储,LSM更适合。 参考

FLIP-188: Introduce Built-in Dynamic Table Storage
Apache Flink 不止于计算,数仓架构或兴起新一轮变革
dynamic_tables

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5701786.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存