Search CTRL + K

ClickHouse MergeTree 结构

MergeTree 是 ClickHouse 中非常重要的存储引擎。它本身由许多概念组成,逐层分解如下图所示:

Table

ClickHouse 作为 关系模型 OLAP 数据库,本身有 的概念。 在 ClickHouse 的磁盘上就是一个文件夹,但 归属于一个 database(也是一个文件夹),也就是在一个 database 文件夹下。

比如 /var/lib/clickhouse/data/system/metric_log 就是在 system 这个 database 下的 metric_log 这张表。

Partition

在 ClickHouse 中,Partition 是逻辑上的分区概念,并不存在物理表示。

数据插入时会根据 DDL 中的 PARTITION BY(分区表达式)将数据强制切分,然后再拆分为不同的 Part

Part

在 ClickHouse 中,一个 Part 就是 ClickHouse 磁盘上的一个文件夹,在表文件夹下。比如 /var/lib/clickhouse/data/system/metric_log/202303_1_491_98 就是 system.metric_log 这张表的一个 Part。

Part 内的数据是有序的(按照 DDLORDER BY 排序),每个 Part 实际存储数据、索引。ClickHouse 后台会不断合并不同的 Part。Part 的命名规则为 {PARTITION 名}_{最小的 Block 序号}_{最大的 Block 序号}_{层级}[1]

Part 存储格式有三种:

WIDE Part 内会包含如下文件:

Column

每个 Column 在不同 Part 中都会有一个 .bin 文件存储压缩数据和一个 .mrk2 数据偏移索引。

Block

Block 有两层含义:

Block 是 ClickHouse 进行 I/O 的基本单位。读取时每次都要读取整个 Block 并解压缩,获取需要的 Granule;写入时也需要内存中的 Block 达到 min_compress_block_size(最大值为 max_compress_block_size)后压缩落盘。

Granule

Granule 是固定大小的一组行,一个 Granule 会在主键索引中存在一条 记录

Granule 是 ClickHouse 中数据的最小单位,也是 I/O 的最小单位。.mrk2 文件记录了一个 .bin 中所有 Granule 的偏移量(两列,一列 Block 偏移量,和这个 Block 内每个 Granule 的偏移量),方便数据读取。


  1. https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/custom-partitioning-key/ ↩︎

  2. https://clickhouse.com/docs/en/guides/improving-query-performance/sparse-primary-indexes/sparse-primary-indexes-design/#mark-files-are-used-for-locating-granules ↩︎