在 ClickHouse 中,TTL(Time To Live) 是一个非常强大且实用的功能,它允许你为数据设置“生命周期”,实现自动清理过期数据、冷热数据分层存储、按时间归档等操作,特别适用于日志、监控、事件流等时效性强的场景。
本篇将全面、深入地详解 ClickHouse TTL 的使用方法、工作原理、配置技巧与最佳实践。
🎯 一、TTL 的核心价值
| 能力 | 说明 |
|---|---|
| 🧹 自动清理过期数据 | 无需手动 DELETE 或 DROP PARTITION |
| 💾 节省存储成本 | 自动删除 N 天前的数据 |
| 🌐 冷热分层存储 | 热数据放 SSD,冷数据迁移到 HDD/S3 |
| ⏳ 数据生命周期管理 | 实现“写入 → 保留 → 归档 → 删除”闭环 |
✅ 适用场景:
- 日志保留 7 天、30 天
- 监控指标保留 90 天
- 用户行为数据冷热分离
🏗️ 二、TTL 基本语法
TTL time_column + INTERVAL N [SECOND|MINUTE|HOUR|DAY] [DELETE|TO DISK 'disk'|TO VOLUME 'volume']
1. 简单删除(最常见)
TTL event_date + INTERVAL 30 DAY
30 天后自动删除
2. 多条件 TTL
TTL
event_date + INTERVAL 7 DAY TO DISK 'hdd',
event_date + INTERVAL 30 DAY TO DISK 's3',
event_date + INTERVAL 90 DAY DELETE
- 7 天后迁移到 HDD
- 30 天后迁移到 S3
- 90 天后删除
3. 基于 DateTime 列
TTL event_time + INTERVAL 1 MONTH
📦 三、实战:配置 TTL 实现自动清理
1. 创建带 TTL 的表(自动删除)
CREATE TABLE user_log (
user_id UInt32,
event_type String,
page_url String,
duration UInt32,
event_date Date,
event_time DateTime
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, user_id)
TTL event_date + INTERVAL 90 DAY; -- 90天后自动删除
✅ 效果:写入 90 天后,数据被后台任务自动清除。
2. 冷热分层存储(SSD → HDD → S3)
步骤 1:定义存储策略(在 config.xml 中)
<storage_configuration>
<disks>
<ssd>
<path>/var/lib/clickhouse/ssd/</path>
</ssd>
<hdd>
<path>/var/lib/clickhouse/hdd/</path>
</hdd>
<s3>
<type>s3</type>
<endpoint>https://s3.example.com/bucket/clickhouse/</endpoint>
<access_key_id>ACCESS_KEY</access_key_id>
<secret_access_key>SECRET_KEY</secret_access_key>
</s3>
</disks>
<policies>
<tiered>
<volumes>
<hot><disk>ssd</disk></hot>
<warm><disk>hdd</disk></warm>
<cold><disk>s3</disk></cold>
</volumes>
<move_factor>0.2</move_factor>
</tiered>
</policies>
</storage_configuration>
步骤 2:创建表并设置 TTL 分层
CREATE TABLE user_log_tiered (
user_id UInt32,
event_type String,
page_url String,
duration UInt32,
event_date Date,
event_time DateTime
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, user_id)
TTL
event_date + INTERVAL 7 DAY TO VOLUME 'warm', -- 7天后迁移到 HDD
event_date + INTERVAL 30 DAY TO VOLUME 'cold', -- 30天后迁移到 S3
event_date + INTERVAL 180 DAY DELETE; -- 180天后删除
✅ 实现真正的“冷热数据分层”。
🔁 四、TTL 的工作原理
1. 异步执行
- TTL 不是实时触发,而是由后台 合并(Merge)任务 触发。
- 当 ClickHouse 执行
Merge操作时,会检查数据是否过期。
2. 合并时清理
- 过期数据所在的 Part 在合并时会被跳过,不再写入新 Part。
- 最终该 Part 被标记为可删除。
3. 删除时机
- 数据不会立即消失,而是在后续合并中逐步清理。
- 可通过
OPTIMIZE TABLE ... FINAL手动触发。
🛠️ 五、TTL 相关 SETTINGS 参数
| 参数 | 说明 | 推荐值 |
|---|---|---|
merge_with_ttl_timeout | 两次 TTL 合并的最小间隔(秒) | 86400(1天) |
ttl_only_drop_parts | 是否只删除整个 Part(更快) | 1(实验性) |
示例
CREATE TABLE log_ttl ...
TTL event_date + INTERVAL 30 DAY
SETTINGS
merge_with_ttl_timeout = 3600; -- 每小时检查一次
⚠️ 注意:设置太小会频繁触发合并,影响性能。
🔍 六、如何监控 TTL 状态?
1. 查看 parts 的 TTL 信息
SELECT
name,
partition,
rows,
bytes_on_disk,
modification_time,
remove_time -- 被标记删除的时间
FROM system.parts
WHERE table = 'user_log'
AND database = 'default'
AND remove_time IS NOT NULL;
✅
remove_time非空表示该 Part 已过期,等待删除。
2. 查看 TTL 统计
SELECT
database,
table,
sum(rows_removed),
sum(bytes_removed)
FROM system.part_log
WHERE event_type = 'RemovePart'
AND part_name LIKE '%ttl%'
GROUP BY database, table;
⚠️ 七、注意事项与常见问题
| 问题 | 说明 | 解决方案 |
|---|---|---|
| TTL 不立即生效 | 异步执行,依赖合并 | 手动 OPTIMIZE TABLE ... FINAL |
OPTIMIZE FINAL 性能差 | 强制合并所有 Parts | 避免在大表上频繁使用 |
| 分区删除更快 | DROP PARTITION 是瞬时操作 | 大批量清理优先用分区 |
| TTL 列必须是 Date/DateTime | 否则报错 | 确保 event_date 类型正确 |
| 复合 TTL 顺序重要 | 按时间升序写 | 先 7 天,再 30 天,最后删除 |
✅ 八、最佳实践建议
| 场景 | 推荐做法 |
|---|---|
| 日志保留 7 天 | TTL event_date + INTERVAL 7 DAY |
| 监控数据冷热分层 | TO VOLUME 'hdd' / TO S3 |
| 避免频繁合并 | merge_with_ttl_timeout = 86400 |
| 大批量清理 | 优先 DROP PARTITION |
| 测试 TTL | 先用 INTERVAL 1 MINUTE 测试 |
| 监控 | 定期检查 system.parts 的 remove_time |
🎯 九、总结:TTL 的核心价值
| 模式 | 语法示例 | 用途 |
|---|---|---|
| 自动删除 | TTL date + INTERVAL 30 DAY | 清理过期数据 |
| 冷热分层 | TO DISK 'hdd' | 节省 SSD 成本 |
| 多级归档 | TO VOLUME 's3' | 构建 Lakehouse |
| 动态保留 | TTL update_time + INTERVAL version_days DAY | 按版本保留 |
🎯 TTL 是 ClickHouse 的“数据管家”:
它让数据生命周期管理变得自动化、低成本、可预测。
539

被折叠的 条评论
为什么被折叠?



