流式数据湖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与分支管理

相关推荐
语落心生33 分钟前
流式数据湖Paimon探秘之旅 (十八) 常见问题排查与性能调优
大数据
语落心生35 分钟前
流式数据湖Paimon探秘之旅 (十五) 文件清理与维护
大数据
土拨鼠烧电路35 分钟前
RPA悖论迷思:从解放的利器到运维的枷锁?
大数据·运维·笔记·rpa
语落心生35 分钟前
流式数据湖Paimon探秘之旅 (十七) 集群部署与运维
大数据
语落心生38 分钟前
流式数据湖Paimon探秘之旅 (十二) 索引与加速
大数据
语落心生39 分钟前
流式数据湖Paimon探秘之旅 (十四) Tag与分支管理
大数据
语落心生40 分钟前
流式数据湖Paimon探秘之旅 (十一) Changelog变更日志
大数据
语落心生40 分钟前
流式数据湖Paimon探秘之旅 (十六) Flink集成深度解析
大数据
数据与后端架构提升之路43 分钟前
自动驾驶仿真数据闭环:如何利用大数据构建“上帝视角”的虚拟矩阵?(硬核指南)
大数据·矩阵·自动驾驶