聊聊流式数据湖Paimon(三)
概述
如果表没有定义主键,则默认情况下它是仅追加 表类型(Append Only Table)。 根据桶(Bucket)的定义,我们有两种不同的仅追加模式:"Append For Scalable Table"和"Append For Queue";两种模式支持不同的场景,提供不同的功能。
只能向表中插入一条完整的记录。 不支持删除或更新,并且不能定义主键。 此类表适合 不需要更新的用例(例如日志数据同步)。
Append 场景特指"无主键"的场景,比如日志数据的记录,不具有直接Upsert更新的能力。
Append For Scalable Table
其支持的功能如下:
- 支持批读批写 INSERT OVERWRITE
- 支持流读流写 自动合并小文件
- 支持湖存储特性 ACID、Time Travel
- order与z-order排序
Definition
通过在表属性中定义 'bucket' = '-1',可以为此表分配特殊模式(我们称之为"unaware-bucket 模式")。 在这种模式下,一切都不同了。 我们已经没有了桶的概念,也不保证流式读取的顺序。 我们将此表视为批量离线表(尽管我们仍然可以流式读写)。 所有记录都会进入一个目录(为了兼容性,我们将它们放在bucket-0中),并且我们不再维护顺序。 由于我们没有桶的概念,所以我们不会再按桶对输入记录进行混洗,这将加快插入速度。
使用此模式,可以将 Hive 表替换为 Lake 表。

Compaction
在unaware-bucket模式下,我们不在writer中进行压缩,而是使用Compact Coordinator扫描小文件并将压缩任务提交给Compact Worker。 这样,我们就可以轻松地对一个简单的数据目录进行并行压缩。 在流模式下,如果在flink中运行insert sql,拓扑将是这样的:

它会尽力压缩小文件,但是当一个分区中的单个小文件长时间保留并且没有新文件添加到该分区时,压缩协调器会将其从内存中删除以减少内存使用。 重新启动作业后,它将扫描小文件并将其再次添加到内存中。 控制紧凑行为的选项与 Append For Qeueue 完全相同。 如果将 write-only 设置为 true,Compact Coordinator 和 Compact Worker 将从拓扑中删除。
自动压缩仅在 Flink 引擎流模式下支持。还可以通过 paimon 中的 flink 操作在 flink 中启动压缩作业,并通过 set write-only 禁用所有其他压缩。
Sort Compact
每个分区中的数据乱序会导致选择缓慢,压缩可能会减慢插入速度。 将插入作业设置为只写是一个不错的选择,并且在每个分区数据完成后,触发分区排序压缩操作。
Streaming Source
Unaware-bucket模式 Append Only Table 支持流式读写,但不再保证顺序。 你不能把它看作一个队列,而是一个有bin的湖。每次提交都会生成一个新的binbin存储记录 来读取增量,但是一个 bin 中的记录会流向它们想要的任何地方,并且我们以任何可能的顺序获取它们。 在Append For Queue模式下,记录不存储在bin中,而是存储在record pipe中。 记录 存储,我们可以通过读取新的存储记录 来读取增量,但是一个 bin 中的记录会流向它们想要的任何地方,并且我们以任何可能的顺序获取它们。 在Append For Queue模式下,记录不存储在bin中,而是存储在record pipe中。
bin:储物箱
Streaming Multiple Partitions Write
由于Paimon-sink需要处理的写入任务数量为:数据写入的分区数量 * 每个分区的桶数量。 因此,我们需要尽量控制每个paimon-sink任务的写任务数量,使其分布在合理的范围内。 如果每个sink-task处理过多的写任务,不仅会导致小文件过多的问题,还可能导致内存不足的错误。
另外,写入失败会引入孤儿文件,这无疑增加了维护paimon的成本。 我们需要尽可能避免这个问题。
对于启用自动合并的 flink-jobs,我们建议尝试按照以下公式来调整 paimon-sink 的并行度(这不仅仅适用于append-only-tables,它实际上适用于大多数场景):
(N*B)/P < 100 (This value needs to be adjusted according to the actual situation)
N(the number of partitions to which the data is written)
B(bucket number)
P(parallelism of paimon-sink)
100 (This is an empirically derived threshold,For flink-jobs with auto-merge disabled, this value can be reduced.
However, please note that you are only transferring part of the work to the user-compaction-job, you still have to deal with the problem in essence,
the amount of work you have to deal with has not been reduced, and the user-compaction-job still needs to be adjusted according to the above formula.)
还可以将 write-buffer-spillable 设置为 true,writer 可以将记录溢出到磁盘。 这可以尽可能地减少小文件。要使用此选项,的 flink 集群需要有一定大小的本地磁盘。 这对于那些在 k8s 上使用 flink 的人来说尤其重要。
对于仅追加表,您可以为仅追加表设置 write-buffer-for-append 选项。 将此参数设置为true,writer将使用Segment Pool缓存记录以避免OOM。
Example
以下是创建Append-Only表并指定bucket key的示例。
CREATE TABLE MyTable (
product_id BIGINT,
price DOUBLE,
sales BIGINT
) WITH (
'bucket' = '-1'
);
Append For Queue
其支持的功能如下:
- 严格保证顺序,可以带消息队列
- 支持Watermark且对齐
- 自动合并小文件
- 支持Consumer-ID (类似Group-ID)
Definition
在这种模式下,可以将append-only table看成是一个由bucket分隔的队列。 同一个桶中的每条记录都是严格排序的,流式读取会严格按照写入的顺序将记录传输到下游。 使用此模式,不需要进行特殊配置,所有数据都会以队列的形式放入一个桶中。还可以定义bucket和bucket-key以实现更大的并行性和分散数据。

Compaction
默认情况下,sink节点会自动进行compaction来控制文件数量。 以下选项控制压缩策略:

Streaming Source
目前仅 Flink 引擎支持流式源行为。
Streaming Read Order
对于流式读取,记录按以下顺序生成:
- 对于来自两个不同分区的任意两条记录
- 如果 scan.plan-sort-partition 设置为 true,则首先生成分区值较小的记录。
- 否则,将先产生分区创建时间较早的记录。
- 对于来自同一分区、同一桶的任意两条记录,将首先产生第一条写入的记录。
- 对于来自同一分区但两个不同桶的任意两条记录,不同的桶由不同的任务处理,它们之间没有顺序保证。
Watermark Definition
定义读取 Paimon 表的watermark:
CREATE TABLE T (
`user` BIGINT,
product STRING,
order_time TIMESTAMP(3),
WATERMARK FOR order_time AS order_time - INTERVAL '5' SECOND
) WITH (...);
-- launch a bounded streaming job to read paimon_table
SELECT window_start, window_end, COUNT(`user`) FROM TABLE(
TUMBLE(TABLE T, DESCRIPTOR(order_time), INTERVAL '10' MINUTES)) GROUP BY window_start, window_end;
还可以启用 Flink Watermark 对齐,这将确保没有源/拆分/分片/分区将其 Watermark 增加得远远超出其他部分:

Bounded Stream
Streaming Source 也可以是有界的,指定 scan.bounded.watermark 来定义有界流模式的结束条件,流读取将结束,直到遇到更大的 watermark 快照。
快照中的watermark 是由writer生成的,例如,指定kafka源并声明watermark 的定义。当使用此kafka源写入Paimon表时,Paimon表的快照将生成相应的watermark,以便流式读取此Paimon表时可以使用有界watermark的功能。
CREATE TABLE kafka_table (
`user` BIGINT,
product STRING,
order_time TIMESTAMP(3),
WATERMARK FOR order_time AS order_time - INTERVAL '5' SECOND
) WITH ('connector' = 'kafka'...);
-- launch a streaming insert job
INSERT INTO paimon_table SELECT * FROM kakfa_table;
-- launch a bounded streaming job to read paimon_table
SELECT * FROM paimon_table /*+ OPTIONS('scan.bounded.watermark'='...') */;
Example
以下是创建Append-Only表并指定bucket key的示例。
CREATE TABLE MyTable (
product_id BIGINT,
price DOUBLE,
sales BIGINT
) WITH (
'bucket' = '8',
'bucket-key' = 'product_id'
);
参考
基于 Apache Paimon 的 Append 表处理
Apache Paimon 实时数据湖 Streaming Lakehouse 的存储底座
聊聊流式数据湖Paimon(三)的更多相关文章
- Apache Hudi 0.9.0版本重磅发布!更强大的流式数据湖平台
1. 重点特性 1.1 Spark SQL支持 0.9.0 添加了对使用 Spark SQL 的 DDL/DML 的支持,朝着使所有角色(非工程师.分析师等)更容易访问和操作 Hudi 迈出了一大步. ...
- 字节跳动流式数据集成基于Flink Checkpoint两阶段提交的实践和优化
背景 字节跳动开发套件数据集成团队(DTS ,Data Transmission Service)在字节跳动内基于 Flink 实现了流批一体的数据集成服务.其中一个典型场景是 Kafka/ByteM ...
- FunDA(2)- Streaming Data Operation:流式数据操作
在上一集的讨论里我们介绍并实现了强类型返回结果行.使用强类型主要的目的是当我们把后端数据库SQL批次操作搬到内存里转变成数据流式按行操作时能更方便.准确.高效地选定数据字段.在上集讨论示范里我们用集合 ...
- 流式大数据处理的三种框架:Storm,Spark和Samza
许多分布式计算系统都可以实时或接近实时地处理大数据流.本文将对三种Apache框架分别进行简单介绍,然后尝试快速.高度概述其异同. Apache Storm 在Storm中,先要设计一个用于实时计算的 ...
- [转载]流式大数据处理的三种框架:Storm,Spark和Samza
许多分布式计算系统都可以实时或接近实时地处理大数据流.本文将对三种Apache框架分别进行简单介绍,然后尝试快速.高度概述其异同. Apache Storm 在Storm中,先要设计一个用于实时计算的 ...
- 流式数据分析模型kafka+storm
http://www.cnblogs.com/panfeng412/archive/2012/07/29/storm-stream-model-analysis-and-discussion.html ...
- 基于Apache Hudi构建数据湖的典型应用场景介绍
1. 传统数据湖存在的问题与挑战 传统数据湖解决方案中,常用Hive来构建T+1级别的数据仓库,通过HDFS存储实现海量数据的存储与水平扩容,通过Hive实现元数据的管理以及数据操作的SQL化.虽然能 ...
- Robinhood基于Apache Hudi的下一代数据湖实践
1. 摘要 Robinhood 的使命是使所有人的金融民主化. Robinhood 内部不同级别的持续数据分析和数据驱动决策是实现这一使命的基础. 我们有各种数据源--OLTP 数据库.事件流和各种第 ...
- 翻译-In-Stream Big Data Processing 流式大数据处理
相当长一段时间以来,大数据社区已经普遍认识到了批量数据处理的不足.很多应用都对实时查询和流式处理产生了迫切需求.最近几年,在这个理念的推动下,催生出了一系列解决方案,Twitter Storm,Yah ...
- 【node】记录项目的开始与完成——pipeline_kafka流式数据库管理项目
前言: 我始终坚信的一点是,学习的效果80%来自总结,甚至全部都是.总结的好处就是让你能翻出你的过往,指出其中的不足,看到未来的改进方法,好的总结更能让知识产生飞跃,所以在工作之余,部署项目之际,总结 ...
随机推荐
- Eclipse修改Web项目名称
Eclipse修改Web项目名称需要两步: 1:修改该项目目录下:.project文件 <projectDescription><name>SpringMVC-Annotati ...
- 如何保持 SSH 会话不中断?
哈喽大家好,我是咸鱼 不知道小伙伴们有没有遇到过下面的情况: 使用终端(XShell.secureCRT 或 MobaXterm 等)登录 Linux 服务器之后如果有一段时间没有进行交互,SSH 会 ...
- Node.js vs. Spring Boot:Hello World 性能对决,谁更快一点?
前言: Spring Boot 在 Java 生态中备受欢迎,它是一款基于 Java 构建的轻量级服务端框架,主要用于 Web 服务.Spring Boot 的应用使得创建各类基于 Spring 的企 ...
- vue3.3.x setup 新实验性特性 defineModel 定义多个属性
由于有些业务组件需要定义多个响应式props,类似这种(比较懒,没上ts),在vue3.3.x以前,如果不用三方库,代码会变得很繁琐 <script setup> const props ...
- LeetCode 周赛上分之旅 #47 前后缀分解结合单调栈的贡献问题
️ 本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问. 学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越 ...
- 文心一言 VS 讯飞星火 VS chatgpt (108)-- 算法导论10.1 6题
六.用go语言,说明如何用两个栈实现一个队列,并分析相关队列操作的运行时间. 文心一言: 使用两个栈实现队列的基本思想是利用一个栈(stack1)来处理入队操作,另一个栈(stack2)来处理出队操作 ...
- 12. 用Rust手把手编写一个wmproxy(代理,内网穿透等), TLS的双向认证信息及token验证
12. 用Rust手把手编写一个wmproxy(代理,内网穿透等), TLS的双向认证信息及token验证 项目 ++wmproxy++ gite: https://gitee.com/tickbh/ ...
- Tinyalsa PCM API 实现深度剖析
高级 Linux 音频架构 (ALSA) 用于为 Linux 操作系统提供音频和 MIDI 功能.它可以高效地支持所有类型的音频接口,从消费者声卡到专业的多通道音频接口.它支持全模块化的音频驱动.它是 ...
- LLM在text2sql上的应用
一.前言: 目前,大模型的一个热门应用方向text2sql它可以帮助用户快速生成想要查询的SQL语句.那对于用户来说,大部分简单的sql都是正确的,但对于一些复杂逻辑来说,需要用户在产出SQL的基础上 ...
- JavaScript用策略模式消除if else 和 switch
js程序中最常用的if else循环,如果分枝很多的的情况下难免使写出的程序又臭又长,但是根据需求又必须将这些分支处理,此时稍有经验的程序员可能会想到用switch case优化但是只是仅仅做到利于阅 ...