Flink Table Store:流批一体存储


2593833641e5d23951791694b067c8dc.png

分享嘉宾:李劲松 阿里巴巴 技术专家

编辑整理:吕宴全 浙江大学

出品平台:DataFunTalk

导读:Flink Table Store 是 Apache Flink 的一个子项目,是Flink在推动流批一体演进中存储领域上的重要一环。考虑到 Flink Table Store 仍然是一个比较新的开源项目,本次分享将会对 Flink Table Store 设计初衷和未来规划进行整体介绍。本次分享会围绕下面四点展开:

  • 业务需求

  • 使用 Flink Table Store

  • 理解 Flink Table Store

  • 项目和规划

01

业务需求

Flink 在 Table API  和 SQL 中提出了动态表的概念,跟 Hive 表在离线数仓中间层的作用类似,动态表是实时数据仓库的中间层。动态表中数据是随时间变化的,而静态表只能包含离线处理的数据。我们可以将实时计算看成对动态表上变更数据的处理,将离线计算看成对动态表某个时间快照的处理。如下图所示,我们可以像查询批处理表一样查询动态表,对动态表的查询将生成一个不会停止的连续查询,这个查询不断更新下游的结果表,以反映输入动态表上的更改,这构成了实时数仓的基本链路。本质上,动态表上的连续查询非常类似于定义物化视图的查询。

84d83069069d74097237446a39fbe7d2.png

从架构上看,实时数仓架构常以 Kafka 作为中间层。然而 Kafka 作为中间层,其数据是不可查询的,只有最后落地的 ODS 层数据可查,这会严重限制数据分析师的能力,数据分析是面向所有表的,数据分析师对所有表数据的查询都有诉求;并且因为 Kafka 数据只能保存一段时间,在中间数据出现问题的场景下,对数据进行排查检验的成本是很大的。在某些场景下,以 Kafka 作为实时计算链路的中间层甚至需要付出比较高的成本。

为了解决 Kafka 不可查询的问题,业界的一种解决方案是构建实时离线一体化数据仓库:对于实时计算的一条流水线,再去创建离线链路的一条流水线,实时数据多往一条离线支路进行写入,离线的数据以天周期更新到下游,用以更新实时链路中的错误数据和分析查询。由于在技术上 Kafka 中需要重视时间字段和水位线等属性,而 Hive 则需要考虑分区问题,这种方案存在的问题就是两套系统的维护成本比较高;并且实时数仓和离线数仓的口径也难以保持天然的一致性,这就导致了两条链路不可避免的走向割裂。

b7e6bc71e8838ea0ed9b5d5311f7a782.png

因此,我们对离线和实时计算在存储上的核心需求有以下几点,这也是对 Flink Table Store 设计的基本要求:

    ① 是一个流批统一的存储,提供一定的 OLAP 查询能力(基于列式存储),做到毫秒级别的实时流式读取,能够支持 Insert Overwrite。

    ② 是最为完善的 Flink Connector,支持 Flink SQL 的全部概念,支持任意 Flink Job 的输出,支持所有数据类型。

    ③ 是最好用的 Flink Connector,能够结合 Flink SQL 提供 DB 级别的体验,并且支持大规模更新。

569c7283fe1372dfd4c9d2cddac02b48.png

02

使用 Flink Table Store

Flink Table Store 结合 Flink SQL,致力于打造类似 Database 的使用体验。

1. 建表

在创建表时会创建实质的物理存储,而不只是逻辑映射,删除数据时也会删除物理存储。对于用户而言,在建表时不需要填写跟业务无关的连接信息,这些信息通过 session 级别的配置就可以设置完成。在实际存储上也有类似数据库主键的概念,在主键上可以预先构建好索引,因此基于主键的查询是非常快的。Flink Table Store 的建表语句如下图所示:

6afada8a65f74ddac6793a6ddfaa3a43.png

2. 统一读

Flink Table Store 中的表有流读和批读两种模式,但是在使用上的体验是一致的,只需要通过修改“execution.runtime-mode”参数值来设置运行模式:

    ① batch,能够查询当前快照的数据信息。

    ② streaming,能够持续性地读取变更信息。

Flink Table Store 原生地支持 Kafka,在用户使用体验上,不需要了解 Kafka表是如何建立和写入的。

Flink Table Store 设置不同读取方式的方法如下图所示:

b58cfe596db1341ce941e5e1bfb071d7.png

在流式读取的场景下,能够达到 CDC 的读取效果。默认采取的是增量快照方案:不仅会将历史的数据全部读取,然后继续读取变更的数据,保证读取到的是全量数据。当然,也支持只读最新的变更数据,由用户通过参数决定读取方式。

c03b9810630138cbc0733eb377b40b62.png

3. 统一写

考虑如下图所示的场景:

假设在 DWD 层存在一张实时写入的表,数据分析人员发现近期写入的数据出现了一些错误,通过把历史数据放入到实时数据去更新这些数据是不正确的,这不仅会导致整个消息队列的数据乱序,也不利于Flink去计算状态,因为状态有可能会过期。

2c0515efe7b238dde4c80ad78a65affc.png

一个有效的解决手段是允许原来的实时写任务继续运行的,并新增一个离线的任务去重写这部分数据。对应到实际操作中,即是下图所示的 SQL 语句,通过修改“execution.runtime-mode”快速切换运行模式,手动修改过滤条件对出错的数据分区进行重写,通过 SQL 就能很方便的就能拉起一个离线任务。

acdc36bccbac62e1644d48418202b449.png

03

理解Flink Table Store

1. 分层设计

不同的数据对于实时性的紧迫程度是不同的:一部分数据对实时性要求非常高,不过这部分数据是很少的,我们称之为黄金数据;另一部分数据则对实时性的要求更低一些,我们称之为白银数据;剩下的大量数据虽然有一定的分析性价值,但是对实时性的要求并不高,我们称之为青铜数据。

我们在存储上的分层设计需要能够覆盖这三类需求,在使用时提供统一的调用接口,让用户能够根据自己的需求选择适合的方案。如下图所示,展示了一种存储分层方案:

f27fee57e93b9132fbb79fef75909d85.png

在最底层,需要存储所有的数据,业界通常的方案是采用 DFS 进行存储。而在次一层,则是 File Store,这是一个准实时的数据湖。在数据湖上,则是 Table Store,提供实时的流水线,主要存储白银数据,而在最上层就是 Table Store Service,通过 Cache 保存数据,存储的是黄金数据。我们预期的流程是通过 Flink 写入数据,在查询端构建良好的生态,可以通过 Flink、Spark 查询。

2. 业界已有实现

业界已经有了两种比较成熟的实现方案,分别是 Copy on Write 和 Merge on Read。第一种实现方案是 Copy on Write,在已经有一堆历史数据文件的基础上,将更新数据与历史数据进行 Join,合并出新的数据文件。

这种方式存在的问题在于历史文件比较多,Join 代价比较大,常用的优化手段是加上文件定位操作,快速找到需要被更新的数据文件。

02c4c437789dbb552769738bdb540d7a.png

文件定位的方法有以下几种:

    ① Key Min Max。在数据文件有序的情况下,通过 Min/Max 能快速过滤文件。

    ② BloomFilter。存在假阳性的问题,在大数据量场景下性能仍然会比较差。

    ③ Key-Value Index。依赖 KV 存储服务,但是 KV 存储的点查询性能不太好。

在合并文件操作中常用的方法有:

    ① Sort Merge Join。对 base 文件和 delta 文件进行排序,然后进行合并。这种方式的优点是比较稳定,缺点是排序的代价比较大。

    ② Hash Join。将 delta 文件的数据加载到内存,将 base 文件与内存中的数据进行对比。这种方式的优点是性能更好,缺点是在 delta 文件比较大的极端情况性能反而低于 Sort Merge Join。

ff91a12c9bce973c071b5ccf4a5abc2b.png

第二种实现方案是 Delta Merge on Read,这种方案在定位到需要更新的文件时不需要立即进行合并,而是新建一份数据文件,在读取时再进行合并,然而这本质上只是延迟了复制操作,对于数据定位合并上的效率是没有太多改变的。

3. Flink Table Store方案

Apache Hudi 满足了列存储和分布式存储的要求,但之所以不选择 Apache Hudi,是因为基于底层数据结构的考虑,Hudi 在设计上采用了 Index 的方式定位文件。对于 Bloom Filter Index,大数据场景下存在的假阳性问题会导致查询效率低下;而使用 Flink State Index 又会出现状态过期、点查性能不足以及不能对外暴露信息等问题。

3611f31433173e4f95decf43876bdae4.png

Flink Table Store 选择使用 LSM Tree(Log Structured Merge Tree)作为底层存储,LSM 是大数据规模场景下的核心数据结构,通过 Sort-Merge 的方式达到了很好的更新性能,并且基于有序的数据,LSM 的数据查询(点查、范围查询)的性能也是比较良好的。考虑到 LSM 是基于单机存储的设计,我们可以加上分桶的策略实现分布式设计。

b0dfc43d2c1c83836af7026c065da3db.png

在 Flink Table Store 中,会在 Sink 端维护一个 Memory Table,用作数据合并,数据会写入到 File Store 和 Log Store 当中,File Store 中保存的就是经过桶分区的 LSM 树存储结构,Log Store 则是保存了 LSM 中的 Write Ahead Log 信息。对于批读,只需要去读取 File Store;而对于流读,则需要混合的读取,先读取 File Store 中的全量数据,再通过 Log Store 读取变更的数据。

75a5d5229c979e5948eab0d8355d0b49.png

基于 LSM 结构,Flink Table Store 能够提供的业务价值包括:

    ① 提供了可以被查询的数据中间层,并且仍然具备流式处理的能力。

    ② 在保证数据更新效率的基础上,还能提供较好的数据过滤能力。

f99c7b799c7a0d9dd43a53225b3381c3.png

04

项目和规划

在 Flink Forward Asia 2021 上,社区已经确定要给 Flink 增加一个重要的存储组件,这之后 Flink Table Store 的规划有以下几个重要节点:

    ① 在 V0.1 版本里实现基本的日志存储功能,这一阶段还不具备服务化能力。

    ② 在 V0.2 版本里希望能够做到聚合 Hive、支持表结构演变和更完整的 LSM 数据结构实现等,达到生产状态,但还不具备服务能力。

    ③ 在 V0.3 版本里预计能够具备服务化能力,能够达到真实时的流批一体存储,为流批一体数仓使用。

    ④ 在 V0.4 版本里期望推出比较完善的版本,为流计算里的维表关联所使用。

4b2aa3dda0321e928ea4c839234c9c92.png

Flink Table Store 的 Github、文档社区信息、邮件列表汇总如下:

项目开源地址:

https://github.com/apache/flink-table-store

项目文档:

https://nightlies.apache.org/flink/flink-table-store-docs-master/

讨论邮件列表:dev@flink.apache.org

用户列表:user@flink.apache.org

用户中文列表:user-zh@flink.apache.org

7303d6a7617e178c781d02ea466d8edb.png

05

Q&A环节

Q1:Flink Table Store 是 Flink 社区中 Table 的发展方向吗?

A1:仅有计算而没有存储会存在许多问题,Flink 社区之后一定会发展自己的存储,之后也将会以 Flink Table Store 作为在存储上的着力点,为流批一体提供更好的保障。

Q2:Flink Table Store 支持 Join 操作吗?

A2:Flink Table Store 不支持维表 Join,这需要点查能力的支撑,而对于 OLAP查询中的多表 Join,Flink Table Store 支持基于 Snapshot 的查询,和传统的数据湖提供的能力是相同的。

Q3:LSM 会有写放大和读放大的问题,Flink Table Store 会有这样的问题吗?如何避免?

A3:LSM 一定会有写放大和读放大的问题,但是我们会提供配置参数进行调节,在默认情况下,我们更重视会对读取的优化,同时保障足够的吞吐量。

今天的分享就到这里,谢谢大家。


在文末分享、点赞、在看,给个3连击呗~


01/分享嘉宾

4bfffecdc7defb8622a2e639f62e23f7.png

李劲松

阿里巴巴

阿里巴巴技术专家,Apache Flink & Iceberg Committer


就职于阿里云的 Flink SQL 团队。长期以来,一直在分布式流/批处理系统领域工作,并对数据湖和 OLAP MPP 进行了一些研究。自从 2015 年硕士毕业于电子科技大学后,加入了阿里巴巴,参与上一代流计算系统的研发,2016 年参与 Apache Beam 社区。2017 年开始专注于 Apache Flink 的研发,主要专注在 SQL 上,包括批计算、流计算、数据湖。

017f02816b3856836f97eab01cff769a.png

🧐 分享、点赞、在看,给个3连击呗!👇

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flink流批一体指的是将流计算和批计算结合在一起进行数据处理和分析的能力。通过流批一体化的架构,Flink能够同时支持流式数据和批处理数据的处理和分析。 在流批一体的架构下,Flink提供了统一的SQL和Table表达能力,以及统一的Query Processor和Runtime。在最新的版本中,Flink已经实现了DataStream API的流批一体化,使得DataStream既可以执行流计算的算子,也可以执行批处理的算子。这意味着DataStream可以同时使用流式算子和批处理算子。 此外,在Flink流批一体架构中,Flink的connector也是流批混合的。它可以读取数据库全量数据同步到数据仓库,并通过Change Data Capture(CDC)读取Binlog进行增量和全量的同步。Flink内部会自动协调这些操作,实现了流批一体的价值。 总而言之,Flink流批一体能力使得它能够在同一平台上处理和分析流式数据和批处理数据,提供了更灵活和高效的数据处理和分析能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [flink 流批一体](https://blog.csdn.net/javastart/article/details/123448159)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值