第04期:MergeTree 引擎之数据分区

前面通过 一文了解 ClickHouse 介绍过 ClickHouse 的特性、结构、使用场景。自己并未完全深入学习 clickhouse,因为公司打算小范围使用 ClickHouse,所以有必要深入学习之。本文主要内容是关于了解 Clickhouse 的分区感念和分区合并规则。

MergeTree 数据分区规则

创建按照月份为分区条件的表 tab_partition

CREATE TABLE tab_partition(`dt` Date, `v` UInt8) 
ENGINE = MergeTree PARTITION BY toYYYYMM(dt) ORDER BY v;
insert into tab_partition(dt,v) values ('2020-02-11',1),('2020-02-13',2);
insert into tab_partition(dt,v) values ('2020-04-11',3),('2020-04-13',4);
insert into tab_partition(dt,v) values ('2020-09-11',5),('2020-09-10',6);
insert into tab_partition(dt,v) values ('2020-10-12',7),('2020-10-09',8);
insert into tab_partition(dt,v) values ('2020-02-14',9),('2020-02-15',10);
insert into tab_partition(dt,v) values ('2020-02-11',23),('2020-02-13',45);

MergeTree 存储引擎在写入数据之后生成对应的分区文件为:

MergeTree 的分区目录是在写入数据的过程中被创建出来,每 insert 一次,就会创建一批次分区目录。也就是说如果仅创建表结构,是不会创建分区目录的,因为木有数据。

MergeTree 数据分区目录命名规则其规则为:PartitionID_MinBlockNum_MaxBlockNum_Level
比如 202002_4_4_0 其中 202002 是分区ID ,4_4 对应的是
最小的数据块编号和最大的数据块编号,最后的 _0 表示目前分区合并的层级。
各部分的含义及命名规则如下:
PartitionID:该值由 insert 数据时分区键的值来决定。分区键支持使用任何一个或者多个字段组合表达式,针对取值数据类型的不同,分区 ID 的生成逻辑目前有四种规则:

不指定分区键:如果建表时未指定分区键,则分区 ID 默认使用 all,所有数据都被写入 all 分区中。

整型字段:如果分区键取值是整型字段,并且无法转换为 YYYYMMDD 的格式,则会按照该整型字段的字符形式输出,作为分区 ID 取值。

日期类型:如果分区键属于日期格式,或可以转换为 YYYYMMDD 格式的整型,则按照 YYYYMMDD 格式化后的字符形式输出,作为分区 ID 取值。

其他类型:如果使用其他类似 Float、String 等类型作为分区键,会通过对其插入数据的 128 位 Hash 值作为分区 ID 的取值。

MinBlockNum 和 MaxBlockNum:BlockNum 是一个整型的自增长型编号,该编号在单张 MergeTree 表中从 1 开始全局累加,当有新的分区目录创建后,该值就加 1,对新的分区目录来讲,MinBlockNum 和 MaxBlockNum 取值相同。例如上面示例数据为 202002_1_1_0 202002_1_5_1,但当分区目录进行合并后,取值规则会发生变化,MinBlockNum 取同一分区所欲目录中最新的 MinBlockNum 值。MaxBlockNum 取同一分区内所有目录中的最大值。
Level:表示合并的层级。相当于某个分区被合并的次数,它不是以表全局累加,而是以分区为单位,初始创建的分区,初始值为 0,相同分区 ID 发生合并动作时,在相应分区内累计加 1。

MergeTree 数据分区合并规则

随着数据的写入 MergeTree 存储引擎会很多分区目录。如果分区目录数太多怎么办?因为 Clickhouse 的 MergeTree 存储引擎是基于 LSM 实现的。MergeTree 可以通过分区合并将属于相同分区的多个目录合并为一个新的目录(官方描述在 10 到 15 分钟内会进行合并,也可直接执行 optimize 语句),已经存在的旧目录(也即 system.parts 表中 activie 为 0 的分区)在之后某个时刻通过后台任务删除(默认 8 分钟)。

分区合并

我们回顾之前创建的表的分区目录

# ls 
202002_1_1_0  202004_2_2_0  202009_3_3_0
202002_4_4_0  202002_5_5_0

手工触发分区合并

qabb-qa-ch00 :) optimize table tab_partition;
OPTIMIZE TABLE tab_partition
Ok.
0 rows in set. Elapsed: 0.003 sec.

qabb-qa-ch00 :) select partition,name,part_type, active from system.parts where  table ='tab_partition';
┌─partition─┬─name─────────┬─part_type─┬─active─┐
│ 202002    │ 202002_1_1_0 │ Wide      │      0 │
│ 202002    │ 202002_1_5_1 │ Wide      │      1 │
│ 202002    │ 202002_4_4_0 │ Wide      │      0 │
│ 202002    │ 202002_5_5_0 │ Wide      │      0 │
│ 202004    │ 202004_2_2_0 │ Wide      │      1 │
│ 202009    │ 202009_3_3_0 │ Wide      │      1 │
└───────────┴──────────────┴───────────┴────────┘

6 rows in set. Elapsed: 0.003 sec.

其中 active 为 1 表示经过合并之后的最新分区,为 0 则表示旧分区,查询时会自动过滤 active=0 的分区。
我们通过分区 202002 最新的分区目录 202002_1_5_1 看到合并分区新目录的命名规则如下:

PartitionID:分区 ID 保持不变
MinBlockNum:取同一个分区内所有目录中最小的 MinBlockNum 值
MaxBlockNUm:取同一个分区内所有目录中最大的 MaxBlockNum 值
Level:取同一个分区内最大 Level 值并加 1

合并之后的目录结构如下:

小结

本文可以认为是《ClickHouse 原理解析与应用实践》的学习笔记。通过案例介绍了 MergeTree 的分区产生的机制,命名规则,以及合并的基本过程。有兴趣的朋友可以自己动手实践一下。


关于 ClickHouse 的技术内容,你们还有什么想知道的吗?赶紧留言告诉小编吧!

<think>好的,用户想了解ClickHouse数据迁移。首先,我需要回顾一下ClickHouse数据迁移方法,确保自己记得正确。常见的迁移方式有几种,比如使用INSERT SELECT语句、导出导入CSV文件,或者用备份工具如clickhouse-backup。还有跨集群复制的情况,可能需要用到远程表或者分布式表。 用户可能是在实际项目中遇到了迁移需求,比如要更换服务器,或者做数据归档,也可能是在不同集群之间迁移。需要分情况讨论,但回答时要保持结构清晰,步骤明确。同时,用户可能需要考虑数据量的大小,迁移过程中如何保证数据一致性和最小化停机时间。 要注意用户是否提到具体环境,比如是否跨版本迁移,是否有网络限制,但问题中没有这些信息,所以需要概括性回答。另外,需要提醒用户注意数据类型兼容性、迁移后的数据校验,以及权限问题。可能用户对性能优化也比较关注,比如如何加快迁移速度,使用合适的压缩格式,或者并行处理。 还要检查是否有遗漏的方法,比如使用第三方工具或者云服务商提供的迁移服务。另外,迁移后的测试步骤也很重要,用户可能需要验证数据的完整性和正确性。 现在需要组织这些点,分步骤说明每种方法的具体操作,注意事项,适用场景。确保语言简洁,用中文,避免使用专业术语过多,或者适当解释术语。比如解释什么是clickhouse-backup,或者分布式表的概念。 可能用户是开发人员或者运维人员,需要技术细节,但如果是新手,可能需要更详细的步骤。但问题中没有说明用户的技术背景,所以保持适中,既给出命令示例,也解释每个步骤的作用。 最后,总结不同方法的优缺点,帮助用户根据实际情况选择合适的方式。例如,小数据量用INSERT SELECT,大数据量用备份工具,跨集群用分布式表等。</think>### ClickHouse数据迁移指南 --- #### 一、迁移场景分类 1. **同集群迁移** - 表结构不变,仅调整存储策略(如从本地盘迁移到云存储) - 数据分片重新分布 2. **跨集群迁移** - 不同版本间迁移(需注意兼容性) - 跨地域/云厂商迁移 3. **异构迁移** - 从其他数据库(如MySQL、PostgreSQL)导入数据 --- #### 二、常用迁移方法 **1. INSERT SELECT(小数据量)** ```sql -- 目标集群执行 INSERT INTO target_table SELECT * FROM remote('source_host', source_database, source_table) ``` **特点** - 适合数据量小(GB级) - 自动类型转换 - 需开放跨集群网络访问 --- **2. 导出/导入CSV** ```bash # 导出 clickhouse-client --query "SELECT * FROM table" > data.csv # 导入 clickhouse-client --query "INSERT INTO table FORMAT CSV" < data.csv ``` **优化技巧** - 使用`FORMAT CSVWithNames`保留列名 - 并行处理:按分区导出导入 - 压缩传输:`gzip`/`zstd` --- **3. 使用备份工具(推荐大数据量)** **clickhouse-backup 工具流程**: ```bash # 1. 创建备份 clickhouse-backup create my_backup # 2. 传输备份文件到目标集群 rsync -av /var/lib/clickhouse/backup/my_backup/ target_host:/var/lib/clickhouse/backup/ # 3. 恢复备份 clickhouse-backup restore my_backup ``` **优势** - 支持增量备份 - 保留表结构、索引、物化视图 - 停机时间短 --- **4. 文件级迁移(极大数据量)** ```bash # 1. 停止ClickHouse服务 sudo service clickhouse-server stop # 2. 复制数据目录 cp -r /var/lib/clickhouse/data/database/table /new/storage/path # 3. 修改存储策略 ALTER TABLE table MODIFY SETTING storage_policy = 'new_policy' ``` **注意** - 需停机操作 - 文件权限需保持一致 - 推荐使用硬链接减少IO --- #### 三、跨集群迁移方案 **1. 分布式表同步** ```sql CREATE TABLE distributed_target AS remote_cluster_table ENGINE = Distributed(cluster, database, table) ``` **特点** - 实时同步写入 - 需配置`remote_servers` **2. 副本表迁移** ```xml <!-- 配置zookeeper同步 --> <yandex> <zookeeper-servers> <node index="1"> <host>zk_cluster</host> <port>2181</port> </node> </zookeeper-servers> </yandex> ``` --- #### 四、迁移注意事项 1. **版本兼容性** - 跨大版本迁移需测试数据类型变化(如DateTime时区处理) - 推荐使用同版本迁移 2. **数据校验** ```sql -- 校验行数 SELECT count() FROM table -- 校验哈希 SELECT sum(cityHash64(*)) FROM table ``` 3. **性能优化** - 调整`max_memory_usage`(处理大查询) - 设置`parallel_view_processing=1` - 使用`Buffer`表减少写入压力 4. **权限迁移** ```sql SHOW CREATE USER user1 SHOW GRANTS FOR user1 ``` --- #### 五、典型问题解决方案 **问题1:迁移后数据不一致** - 检查字符集(特别是中文字符) - 验证Nullable字段处理 **问题2:迁移速度慢** - 增加`max_insert_threads` - 禁用索引:`ALTER TABLE ... DROP INDEX` - 使用`MergeTree`系列引擎的轻量级写入优势 **问题3:Zookeeper依赖问题** - 使用`ReplicatedMergeTree`时需迁移zk元数据 - 或改用非复制表临时迁移 --- #### 六、迁移后检查清单 1. 验证表引擎配置 2. 检查物化视图/投影是否重建 3. 测试查询性能 4. 监控系统表: ```sql SELECT * FROM system.parts WHERE table = 'target_table' ``` 通过以上步骤,可完成安全可靠的数据迁移。建议先在测试环境验证完整流程,实际迁移时根据数据量选择合适方案。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值