ClickHouse数据迁移实战:clickhouse-copier的配置与优化

张开发
2026/4/5 2:37:19 15 分钟阅读

分享文章

ClickHouse数据迁移实战:clickhouse-copier的配置与优化
1. ClickHouse数据迁移的三种武器当你需要把ClickHouse数据从一个地方搬到另一个地方时就像搬家一样需要选择合适的工具。我经历过多次数据迁移总结下来主要有三种常用方法各有各的适用场景。第一种是直接拷贝数据目录这就像把整个衣柜原封不动搬到新家。操作简单粗暴打包源集群的data和metadata目录复制到目标集群对应位置然后重启服务。这种方法最快但有个致命缺点——迁移过程中源集群必须停止写入就像搬家时得先把衣柜锁起来不让放新衣服。第二种是使用remote函数配合INSERT SELECT这就像一件件把衣服从旧衣柜拿到新衣柜。具体操作是用INSERT INTO local_table SELECT * FROM remote(...)语句。我常用这个方法迁移小表实测100GB以下数据效果不错。优点是灵活可以边迁移边转换数据缺点是单线程操作大表迁移会慢得让人抓狂。第三种就是今天的主角clickhouse-copier它像专业的搬家公司能多线程打包运输。这是ClickHouse官方提供的分布式迁移工具最大特点是基于Zookeeper的任务协调支持多实例并行可增量同步分区数据自动处理ReplicatedMergeTree表引擎转换2. clickhouse-copier的实战配置2.1 环境准备与依赖安装第一次配置clickhouse-copier时我踩过不少坑。首先要确保所有节点都满足相同版本的ClickHouse版本差异会导致奇怪错误Zookeeper集群建议3节点以上网络互通特别是Zookeeper端口和ClickHouse端口安装其实很简单copier工具已经包含在clickhouse-client包里。如果你已经装了客户端直接就能用which clickhouse-copier # 正常应该输出类似/usr/bin/clickhouse-copier2.2 Zookeeper配置详解copier重度依赖Zookeeper配置文件zookeeper.xml是第一个关键点。这是我的生产配置模板yandex logger leveltrace/level log/var/log/clickhouse-copier.log/log size100M/size count3/count /logger zookeeper node index1 hostzk1.prod.cluster/host port2181/port /node node index2 hostzk2.prod.cluster/host port2181/port /node node index3 hostzk3.prod.cluster/host port2181/port /node session_timeout_ms30000/session_timeout_ms operation_timeout_ms10000/operation_timeout_ms /zookeeper /yandex几个容易出问题的地方session_timeout_ms不要设太小网络不稳定时会导致频繁重连生产环境一定要配多个Zookeeper节点日志路径要有写入权限2.3 任务配置文件剖析任务配置文件是copier的核心我把它拆解为几个关键部分集群连接配置remote_servers !-- 源集群 -- source_cluster shard replica hostsource01/host port9000/port usermig_user/user passwordsecure_pass/password /replica /shard /source_cluster !-- 目标集群 -- target_cluster shard internal_replicationtrue/internal_replication replica hosttarget01/host port9000/port /replica /shard /target_cluster /remote_servers表迁移配置tables user_events !-- 任务标识名 -- cluster_pullsource_cluster/cluster_pull database_pullanalytics/database_pull table_pulluser_events/table_pull cluster_pushtarget_cluster/cluster_push database_pushanalytics_prod/database_push table_pushuser_events_v2/table_push engine ENGINE ReplicatedMergeTree(/clickhouse/tables/{shard}/analytics_prod/user_events_v2, {replica}) PARTITION BY toYYYYMM(event_time) ORDER BY (user_id, event_type) SETTINGS index_granularity 8192 /engine sharding_keyrand()/sharding_key /user_events /tables特别注意engine配置必须完整且正确copier会用它创建新表如果源表有分区一定要在目标表保留相同或兼容的分区策略sharding_key影响数据分布要谨慎选择3. 性能优化实战技巧3.1 并发控制的艺术copier的并发控制有两个关键参数max_workers控制单个copier进程的线程数copier实例数可以启动多个copier进程我的经验公式最优worker数 min(源集群分片数 × 2, CPU核心数 - 2)例如对于4分片的源集群8核服务器配置max_workers6/max_workers同时可以在3台服务器上各启动一个copier实例。3.2 分区策略优化迁移超大规模表时我常用这些技巧分批迁移分区enabled_partitions 202301,202302,202303 /enabled_partitions动态分区过滤where_condition event_date 2023-01-01 /where_condition夜间增量同步# 每天只同步当天分区 clickhouse-copier --task-path/migration/daily \ --config zookeeper.xml \ --task-filedaily_increment.xml3.3 网络与资源调优在迁移10TB级数据时这些配置很关键压缩传输distributed_connections compressiontrue/compression connect_timeout60/connect_timeout /distributed_connections批量大小调整settings max_insert_block_size1048576/max_insert_block_size /settings限流保护throttler bytes_per_second104857600/bytes_per_second !-- 100MB/s -- /throttler4. 常见问题排查指南4.1 Zookeeper相关错误问题1频繁出现Session expired错误检查ZK服务端日志常见于磁盘IO瓶颈调整session_timeout_ms到30000以上增加ZK集群资源问题2节点不存在错误确保task-path在ZK上已创建检查zkCli的ACL权限4.2 数据不一致问题我遇到过几次目标表行数少于源表的情况排查步骤检查copier日志中的WARN和ERROR对比源表和目标表的分区状态SELECT partition, count() FROM source_table GROUP BY partition; SELECT partition, count() FROM target_table GROUP BY partition;验证where_condition是否过滤了过多数据4.3 性能瓶颈分析当迁移速度不符合预期时按这个顺序检查网络带宽iftop看流量是否打满CPU使用率copier进程是否充分利用多核磁盘IOiostat看磁盘是否成为瓶颈ClickHouse负载检查query_log是否有慢查询5. 生产环境最佳实践经过多次实战我总结出这些黄金法则预创建目标表结构先用CREATE TABLE手动创建目标表确保schema正确先小后大原则先用小表验证配置然后按数据量从大到小迁移最后处理物化视图监控三板斧Zookeeper的znode数量监控copier进程的CPU/内存监控网络流量监控回滚方案# 保留每次迁移的配置和日志 mkdir -p /backup/migration/$(date %Y%m%d) cp *.xml /backup/migration/$(date %Y%m%d)/最终一致性检查脚本-- 行数比对 SELECT (SELECT count() FROM source_table) AS source_count, (SELECT count() FROM target_table) AS target_count, source_count - target_count AS diff; -- 抽样校验 SELECT * FROM source_table LIMIT 1000 EXCEPT DISTINCT SELECT * FROM target_table LIMIT 1000;在最近一次跨机房迁移中这套方法帮助我们在8小时内完成了15TB数据的迁移期间业务查询完全不受影响。最关键的是提前做了充分的测试用1%的数据量模拟了全量迁移过程发现了三个潜在配置问题。

更多文章