流式数据湖Paimon探秘之旅 (十三) 分区与过期管理

第13章:分区与过期管理

导言:如何优雅地清理旧数据

在运营一个大型数据系统时,会积累大量的历史数据。如何高效地清理?如何避免误删? 这就是分区与过期管理的核心问题。


第一部分:分区设计

1.1 分区的作用

css 复制代码
无分区表:
Table/
└── bucket-0/
    ├── file_1.parquet
    ├── file_2.parquet
    └── ... (万级文件)
    
问题:查询某日数据需要扫描所有文件

有分区表:
Table/
├── dt=2024-01-01/
│   └── bucket-0/
│       ├── file_1.parquet
│       ├── file_2.parquet
│       └── ...
├── dt=2024-01-02/
│   └── bucket-0/
│       ├── file_3.parquet
│       └── ...
└── ...

优势:
├─ 查询特定日期数据,仅扫描一个分区
├─ 清理历史数据,直接删除整个分区目录
└─ 性能提升100倍

1.2 分区字段选择

sql 复制代码
推荐:按时间分区
CREATE TABLE orders (
    order_id BIGINT PRIMARY KEY,
    user_id BIGINT,
    amount DECIMAL,
    dt DATE
) PARTITIONED BY (dt)  ← 按日期分区

原因:
├─ 时间维度天然递进
├─ 容易按日期删除旧数据
└─ 符合数据生命周期

多级分区(可选):
CREATE TABLE events (
    event_id STRING PRIMARY KEY,
    ...
    dt DATE,
    hour INT
) PARTITIONED BY (dt, hour)  ← 年月日 + 小时

优势:
├─ 更精细的数据组织
├─ 支持按小时清理
└─ 但增加复杂性(文件数增加)

第二部分:分区过期策略

2.1 自动过期配置

yaml 复制代码
CREATE TABLE orders (
    order_id BIGINT PRIMARY KEY,
    ...
    dt DATE
) PARTITIONED BY (dt) WITH (
    'partition.expiration.time' = '30d',
    'partition.expiration.check.interval' = '1d',
    'partition.expiration.strategy' = 'drop'
);

配置说明:
├─ partition.expiration.time:保留30天数据
├─ partition.expiration.check.interval:每天检查一次
└─ partition.expiration.strategy:直接删除分区

执行流程:
Time 1: Snapshot提交时检查是否有过期分区
Time 2: 发现dt=2023-12-01的分区(30天前)
Time 3: 删除该分区的所有文件
└─ 自动进行,无需手动干预

2.2 分区过期策略

sql 复制代码
策略1:DROP(删除)
├─ 直接删除过期分区
├─ 最常用
└─ 无法恢复

策略2:ARCHIVE(归档)
├─ 将过期分区移到低温存储
├─ 支持后续恢复
└─ 成本优化(冷热数据分离)

策略3:SOFT_DELETE(软删除)
├─ 标记为已删除,但不真正删除
├─ 支持快速恢复
└─ 适合关键数据

第三部分:动态分区重写

3.1 什么是动态分区重写

某些写入会涉及多个分区,但无法提前知道目标分区。此时使用动态分区重写

ini 复制代码
Upsert场景:
User A初始化:dt=2024-01-01, data="initial"
User A 30天后更新:dt=2024-01-31, data="updated"

同一主键跨越不同分区!

动态分区重写的作用:
├─ 接受跨分区的更新
├─ 自动路由到正确分区
├─ 保持数据一致性
└─ 支持ACID事务

配置:
'dynamic-partition-overwrite' = 'true'

第四部分:跨分区更新

4.1 跨分区UPDATE

sql 复制代码
-- 场景:用户状态从一个月跨到下一个月

UPDATE orders SET status='completed'
WHERE user_id=123 AND dt >= '2024-01-01';

目标行可能分散在多个分区:
├─ dt=2024-01-01的order(旧)
├─ dt=2024-01-15的order(新)
└─ ...

Paimon需要:
├─ 读取所有相关分区
├─ 应用更新
├─ 写入回各自的分区
└─ 提交一个原子Snapshot

4.2 跨分区DELETE

sql 复制代码
-- 场景:删除用户所有订单

DELETE FROM orders WHERE user_id=123;

受影响的分区:所有存在该用户的分区

Paimon处理:
├─ 找出所有包含user_id=123的分区
├─ 从各分区删除该用户的记录
├─ 生成新的Snapshot
└─ 原子提交

第五部分:生产级配置

5.1 电商订单表

yaml 复制代码
CREATE TABLE orders (
    order_id BIGINT PRIMARY KEY,
    user_id BIGINT,
    amount DECIMAL,
    status STRING,
    created_at BIGINT,
    updated_at BIGINT,
    dt DATE
) PARTITIONED BY (dt) WITH (
    'bucket' = '16',
    'merge-engine' = 'deduplicate',
    'sequence.field' = 'updated_at',
    'partition.expiration.time' = '90d',
    'partition.expiration.check.interval' = '1d',
    'dynamic-partition-overwrite' = 'true',
    'dynamic-partition-path' = '/path/to/default'
);

配置说明:
├─ 按日期分区,90天过期策略
├─ 支持跨分区更新
├─ 自动清理3个月前数据
└─ 存储成本:日均100GB增长,3个月清理可节省9TB

5.2 实时日志表

yaml 复制代码
CREATE TABLE logs (
    log_id STRING,
    level STRING,
    message STRING,
    ts BIGINT,
    dt DATE,
    hour INT
) PARTITIONED BY (dt, hour) WITH (
    'bucket' = '-1',
    'partition.expiration.time' = '7d',
    'partition.expiration.check.interval' = '1h'
);

配置说明:
├─ 按日期和小时二级分区
├─ 仅保留7天日志
├─ 每小时检查过期
└─ 及时清理,成本最优

总结

分区的核心价值

复制代码
效率:
└─ 查询特定分区时,避免扫描全表

成本:
├─ 自动清理旧分区
└─ 按时间维度管理数据生命周期

可维护性:
└─ 清晰的数据组织结构

配置checklist

  • 选择合适的分区字段(通常是日期)
  • 根据业务需求设置过期时间
  • 配置检查间隔(多久检查一次过期分区)
  • 启用动态分区(如需要跨分区更新)
  • 定期验证过期策略是否正确执行

下一章:第14章讲解Tag与分支管理

相关推荐
Aktx20FNz6 分钟前
iFlow CLI 完整工作流指南
大数据·elasticsearch·搜索引擎
LaughingZhu1 小时前
Anthropic 收购 Oven 后,Claude Code 用运行时写了一篇护城河文章
大数据·人工智能·经验分享·搜索引擎·语音识别
学习3人组1 小时前
TortoiseGit冲突解决实战上机练习
大数据·elasticsearch·搜索引擎
Ln5x9qZC21 小时前
Flink SQL 元数据持久化实战
大数据·sql·flink
OYpBNTQXi2 小时前
Flink Agents 源码解读 --- (6) --- ActionTask
大数据·flink
中金快讯2 小时前
济民健康医疗服务占比提升至46%!业务结构调整初见成效
大数据·人工智能
lizhihai_992 小时前
股市学习心得-尾盘半小时买入法
大数据
大大大大晴天️3 小时前
Hudi 生产问题排障-乱序Upsert入湖数据丢失
大数据·flink·hudi
程序大视界3 小时前
2026AI智能体元年,中国正式超越美国
大数据·人工智能
qq_235132173 小时前
五金制造行业ERP系统多少钱?易呈erp五金行业版功能模块详解与成功案例分享
大数据·运维·人工智能·制造·智能制造