Paimon DQL

250 阅读7分钟

<1> 批量查询

Paimon的批量读取返回表快照中的所有数据。默认情况下,批量读取返回最新快照。

在sql-client中,设置执行模式为批即可:

RESET 'execution.checkpointing.interval';
SET 'execution.runtime-mode' = 'batch';

《1》时间旅行

1)读取指定id的快照
SELECT * FROM ws_t /*+ OPTIONS('scan.snapshot-id' = '1') */;
SELECT * FROM ws_t /*+ OPTIONS('scan.snapshot-id' = '2') */;
2)读取指定时间戳的快照
-- 查看快照信息
SELECT * FROM ws_t&snapshots;

SELECT * FROM ws_t /*+ OPTIONS('scan.timestamp-millis' = '1688369660841') */;
3)读取指定标签
SELECT * FROM ws_t /*+ OPTIONS('scan.tag-name' = 'my-tag') */;
4)查询指定表的元数据表
select * from ws_t$snapshots;
5)查询表的标签表
select * from ws_t$tags;

《2》增量查询

读取开始快照(不包括)和结束快照之间的增量更改。例如,“3,5”表示快照 3 和快照 5 之间的更改:
SELECT * FROM ws_t /*+ OPTIONS('incremental-between' = '3,5') */;
在batch模式中,不返回DELETE记录,因此-D的记录将被删除。如果你想查看DELETE记录,可以查询audit_log表:
SELECT * FROM ws_t$audit_log /*+ OPTIONS('incremental-between' = '3,5') */;

<2> 流式查询

默认情况下,Streaming read 在第一次启动时会生成表上的最新快照,并继续读取最新的更改。

SET 'execution.checkpointing.interval'='30s';
SET 'execution.runtime-mode' = 'streaming';

也可以从最新读取,设置扫描模式:
SELECT * FROM ws_t /*+ OPTIONS('scan.mode' = 'latest') */

《1》时间旅行

注意:使用流的时间旅行,以谁为起点就另立新王,以前的操作都不算了,从新王一开始的snapshot都是insert,如果说以前是-U|+U,那么新王就是+i

从快照2开始的快照3变更

image.png

从快照3开始

image.png

如果只想处理今天及以后的数据,则可以使用分区过滤器来实现:
SELECT * FROM test_p WHERE dt > '2023-07-01'
如果不是分区表,或者无法按分区筛选,可以使用时间旅行的流读取。
1)从指定快照id开始读取变更数据
SELECT * FROM ws_t /*+ OPTIONS('scan.snapshot-id' = '1') */;
2)从指定时间戳开始读取
SELECT * FROM ws_t /*+ OPTIONS('scan.timestamp-millis' = '1688369660841') */;
3)第一次启动时读取指定快照数据,并继续读取变化---想要拿到新王前的历史全量数据,并记录后续的变更(常用)
SELECT * FROM ws_t /*+ OPTIONS('scan.mode'='from-snapshot-full','scan.snapshot-id' = '3') */;

image.png

《2》Consumer ID---用于流式数据读取

(1)核心功能

image.png

  1. 安全消费(Safe Consumption) Paimon 在判断快照是否过期时,会检查文件系统中所有关联该表的 Consumer ID。若某个快照仍有 Consumer 依赖(即使作业已暂停),则该快照不会被删除。例如,默认快照保留时间为1小时,但配置 Consumer ID 后,依赖的快照可长期保留,避免流作业恢复时因快照被删而失败。

  2. 断点续传(Resume from Breakpoint) Consumer ID 会记录流作业消费的快照进度到文件系统。若作业中断,新作业可通过同一 Consumer ID 自动从上次消费的快照继续读取,无需依赖 Flink 状态恢复。类似 Kafka 的消费者组机制,但进度存储在 Paimon 表中。

(2)使用

  1. 基本配置

    • 指定 Consumer ID:在流式查询时通过 /*+ OPTIONS('consumer-id' = 'myid') */ 指定唯一标识。
    • 管理生命周期:通过 ALTER TABLE t SET ('consumer.expiration-time' = '1 d') 设置 Consumer ID 的过期时间,避免无效 Consumer 长期占用存储。
  2. 消费模式(consumer.mode)

    • exactly-once(默认) :严格记录所有读取器精确消费的快照 ID +1,确保一致性。
    • at-least-once:记录最慢读取器的快照 ID,允许不同读取器以不同速率消费,适用于水印对齐等场景。
  3. 忽略进度(consumer.ignore-progress) 设置 'consumer.ignore-progress' = 'true' 时,作业会从当前最新快照重新消费,仅保留“安全消费”功能,不继承历史进度。适用于需要重置消费位点或仅需防快照删除的场景

-- 开启consumerId 然后启动流作业并记录进度
SELECT * FROM t /*+ OPTIONS('consumer-id' = 'test-id', 'consumer.mode' = 'at-least-once') */;

-- 插入新数据后,新作业自动续传
INSERT INTO t VALUES (1, 'data');
SELECT * FROM t /*+ OPTIONS('consumer-id' = 'test-id') */;  -- 仅消费新增数据

-- 强制从最新快照重新消费
SELECT * FROM t /*+ OPTIONS('consumer-id' = 'test-id', 'consumer.ignore-progress' = 'true') */;
模式exactly-once(默认)at-least-once
一致性保证严格对齐检查点,确保快照消费不重复、不丢失允许不同读取器速率差异,可能存在重复消费
进度记录方式记录所有 Reader 消费的最新快照 ID(精确到每个读取器)记录所有 Reader 中最小的快照 ID(最慢读取器进度)
性能影响检查点需等待所有 Reader 对齐,可能增加延迟无需对齐,吞吐量更高,延迟更低
适用场景需要严格断点续传(如金融交易)允许少量重复(如日志分析)、需水印对齐的场景

4.Reset Consumer

用于 动态调整消费位点清理无效 Consumer,是管理消费进度的重要工具。

场景操作方式
重置消费位点指定 next_snapshot_id,将 Consumer 的进度重置到指定快照(如回溯消费旧数据)
删除 Consumer不指定 next_snapshot_id,直接删除 Consumer ID 及其进度记录
修复进度不一致当 Consumer 记录的进度与实际情况冲突时(如手动删除快照),强制重置位点

步骤

  1. 停止作业:确保使用该 Consumer ID 的所有流任务已停止,否则操作可能失败。
  2. 权限检查:需拥有表的管理权限(如 HDFS 文件系统写权限、元数据操作权限)。
  3. 重置进度
  4. 启动新作业
-- 将 Consumer ID 'cid1' 的进度重置到快照 100
CALL sys.reset_consumer(
    `table` => 'db1.table1', 
    consumer_id => 'cid1', 
    next_snapshot_id => 100
);

-- 删除 Consumer ID 'cid2'
CALL sys.reset_consumer(
    `table` => 'db1.table1', 
    consumer_id => 'cid2'
);

-- 启动新作业
SELECT * FROM t /*+ OPTIONS(
    'consumer-id' = 'cid_new', 
    'consumer.mode' = 'at-least-once'
) */;

(3)优缺点

在流式读取表时指定consumer-id,这是一个实验性功能。

当流读取Paimon表时,下一个快照id将被记录到文件系统中。这有几个优点:

Ø 当之前的作业停止后,新启动的作业可以继续消耗之前的进度,而不需要从状态恢复。新的读取将从消费者文件中找到的下一个快照 ID 开始读取。

Ø 在判断一个快照是否过期时,Paimon会查看文件系统中该表的所有消费者,如果还有消费者依赖这个快照,那么这个快照就不会因为过期而被删除。

Ø 当没有水印定义时,Paimon表会将快照中的水印传递到下游Paimon表,这意味着您可以跟踪整个管道的水印进度。比如 A表有水印,但是B表没有,此时A表数据要往B表插入,那么A的水印也就会传给B

注意:消费者将防止快照过期。可以指定“consumer.expiration-time”来管理消费者的生命周期。

缺点:

  • 数据丢失:若 next_snapshot_id 指定过旧快照,可能导致已消费数据重复处理。
  • 状态不一致:若未停止作业直接重置,可能引发进度冲突(如 Flink 状态与 Paimon 进度不匹配)。

<3> 查询优化

强烈建议在查询时指定分区和主键过滤器,这将加快查询的数据跳过速度。

1)可以加速数据跳跃的过滤函数有:
    =
    <
    <=
    >
    >=
    IN (...)
    LIKE 'abc%'
    IS NULL

2)Paimon会按主键对数据进行排序,从而加快点查询和范围查询的速度。
使用复合主键时,查询过滤器最好形成主键的最左边前缀,以获得良好的加速效果。
CREATE TABLE orders (
    catalog_id BIGINT,
    order_id BIGINT,
    .....,
    PRIMARY KEY (catalog_id, order_id) NOT ENFORCED -- composite primary key
)

通过为主键最左边的前缀指定范围过滤器,查询获得了很好的加速。(从catalog_id开始)
SELECT * FROM orders WHERE catalog_id=1025;

SELECT * FROM orders WHERE catalog_id=1025 AND order_id=29495;

SELECT * FROM orders
  WHERE catalog_id=1025jkjkjk
  AND order_id>2035 AND order_id<6000;
  
下面例子的过滤器不能很好地加速查询:(从order_id开始 或者 用了or)
SELECT * FROM orders WHERE order_id=29495;

SELECT * FROM orders WHERE catalog_id=1025 OR order_id=29495;