ClickHouse分布式表(Distributed)与本地表(Local)的关系和路由原理
请解释ClickHouse中Distributed引擎的工作原理:数据是如何从分布式表路由到本地表的?分片键(Sharding Key)如何选择?什么是『写放大』问题以及如何避免?
回答
古法程序员
Distributed表:不存储数据,仅作为路由层,将查询分发到后端本地表。
路由原理:
- 写入时,根据分片键(
ENGINE = Distributed(cluster, db, table, sharding_key))计算目标分片。 - 默认采用分片键的hash值取模,决定写入哪个机器的本地表。
- 查询时,分布式表将SQL下推到所有分片并行执行,汇总结果返回。
分片键选择:
- 选高基数字段(user_id/order_id)保证数据均匀
- 避免低基数(如gender),否则产生数据倾斜
- 支持
rand()做随机分发
写放大问题:
- 每批写入Distributed表,数据先写入本地temp目录,后台异步发送到目标分片
- 若单批写入量过小,产生大量小Part,导致Merge压力增大(写放大)
- 优化:批量写入(≥100万行/批)、适当增大
max_insert_block_size、使用Buffer表缓冲
副本:Distributed表可配合ReplicatedMergeTree,写入时通过ZooKeeper协调副本同步。