① Sort Merge Join。对 base 文件和 delta 文件进行排序,然后进行合并。这种方式的优点是比较稳定,缺点是排序的代价比较大。
② Hash Join。将 delta 文件的数据加载到内存,将 base 文件与内存中的数据进行对比。这种方式的优点是性能更好,缺点是在 delta 文件比较大的极端情况性能反而低于 Sort Merge Join。
第二种实现方案是 Delta Merge on Read,这种方案在定位到需要更新的文件时不需要立即进行合并,而是新建一份数据文件,在读取时再进行合并,然而这本质上只是延迟了复制操作,对于数据定位合并上的效率是没有太多改变的。
3. Flink Table Store方案
Apache Hudi 满足了列存储和分布式存储的要求,但之所以不选择 Apache Hudi,是因为基于底层数据结构的考虑,Hudi 在设计上采用了 Index 的方式定位文件。对于 Bloom Filter Index,大数据场景下存在的假阳性问题会导致查询效率低下;而使用 Flink State Index 又会出现状态过期、点查性能不足以及不能对外暴露信息等问题。
在 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 读取变更的数据。
基于 LSM 结构,Flink Table Store 能够提供的业务价值包括:
① 提供了可以被查询的数据中间层,并且仍然具备流式处理的能力。
② 在保证数据更新效率的基础上,还能提供较好的数据过滤能力。
04 项目和规划
在 Flink Forward Asia 2021 上,社区已经确定要给 Flink 增加一个重要的存储组件,这之后 Flink Table Store 的规划有以下几个重要节点:
① 在 V0.1 版本里实现基本的日志存储功能,这一阶段还不具备服务化能力。
② 在 V0.2 版本里希望能够做到聚合 Hive、支持表结构演变和更完整的 LSM 数据结构实现等,达到生产状态,但还不具备服务能力。