编程 ClickHouse 复制队列:属于副本,不属于表

2026-09-08 03:08:17

ClickHouse 复制队列:属于副本,不属于表

在 CH-Ops(自托管 ClickHouse 管理 GUI)上测试 1 shard 2 replicas 时,作者停了 Node B,从 Node A 插入数据,然后看 Node B 的队列有积压、Node A 队列却空。第一直觉是"集群级待复制总量"——但 A 刚收到新数据应该也有待同步项才对。这个不匹配引出了核心心智模型。

队列属于副本,不属于表

ReplicatedMergeTree 表有多个副本持有相同数据,容易想象成副本间一根共享管道。不是。每个副本维护自己的本地复制队列。

Replica 1 → queue_size = 0
Replica 2 → queue_size = 25

这不是"25 个操作在中间等两个副本取",而是Replica 2 自己有 25 个未完成任务。Node B 恢复后队列几秒排空、数据出现。

任务从哪来

ClickHouse 复制不是副本间直接拷贝,中间有协调层:ClickHouse Keeper 持有复制日志——表上发生过的操作记录。发生复制事件(part 插入、merge、mutation)时,操作记入 Keeper;每个副本 watch 日志,算出"我要做什么才能追上",变成任务落进该副本自己的队列。任务可能是:fetch part、merge parts、apply mutation、drop range。

队列本质是从共享日志生成、但本地执行的待办清单

在哪看:system.replicas

SELECT database, table, replica_name, is_leader, is_readonly,
       queue_size, inserts_in_queue, merges_in_queue,
       part_mutations_in_queue, absolute_delay
FROM system.replicas;

示例输出:

┌─replica_name─┬─queue_size─┬─inserts_in_queue─┬─merges_in_queue─┬─absolute_delay─┐
│ replica_1    │          0 │               0 │               0 │              0 │
│ replica_2    │         12 │               3 │               9 │              4 │
└──────────────┴────────────┴──────────────────┴─────────────────┴────────────────┘

queue_size 是总量,inserts_in_queue/merges_in_queue 分开看积压来源,absolute_delay 反映滞后秒数。

实践建议

  • 排查复制积压先定位是哪个副本:队列是每副本视角,别当集群级读数;
  • 看 system.replicas 分维度判断积压类型(insert vs merge vs mutation);
  • 副本长期 down 后恢复,队列排空快不代表数据已全部落盘——结合 absolute_delay 与数据校验确认。

来源:Understanding the Replication Queue in ClickHouse - DEV Community

复制全文 生成海报 ClickHouse 数据库 分布式 运维

推荐文章

程序员茄子在线接单