CodeWalk

ClickHouse Local与Distributed表配合实现跨集群查询

作者:小字辈 · 2026-05-30 12:55

ClickHouse中Local表(本地表)与Distributed表(分布式表)在跨集群查询场景下如何配合?请解释Distributed表的分片键'rand()'和具体字段的区别、GLOBAL IN/JOIN的实现机制、以及集群间数据移动的最佳实践(如ALTER TABLE MOVE PARTITION跨集群迁移)。

回答

小字辈

Local + Distributed配合

  1. 表关系
-- 每台机器创建Local表
CREATE TABLE orders_local ON CLUSTER my_cluster (
  id UInt64, amount Float64, ts DateTime
) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/orders', '{replica}')
PARTITION BY toYYYYMM(ts)
ORDER BY (id, ts);

-- 创建Distributed表
CREATE TABLE orders_dist ON CLUSTER my_cluster
  AS orders_local
  ENGINE = Distributed(my_cluster, default, orders_local, rand());
  1. 分片键选择

    • rand():随机分布,适合无关键字段的场景
    • 具体字段:cityHash64(user_id),保证同user_id落入同一分片
    • 选高基数字段,避免数据倾斜
  2. GLOBAL IN/JOIN

    • IN子查询:默认每个分片本地执行子查询,结果可能不一致
    • GLOBAL IN:Coordinator先全局执行子查询,把结果广播到所有分片
    • 适用于子查询结果集较小(<1万行)的场景
    • GLOBAL JOIN同理,右表广播到所有分片
  3. 跨集群PARTITION移动

-- 在源集群
ALTER TABLE orders_local MOVE PARTITION '202505' TO SHARD 'new_shard';

-- 跨集群迁移(使用Frozen Backup)
# 1. 源集群:ALTER TABLE t FREEZE PARTITION '2025-05'
# 2. SCP文件到目标集群
# 3. 目标集群:ALTER TABLE t ATTACH PARTITION '2025-05'
  1. 查询路由
    • SELECT * FROM orders_dist → 下推到所有分片并行执行
    • 结果在Coordinator合并后返回