【TTL(Time To Live)+ ReplicatedMergeTree】分布式环境下自动清理过期数据

当然可以!在 ClickHouse 集群环境 中,将 TTL(Time To Live)ReplicatedMergeTree 结合使用,是实现分布式环境下自动清理过期数据的标准做法。它不仅能有效管理存储成本,还能确保多副本之间的一致性清理,是生产环境中日志、监控、事件类数据管理的必备能力。

本篇将深入详解如何在 多分片多副本集群 中安全、高效地使用 TTL + ReplicatedMergeTree,并附上配置、验证与最佳实践。


🎯 一、目标:实现集群级 TTL 自动清理

需求场景

  • 海量日志数据写入 ClickHouse 集群
  • 要求保留 90 天,过期自动删除
  • 确保所有副本同步清理,避免数据不一致
  • 支持冷热分层(可选)

核心挑战

  • TTL 清理是否在所有副本上一致?
  • 是否影响集群性能?
  • 如何监控清理进度?

✅ 解决方案:
ReplicatedMergeTree 表上配置 TTL,由 ZooKeeper/Keeper 协调,确保各副本清理行为一致。


🏗️ 二、架构回顾:集群 + 复制 + TTL

Cluster: analytics_cluster
│
├── Shard 1
│   ├── Replica 1 → node1 → ReplicatedMergeTree + TTL
│   └── Replica 2 → node2 → ReplicatedMergeTree + TTL
│
├── Shard 2
│   ├── Replica 1 → node3 → ReplicatedMergeTree + TTL
│   └── Replica 2 → node4 → ReplicatedMergeTree + TTL
  • 每个副本独立执行 TTL 清理
  • 清理行为由 ZooKeeperClickHouse Keeper 协调
  • 确保最终一致性

🔧 三、配置步骤:创建带 TTL 的复制表

1. 确保集群配置已定义(config.xml

<remote_servers>
    <analytics_cluster>
        <shard>
            <replica><host>node1</host><port>9000</port></replica>
            <replica><host>node2</host><port>9000</port></replica>
        </shard>
        <shard>
            <replica><host>node3</host><port>9000</port></replica>
            <replica><host>node4</host><port>9000</port></replica>
        </shard>
    </analytics_cluster>
</remote_servers>

2. 创建带 TTL 的 ReplicatedMergeTree 表(在任意节点执行)

CREATE TABLE user_log_cluster (
    user_id UInt32,
    event_date Date,
    event_type String,
    page_url String,
    duration UInt32,
    event_time DateTime
) ENGINE = ReplicatedMergeTree(
    '/clickhouse/tables/{shard}/user_log_cluster',  -- ZooKeeper 路径
    '{replica}'                                    -- 副本标识
)
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, user_id)
TTL event_date + INTERVAL 90 DAY                  -- 90天后自动删除
SETTINGS 
    merge_with_ttl_timeout = 86400;               -- 每24小时检查一次TTL

✅ 关键点:

  • ReplicatedMergeTree 支持 TTL
  • 所有副本会独立检查并清理过期数据
  • 清理进度可能略有差异,但最终一致

🔁 四、TTL 在集群中的工作原理

1. 数据写入任意副本

  • 写入 node1 → 通过 ZooKeeper 同步到 node2
  • 所有副本数据一致

2. TTL 触发(异步)

  • 每个副本的后台 Merge 任务定期检查:
    event_date + INTERVAL 90 DAY < today()
    
  • 如果满足,标记 Part 为“待删除”

3. 合并时清理

  • Merge 操作中,过期数据不会被写入新 Part
  • 原 Part 被标记为 inactive,最终删除

4. 副本间一致性

  • 清理不是原子操作,但:
    • 所有副本基于相同数据
    • 使用相同 TTL 表达式
    • 最终所有副本都会清理相同数据
  • 不依赖 ZooKeeper 协调删除操作,而是独立执行

📊 五、验证 TTL 清理是否生效

1. 检查某副本的待清理 Parts

-- 在 node1 上执行
SELECT 
    table,
    partition,
    name,
    rows,
    bytes_on_disk,
    remove_time
FROM system.parts
WHERE 
    table = 'user_log_cluster'
    AND remove_time IS NOT NULL
    AND active = 1;

remove_time 非空 → 已过期,等待清理


2. 检查所有副本的清理状态(对比)

-- 在每个节点执行
SELECT 
    'node1' AS host,
    count() AS parts_pending,
    sum(rows) AS rows_pending,
    formatBytes(sum(bytes_on_disk)) AS size_pending
FROM system.parts
WHERE table = 'user_log_cluster' AND remove_time IS NOT NULL;

✅ 预期:各副本的 size_pending 接近(允许微小差异)


3. 查看历史清理记录

SELECT
    event_date,
    sum(rows_removed) AS rows_removed,
    formatBytes(sum(bytes_removed)) AS bytes_removed
FROM system.part_log
WHERE 
    event_type = 'RemovePart'
    AND table = 'user_log_cluster'
    AND event_date >= today() - INTERVAL 7 DAY
GROUP BY event_date;

🌐 六、高级用法:TTL + 冷热分层(集群级)

1. 配置共享存储策略(所有节点 config.xml 一致)

<storage_configuration>
    <disks>
        <ssd> <path>/var/lib/clickhouse/ssd/</path> </ssd>
        <hdd> <path>/var/lib/clickhouse/hdd/</path> </hdd>
    </disks>
    <policies>
        <tiered>
            <volumes>
                <hot><disk>ssd</disk></hot>
                <warm><disk>hdd</disk></warm>
            </volumes>
        </tiered>
    </policies>
</storage_configuration>

2. 修改表 TTL 实现分层

ALTER TABLE user_log_cluster ON CLUSTER 'analytics_cluster'
MODIFY TTL 
  event_date + INTERVAL 7 DAY TO VOLUME 'warm',
  event_date + INTERVAL 90 DAY DELETE;

✅ 效果:

  • 7 天后数据从 SSD 迁移到 HDD
  • 90 天后删除
  • 所有分片和副本同步生效

⚠️ 七、注意事项与最佳实践

项目建议
TTL 表达式一致性所有副本必须使用相同表达式
merge_with_ttl_timeout建议 86400(避免频繁合并)
大表 OPTIMIZE FINAL❌ 禁止在集群大表上使用
监控清理延迟使用 system.part_log 分析延迟
批量清理大规模清理优先用 DROP PARTITION
ZooKeeper 负载TTL 不增加 ZooKeeper 负载(仅数据同步)

🛠️ 八、运维建议

1. 手动触发 TTL 合并(测试用)

-- 在某个副本上执行
OPTIMIZE TABLE user_log_cluster PARTITION '202401' FINAL;

⚠️ 仅用于测试,生产环境慎用

2. 监控脚本示例(Shell)

# 检查待清理数据量
clickhouse-client --query="
SELECT 
    sum(bytes_on_disk) AS pending_bytes
FROM system.parts 
WHERE table = 'user_log_cluster' AND remove_time IS NOT NULL
" | awk '{print "TTL Pending Size: " $1/1024/1024/1024 " GB"}'

🎯 九、总结:TTL + ReplicatedMergeTree 的核心价值

能力说明
🧹 自动清理90天后自动删除,无需人工干预
🔄 副本一致所有副本基于相同逻辑清理,最终一致
💾 节省成本减少存储占用,支持冷热分层
📈 可监控通过 system.partspart_log 监控
🧩 无缝集成与集群、分区、复制机制完美兼容

🎯 这是 ClickHouse 集群数据生命周期管理的“标准模式”
让你既能享受分布式扩展性,又能轻松管理存储成本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值