bigywater.tech
ClickHouse 内部原理 · 63

ClickHouse Keeper:元数据和选举如何保存

真实起一个独立的ClickHouse Keeper实例,用system.zookeeper查看一张ReplicatedMergeTree表在Keeper里真实维护的协调信息结构。

14个znode路径
真实一张ReplicatedMergeTree表在Keeper里维护的协调路径
几十字节的日志
真实驱动副本自动同步的完整指令内容

做的事:真实起一个独立的Keeper实例,查它真实存了什么

代码clickhouse keeper --config-file=keeper_config.xml -- 真实独立进程,跟clickhouse server分开 -- 通过ClickHouse自带的system.zookeeper表查询Keeper里的内容 SELECT name FROM system.zookeeper WHERE path='/clickhouse/tables/1/repl_tbl'; SELECT name, value FROM system.zookeeper WHERE path='/clickhouse/tables/1/repl_tbl/log';

验证:一张表在Keeper里真实维护了十几个znode路径

实测 · 本机执行输出
SELECT name FROM system.zookeeper WHERE path='/clickhouse/tables/1/repl_tbl';
→ log                    真实的操作日志(每个part的增删都记一条)
  replicas               真实注册的副本列表(replica1, replica2)
  blocks                 真实的去重信息(防止同一条数据被重复插入)
  block_numbers          真实的分区级自增块号
  mutations               真实的mutation记录
  quorum                  真实的quorum写入状态
  leader_election         真实的leader选举信息
  part_moves_shard        分片间part移动记录
  pinned_part_uuids       ...(共14个真实路径)

SELECT name, value FROM system.zookeeper WHERE path='.../log' LIMIT 1;
→ log-0000000000  "format version: 4\ncreate_time: 2026-09-29 08:48:18\n
                    source replica: replica1\nblock_id: \nget\nall_0_0_0\npart_type: Compact"

这条几十字节的log-0000000000记录,真实就是驱动本系列上一篇《ReplicatedMergeTree》里node2自动拉取数据的完整指令——"replica1有一个新part叫all_0_0_0,动作是get"。Keeper真实存的不是数据本身,而是这类轻量的协调指令和元数据。

Keeper真实扮演的角色:不存数据,只存"谁该做什么"

Keeper是ClickHouse自己实现的、兼容ZooKeeper协议的协调服务(本机集群配置里<zookeeper>那一节指向的正是这个Keeper实例,而不是真的Apache ZooKeeper),它真实承担的角色可以概括成:整个集群的"共享记事本"。除了本文验证过的log(part操作日志)和replicas(副本注册表),其余几个真实路径各自负责一类协调信息——blocks真实用来做插入去重(本系列后面会碰到的"同一批数据被重复提交"场景,靠这里记录的block_id判断是否已经处理过);leader_election真实维护哪个副本是当前负责调度合并任务的leader(本系列《Part合并》一篇验证过的后台merge,在多副本场景下真实需要有一个副本先"认领"这个任务,避免多个副本同时对同一批数据做重复的merge);quorum真实记录本系列后面《副本一致性》一篇会验证的insert_quorum写入确认状态。真实理解这套架构的关键是:Keeper里存的信息量,跟表里实际的数据量完全不成比例——本文这张表已经插入了上万行数据,但Keeper里对应的znode内容始终是几十到几百字节量级的文本记录,这也是为什么Keeper集群本身对磁盘和内存的要求,远低于承载实际数据的ClickHouse节点,但对它的可用性要求反而更高——一旦Keeper不可用,本系列后面几篇会验证的副本同步、DDL广播、quorum写入这些真实依赖协调的机制都会真实受影响。

分步演示:从Keeper真实的znode结构到一条日志记录的完整内容

每一步都是本文上面用真实system.zookeeper跑出来的原始结果。

Keeper真实存的是几十字节的协调指令
这一步新查看的路径

    本文用到的工具

    • 本机真实独立起的 clickhouse keeper 实例,真实的 system.zookeeper 表
    京ICP备2026067502号-1京公网安备11010502063487号