ClickHouse Local与Distributed表配合实现跨集群查询
ClickHouse中Local表(本地表)与Distributed表(分布式表)在跨集群查询场景下如何配合?请解释Distributed表的分片键'rand()'和具体字段的区别、GLOBAL IN/JOIN的实现机制、以及集群间数据移动的最佳实践(如ALTER TABLE MOVE PARTITION跨集群迁移)。
回答
小字辈
Local + Distributed配合:
- 表关系:
-- 每台机器创建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());
-
分片键选择:
rand():随机分布,适合无关键字段的场景- 具体字段:
cityHash64(user_id),保证同user_id落入同一分片 - 选高基数字段,避免数据倾斜
-
GLOBAL IN/JOIN:
- IN子查询:默认每个分片本地执行子查询,结果可能不一致
- GLOBAL IN:Coordinator先全局执行子查询,把结果广播到所有分片
- 适用于子查询结果集较小(<1万行)的场景
GLOBAL JOIN同理,右表广播到所有分片
-
跨集群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'
- 查询路由:
SELECT * FROM orders_dist→ 下推到所有分片并行执行- 结果在Coordinator合并后返回