什么是Paimon?
Paimon的官网介绍是:Streaming data lake platform
with high-speed data ingestion, changelog tracking and efficient real-time analytics.
Paimon 是流数据湖平台,具有高速数据摄取、变更日志跟踪和高效的实时分析能力
数据湖是大数据近年来的网红项目,熟知的开源数据湖三剑客 Apache hudi
、Apache iceberg
、Databricks delta
近年来野蛮生长,目前各自背后也都有商业公司支持,投入了大量的人力物力去做研发和宣传。
Paimon
的前身是flink-table-store
即FTS
最开始是作为 Flink 的子项目加入了 Apache 社区,由 Flink 团队主导研发,开源后不够火
也许是因为数据湖市场早已被三剑客占据了大半,也许是宣传的力度不够,也许是 Flink 子项目限制了它作为数据湖产品的发展。
可能也正是这些种种的原因促成 flink-table-store 作为独立项目重新加入 Apache,不再依附 Flink,并且更名为Paimon
提供的核心功能
- Unified Batch & Streaming: 统一批流读写,支持批写、批读、流写、流读
- Data Lake: 作为数据湖存储,具有成本低、可靠性高、元数据可扩展等优点。
- Merge Engines: 支持丰富的合并【merge】引擎。缺省情况下,根据主键保留最新的一条记录,当然还可以根据业务需要,使用使用“部分更新【partial-update】”或“聚合【aggregation】”引擎等
- Changelog producer:支持丰富的changelog producer,如“lookup”和“full-compaction”。正确的changelog 可以简化流pipeline的构建
- Append Only Tables: 支持只追加表,自动压缩小文件,并提供有序的流读取。您可以使用它来替换消息队列。
架构
- 读/写:Paimon支持多种方式来读/写数据和执行OLAP查询。
- 对于读取,它支持从历史快照(批处理模式)、从最新偏移量(流模式)中读取数据,或者以混合方式读取增量快照
- 对于写操作,它支持从数据库变更日志(CDC)进行流同步,或者从离线数据进行批量插入/覆盖。
- 生态系统:除了Apache Flink, Paimon还支持其他计算引擎的读取,如Apache Hive、Apache Spark和Trino。
- 内部:在底层,Paimon将列文件存储在文件系统/对象存储中,并使用LSM树结构来支持大量数据更新和高性能查询。
- 统一存储: 提供表抽象。它的使用方式与传统数据库没有什么不同:
- 在批处理执行模式下,它就像一个Hive表,支持批处理SQL的各种操作。查询最新快照。
- 在流式执行模式下,它的作用类似于消息队列。查询它的行为类似于从历史数据永远不会过期的消息队列查询流更改日志。
- 统一存储: 提供表抽象。它的使用方式与传统数据库没有什么不同:
基本概念
Snapshot
快照捕获表在某个时间点的状态。
- 用户可以通过最新的快照访问表的最新数据
- 也可以通过时间旅行【time traveling】,通过较早的快照访问表的先前状态。
Partition
Paimon采用与Apache Hive相同的分区概念来分离数据。
- 分区是一种可选的方法,可以根据特定列(如日期、城市和部门)的值将表划分为相关的多个部分,
- 可以使用一个或多个分区键来标识一个特定的分区。
- 通过分区,用户可以有效地操作表中的记录切片
- 注意:
如果定义了主键,分区键必须是主键的子集。
Bucket
未分区的表或分区表中的分区被细分为桶,为数据提供额外的结构,用于更有效的查询。
- 一个bucket的范围由记录中一个或多个列的哈希值决定。
- 用户可以通过提供bucket-key选项来指定bucket列。
- 如果没有指定bucket-key选项,则使用主键(如果定义了)或完整记录作为bucket-key。
- bucket是用于读写的最小存储单元,因此bucket的数量限制了最大的处理并行性。但是,这个数字不应该太大,因为它将导致大量小文件和低读取性能。一般情况下,
建议每个bucket中的数据大小为1GB左右
。
Consistency Guarantees
- Paimon writer使用两阶段提交协议自动将一批记录提交到表中。每次提交在提交时最多产生两个快照。
- 对于任何两个同时修改一个表的writer,
- 只要他们没有修改同一个桶,他们的提交就是可序列化的。
- 如果修改的是同一个桶,则只保证快照隔离。也就是说,最终的表状态可能是两次提交的混合状态,但不会丢失任何更改。
面临的难题
- 全链路实时流动
- 全链路实时可查。 数据分层存储,则存储对应的挑战如下:
- 全增量一体摄入
- 消息队列的流读
- 变更日志的流读
- 可流join的存储
- 丰富的生态查询
- 数据分层可复用
使用示例
以下资料是根据Flink Table Store 0.3 构建流式数仓最佳实践|李劲松梳理产生的。
场景说明
多表连接到一起,打成大宽表,并流写到下游的clickhouse和ES中
- 订单表Sales和退货表Returns同主键
- Sales表有顾客表的customer_id外键
- Returns有退货原因表reason_id外键
- 顾客表Customer表可更新
- Reason表不可更新
使用FTS操作
- 使用partial-update Merge Engines,根据表的主键,写入订单表
- 使用full-compaction Changelog producer,保证表可以产生正确有序的changelog
- 使用lookup join,写入退货及退货原因表
- 使用双流join,写入顾客表,state只包含关联主键和顾客表的信息,很轻量
- compaction时产生changelogs,并触发将数据写入下游的clickhouse及ES,面向用户提供即席查询功能
FTS 0.3功能解读
全增量一体的数据摄入
消息队列的流读
变更日志的流读
流连接
- 双流连接和维表连接
- 因为是每条记录lookup,代价很大
- 因为是每条记录lookup,代价很大
- 流连接: Partial Update连接
- 注意:表需要有相同的主键
- 注意:表需要有相同的主键
参考
Flink Table Store 0.3 构建流式数仓最佳实践|李劲松