将3分片无副本ClickHouse集群迁移至2分片集群的最优方案咨询
问题描述
当前运行版本为21.8的ClickHouse集群,包含3个无副本分片,存储了92张表共约60G数据。集群信息如下:
SELECT cluster, shard_num, shard_weight, replica_num FROM system.clusters
查询结果:
Row 1: ────── cluster: clickhouse shard_num: 1 shard_weight: 1 replica_num: 1 Row 2: ────── cluster: clickhouse shard_num: 2 shard_weight: 1 replica_num: 1 Row 3: ────── cluster: clickhouse shard_num: 3 shard_weight: 1 replica_num: 1
希望将现有集群的分片布局从3分片调整为2分片。已知ClickHouse不支持分片重平衡,目前考虑的方案是:
- 创建符合目标布局的全新集群
- 通过
INSERT FROM SELECT语句将现有数据复制到新集群
该方案虽直接但效率不高,询问是否存在更优实现方法。
更优实现方案
针对你的场景,有几种比INSERT FROM SELECT更高效的方案:
1. 使用官方工具clickhouse-copier
这是ClickHouse官方提供的分布式数据迁移工具,专门适配跨集群或集群内调整分片布局的场景,相比INSERT FROM SELECT有明显优势:
- 支持并行迁移,能充分利用集群CPU、带宽资源,大幅提升迁移速度
- 支持断点续传,迁移过程中断后可从断点恢复,无需从头开始
- 自动处理分片键的重新分布,无需手动计算数据归属分片
基本操作步骤:
- 编写XML配置文件,定义源集群(3分片)、目标集群(2分片)的连接信息,以及需要迁移的表列表和分片规则
- 在任意集群节点启动
clickhouse-copier进程,指定配置文件开始迁移 - 迁移完成后执行数据一致性校验,确认无误后切换业务到新集群
2. 直接迁移数据文件(适合无副本场景)
你的集群是无副本分片,且数据量仅60G,可直接操作底层数据文件,步骤如下:
- 先停止源分片的ClickHouse服务,避免迁移过程中有新数据写入
- 将源分片表数据目录(默认路径
/var/lib/clickhouse/data/<database>/<table>/)下的分区文件,根据目标集群的分片键规则,复制到对应目标分片的相同表目录下 - 在目标集群的每个分片上执行
ALTER TABLE ... ATTACH PARTITION命令,加载复制过来的分区数据 - 验证数据一致性后,切换业务并启动源分片服务(或直接下线源分片)
注意:操作前必须做好全量数据备份,且要保证复制的文件权限与ClickHouse运行用户一致,避免加载失败。
3. 利用ALTER TABLE ... MOVE PARTITION(集群内调整)
如果不需要新建集群,而是直接将现有3分片合并为2分片,可按以下步骤操作:
- 调整集群配置,添加2个目标分片(可复用现有节点,修改分片权重与编号)
- 对每张表,执行
ALTER TABLE <table> MOVE PARTITION <partition_id> TO SHARD <shard_num>命令,将源分片的分区迁移到目标分片 - 所有分区迁移完成后,移除旧的3分片配置,切换集群为2分片布局
注意:ClickHouse 21.8版本已支持该命令,操作期间需暂停业务写入,避免数据不一致。
方案对比
| 方案 | 效率 | 复杂度 | 风险 | 适用场景 |
|---|---|---|---|---|
INSERT FROM SELECT | 低 | 低 | 低 | 小数据量、快速验证场景 |
clickhouse-copier | 高 | 中 | 低 | 大规模数据、跨集群迁移场景 |
| 直接迁移数据文件 | 极高 | 中 | 中 | 无副本、小数据量、紧急场景 |
MOVE PARTITION | 高 | 中 | 中 | 集群内调整分片布局场景 |
内容的提问来源于stack exchange,提问作者zzzzzz
相关产品推荐
相关产品推荐

