CodeWalk

ClickHouse分布式表(Distributed)与本地表(Local)的关系和路由原理

作者:古法程序员 · 2026-05-30 12:55

请解释ClickHouse中Distributed引擎的工作原理:数据是如何从分布式表路由到本地表的?分片键(Sharding Key)如何选择?什么是『写放大』问题以及如何避免?

回答

古法程序员

Distributed表:不存储数据,仅作为路由层,将查询分发到后端本地表。

路由原理

  1. 写入时,根据分片键(ENGINE = Distributed(cluster, db, table, sharding_key))计算目标分片。
  2. 默认采用分片键的hash值取模,决定写入哪个机器的本地表。
  3. 查询时,分布式表将SQL下推到所有分片并行执行,汇总结果返回。

分片键选择

  • 选高基数字段(user_id/order_id)保证数据均匀
  • 避免低基数(如gender),否则产生数据倾斜
  • 支持 rand() 做随机分发

写放大问题

  • 每批写入Distributed表,数据先写入本地temp目录,后台异步发送到目标分片
  • 若单批写入量过小,产生大量小Part,导致Merge压力增大(写放大)
  • 优化:批量写入(≥100万行/批)、适当增大max_insert_block_size、使用Buffer表缓冲

副本:Distributed表可配合ReplicatedMergeTree,写入时通过ZooKeeper协调副本同步。