在使用ClickHouse过程中免不了需要数据迁移,比如更新表结构、迁移数据到新的集群。如何尽量将影响降低,加快迁移过程是数据迁移的关键。
可用方案横向对比
Altinity Wiki详细罗列了所有可用的迁移方案^data_migration,这里做一个汇总。没有最好的方案,只有最适合的方案。
导出导入 | clickhouse-backup | remote/remoteSecure和cluster/Distributed表 | clickhouse-copier | 手动分区迁移freeze/rsync/attach | 利用zookeeper同步 | 利用clickhouse自带Replication同步 | |
---|---|---|---|---|---|---|---|
方案描述 | 使用clickhouse-client工具将数据从源实例导出,再导入到目标实例 | 使用第三方clickhouse-backup工具将数据从源实例导出,再导入到目标实例 | 利用remote、cluster或者Distributed表函数直接在目标实例访问源实例数据 | 使用官方clickhouse-copier工具迁移数据 | 手动将一个个分区在源实例freeze,利用rsync工具传输到目标实例,在目标实例attach分区 | ALTER TABLE FETCH PARTITION FROM zookeeper实现自动迁移 | clickhouse会自动保持同一shard之间不同replica的数据同步,所以将目标实例注册成源实例的replica,就会自动同步数据 |
速度 | 慢 | 中 | 中 | 快 | 慢 | 慢 | 快 |
复杂性 | 低 | 低 | 低 | 高 | 高 | 中 | 中 |
资源消耗 | 中 | 低 | (目标实例)高 | (目标实例)高 | 低 | 低 | 低 |
数据分布可变 | 可以 | 不可以 | 可以 | 可以 | 可以 | 不可以 | 不可以 |
schema可变 | 完全可变 | 不可变 | 完全可变 | 部分可变* | 不可变 | 不可变 | 不可变 |
依赖工具 | clickhouse-client | clickhouse-backup | 无 | zookeeper | rsync等数据同步工具 | zookeeper | zookeeper |
要求 | 无 | 无 | 目标实例可以访问源实例TCP端口 | 无 | 手动实现脚本、操作 | 目标实例使用源实例的zookeeper | 目标实例使用源实例的zookeeper |
适数据用场景 | 少量数据变备份边迁移 | 海量数据边备份边迁移 | 部分数据迁移,特别是需要修改schema | 海量数据迁移 | 不推荐 | 海量数据迁移且希望低资源开销 | 数据插入不可停止的实时迁移 |
部分可变:可以修改表meta定义,比如主键、TTL。可以修改字段CODEC。但是不能修改字段名、字段类型。
remote/remoteSecure和cluster/Distributed表
这个方案是最简单的,速度不错且自由度极高。除非海量数据,迁移数据首选该方案。
这个方案有三个需要注意的地方:
- 两边实例
max_execution_time
配置限制SQL执行超时。执行查询前务必将max_execution_time
设置为0或者一个极大值,避免数据插入一半因为超时被中止。 - 数据迁移一旦中途中止,需要手动清理目标实例中迁移的数据后重试,否则会有数据重复。
- 目标节点负载较高,一般是性能瓶颈,为了加速插入,可以调整配置。ClickHouse将插入的数据拆封为block,
min_insert_block_size_rows
或min_insert_block_size_bytes
命中就会将block落盘。当max_insert_threads
大于1,就会同时在内存中形成多个block。最大内存使用可以计算max_insert_threads * first(min_insert_block_size_rows OR min_insert_block_size_bytes)
。可以根据行大小在内存允许的条件下调大这几个值。
clickhouse-copier
clickhouse-copier是第二推荐的方案,除非需要修改字段名/类型,都可以使用该方案。
该方案需要额外的zookeeper,但是可以同时执行大量数据迁移。clickhouse-copier会在目标实例创建_piece_x
表,将源实例的数据拆分到这些临时表中, 最后将数据插入回目标实例的目标表。由于实际还是INSERT
,建议将所有物化视图DETACH
避免影响插入速度。
clickhouse-copier执行过程如下图所示:
任务配置文件^clickhouse_copier有几个需要注意的地方:
remote_servers
部分中,不同shard尽量设置internal_replication
减少网络数据IO。tables
部分中cluster_pull
、cluster_push
填入的是remote_servers
中定义的cluster而不是实例中的cluster。- clickhouse-copier旧版本存在bug^clickhouse_copier_bugs,若遇到
DB::Exception: Engine Distributed doesn't support skipping indices.
、DB::Exception: Engine Distributed doesn't support TTL.
,可以尝试使用更新版本的clickhouse-copier。 - 使用clickhouse-copier时,源表、目标表的数据插入都要停止。迁移时设置好数据时间范围,方便迁移完成后补全迁移期间空档数据。
- 如果迁移的目标是Replicated表,一定设置
internal_replication
为true
,否则会导致数据重复。^clickhouse_copier_distributed
引用
undefined
undefined
undefined
undefined
undefined