未记录事实核验 · 状态:维护中
记录仅说明核验时间与维护状态,不保证适用于所有环境;使用前请留意正文中的版本、适用条件与风险提示。
warning 适用边界与维护说明
本文适用于理解Paimon的SQL写入、快照与流式读取、历史回溯及消费进度管理,不提供API实战或完整环境搭建与生产作业配置;练习需预先配置Paimon集成、两个窗口共享的Catalog和数据库,并使用Flink流式执行模式。当前from-snapshot-full示例未给出适用版本及起始快照选择条件,因此新建空表后“没有输出,处于等待状态”的启动结果不能作为可确定复现的承诺;主键更新输出应按正文所述结合版本、扫描方式和变更日志配置理解。执行覆写前须确认引擎配置及实际覆写范围,历史查询限于仍保留的快照或Tag,Consumer ID不能单独保证端到端不重不漏。本次仅作全文结构审阅,未进行外部事实核验或运行验证。
📝 Paimon读写操作 - SQL与API实战
abstract 📋 本节概览
- 🎯 学习目标:掌握Paimon的批量与流式读写操作
- 📚 前置知识:Paimon表类型详解
- ⏱️ 预计用时:25分钟
- 🔧 核心内容:INSERT语句、流式查询、Time Travel、Consumer ID
- 💡 关键收获:能够熟练进行数据的写入、查询和历史回溯
🎯 统一的读写体验
Paimon最强大的特性之一是流批一体的读写体验。
- 写入端:支持批处理写入(历史数据初始化)和流处理写入(实时数据同步)。
- 读取端:支持快照查询(Batch Read)和流式查询(Streaming Read)。
✍️ 数据写入操作 (Write)
1. 标准写入 (INSERT INTO)
这是最基础的写入方式,适用于初始化数据或追加少量数据。
-- 插入具体数值
INSERT INTO user_profile
VALUES (1, 'Alice', 25, '2024-01-01 10:00:00');
-- 从其他表查询插入 (Batch ETL常用)
INSERT INTO user_profile
SELECT id, name, age, now()
FROM source_table
WHERE dt = '2024-01-01';
2. 覆写分区 (INSERT OVERWRITE)
适用场景:重跑数据、修正历史分区数据。
注意:INSERT OVERWRITE 会删除指定分区内的所有旧数据,然后写入新数据。
-- 覆写 dt='2024-01-01' 分区的所有数据
INSERT OVERWRITE user_profile PARTITION (dt = '2024-01-01')
SELECT id, name, age, update_time
FROM source_table
WHERE dt = '2024-01-01';
-- 动态覆写示意:仅在所用引擎及配置支持并启用动态分区覆写时,按SELECT结果涉及的分区覆写;执行前须确认实际范围
INSERT OVERWRITE user_profile
SELECT * FROM source_table;
3. 流式写入 (Streaming Write)
在Flink流式执行模式下,可将Kafka等流式源持续写入Paimon;运行还需要正确配置源表、Paimon目标表及任务提交机制,不能仅凭源类型确定执行模式。
-- Flink SQL Job
-- 从Kafka读取JSON数据,实时写入Paimon
INSERT INTO paimon_user_log
SELECT
user_id,
event_type,
PROCTIME()
FROM kafka_source;
📖 数据读取操作 (Read)
1. 批量/快照查询 (Batch/Snapshot Query)
读取表在当前时刻的完整快照。这是默认的查询模式(在Spark或Flink Batch模式下)。
-- 查询当前最新状态
SELECT * FROM user_profile WHERE age > 20;
2. 流式查询 (Streaming Query)
实时订阅表的变更。当新数据写入Paimon时,查询会自动输出新数据。
如何开启:先确保Flink SQL使用流式执行模式,再通过Hints或表配置指定Paimon扫描方式;扫描参数本身不会将批执行模式切换为流式执行模式。
-- 方法1: 使用Hints指定流读模式 (推荐)
-- 'scan.mode'='latest': 从当前最新数据开始读(只读增量)
SELECT * FROM user_profile /*+ OPTIONS('scan.mode'='latest') */;
-- 方法2: 读取全量快照后,自动切换为增量流读
-- 'scan.mode'='from-snapshot-full': 先读历史全量,再读后续增量
SELECT * FROM user_profile /*+ OPTIONS('scan.mode'='from-snapshot-full') */;
3. 时间旅行 (Time Travel)
Paimon支持查询历史版本的数据,这对于排查问题、回溯历史状态非常有用。
语法支持:
- 按快照ID (
scan.snapshot-id) - 按时间点 (
scan.timestamp-millis) - 按Tag (
scan.tag-name)
-- 1. 查询快照ID为 10 的数据版本
SELECT * FROM user_profile /*+ OPTIONS('scan.snapshot-id'='10') */;
-- 2. 查询北京时间(UTC+08:00)2024-01-01 12:00:00 对应的历史状态,前提是相关快照仍可用
SELECT * FROM user_profile /*+ OPTIONS('scan.timestamp-millis'='1704081600000') */;
-- 3. 查询标记为 'release-v1' 的版本
SELECT * FROM user_profile /*+ OPTIONS('scan.tag-name'='release-v1') */;
tip 如何获取快照ID?
执行 SELECT * FROM table_name$snapshots; 即可查看所有可用的快照历史。
🎮 进阶特性: Consumer ID (消费进度管理)
在流式消费Paimon时,如果任务重启,如何确保不重读、不漏读?
Paimon提供了类似Kafka Group ID的机制,称为 consumer-id。
作用:
- 记录消费进度(Offset)。
- 在消费进度已有效提交、消费者未过期且所需快照仍可用等条件下,重启时可利用记录的进度恢复消费。
- 参与快照保留:有效消费者记录可参与相关快照的保留;消费者过期后不能保证所需快照继续保留,也不能据此保证端到端不重不漏。
SELECT * FROM user_profile /*+ OPTIONS(
'consumer-id' = 'app_group_1', -- 消费者组ID
'consumer.expiration-time' = '24 h' -- 如果24小时无消费,进度失效
) */;
⚙️ 常用查询参数速查 (Options)
参数名 (/*+ OPTIONS(...) */) |
可选值 | 说明 | 适用场景 |
|---|---|---|---|
scan.mode |
latest |
只读最新增量 | 实时监控、报警 |
from-snapshot |
从指定快照开始读 | 断点续传 | |
from-snapshot-full |
全量快照 + 增量流 | 实时数仓分层计算 | |
scan.snapshot-id |
Long (e.g., 10) | 指定读取的快照ID | Time Travel |
scan.timestamp-millis |
Long (Unix ms) | 指定读取的时间点 | Time Travel |
consumer-id |
String | 消费者唯一标识 | 需要消费进度管理与相关快照保留的流读场景 |
🧪 动手实践:流批一体体验
假设你已经配置好了Flink SQL Client。
步骤1:创建表
CREATE TABLE orders (
order_id BIGINT PRIMARY KEY NOT ENFORCED,
amount DECIMAL(10,2)
);
步骤2:开启一个流式查询窗口
-- 窗口1:实时监控订单
SELECT * FROM orders /*+ OPTIONS('scan.mode'='from-snapshot-full') */;
-- 此时没有输出,处于等待状态
步骤3:在另一个窗口写入数据
-- 窗口2:写入数据
INSERT INTO orders VALUES (1, 100.00);
INSERT INTO orders VALUES (2, 200.00);
预期结果:在表配置和流式查询条件正确、写入提交成功且查询发现新快照后,窗口1可输出这两条数据;实际延迟取决于提交和扫描配置。
步骤4:更新数据
-- 窗口2:修改订单1的金额
INSERT INTO orders VALUES (1, 150.00);
结果:若当前版本、扫描方式及表的变更日志配置支持读取该更新,窗口1可观察到相应变更;是否包含旧值撤回或仅输出新值,取决于实际变更日志语义与查询结果呈现方式,不能仅由Flink显示模式确定。
📋 本节要点回顾
✅ 核心技能掌握检查
- [ ] 会使用
INSERT INTO和INSERT OVERWRITE - [ ] 掌握
scan.mode的几种关键模式 (latest,from-snapshot-full) - [ ] 能够使用 Time Travel 查询历史数据
- [ ] 理解
consumer-id在流式消费中的作用
🔗 学习路径连接
已完成:✅ 05-表类型详解 → ✅ 06-读写操作 下一步:Paimon主键表管理 - 深入学习主键表的CRUD和合并机制
tip 最佳实践
在生产环境进行流式读取时,强烈建议配置 consumer-id。在消费进度已有效提交、消费者未过期且所需快照仍可用等条件下,consumer-id可用于恢复消费位置并参与快照保留;它不能单独保证端到端不重不漏,也不能保证消费者过期后所需数据仍被保留。
创建时间:2024-12-05 最后更新:2024-12-05 学习时长:25分钟 难度等级:⭐⭐ (中级)
#Paimon #SQL #流批一体 #TimeTravel #ConsumerID