Clickhouse MergeTree底层存储(二进制文件)分析

        本文从二进制文件的角度出发,重点介绍ck的MergeTree表引擎下的数据是如何在硬盘上存储的,以便于更好地去理解MergeTree表引擎的原理。


        首先创建一个MergeTree的基础表,如下:

         注:将索引粒度置为2,并且按行限制索引粒度。

        导入一些测试数据,如下:


        数据文件在硬盘上的存储如下:


        对上述各文件进行分析: 

  1. checksums.txt

        校验文件,使用二进制格式存储。它保存了其他各文件的size大小及size的hash值,用于快速校验文件的完整性和真确性。

        从中可以看到有各个[column].bin、[coulumn].mrk、minmax_birthday.idx、primary.idx、count.txt、minmax_birthday.idx、partition.dat、skp_idx_age_index.idx等文件的值都会记录在该二进制文件中。 

        2.columns.txt

        表的列信息文件,使用明文格式进行存储。用于保存此数据分区下的列字段信息。

        3.count.txt

         计数文件,使用明文格式进行存储。用于记录当前数据分区目录下数据的总行数。

        4.primary.idx 

        一级索引(主键索引|稀疏索引)文件,使用二进制格式存储。 

        MergeTree基于index_granularity=2,每间隔2行数据取主键的值作为稀疏索引。

        注:建表没有声明primary key时,主键是以order by为准的,上图的结果是正确的。

        5.[column].bin

        表的数据文件,使用压缩格式存储,默认为LZ4 压缩格式,用于存储某一列的数据。由于MergeTree采用列式存储,所以每个字段都有其独立的[column].bin文件,并且以字段名来命名,如id.bin等。

        clickhouse-compressor --decompress命令可以对数据压缩块进行解压缩。

        clickhouse-compressor --stat命令可以查询[column].bin文件中压缩数据的统计信息。 

        其中第一列表示数据压缩前大小,Int32占4个字节,1-4一共4条数据,一共是16字节,第二列是压缩后的数据大小,因为数据量小,压缩本身还有一些必要的信息要压缩,所以压缩后会比压缩前大。 

        [column].bin文件第一行16个字节是该文件的checksum值。

        第二行第一个字节是0x82,是默认的LZ4算法,第2个到第5个字节是压缩后的数据块的大小,这里是小端模式,这4个字节得倒着看,00 00 00 1b,也就是十进制的27,和clickhouse-compressor --stat里统计的信息一致;第6个到第9个字节是压缩前的数据块的大小,倒着看就是00 00 00 10,也就是十进制的16,和clickhouse-compressor --stat里统计的信息一致。

        从第二行第10个字节开始就是LZ4要压缩的内容了。倒着看分别是十进制的1 2 3 4,和插入的数据一致。

        6.[coulumn].mrk

        表的各列字段标记文件,使用二进制格式进行存储。标记文件中保存了[column].bin文件中数据的偏移量信息。标记文件与稀疏索引文件(primary.idx)对齐,又与[column].bin文件一一对应,所以MergeTree通过标记文件建立了primary.idx稀疏索引与[column].bin数据文件的映射关系。即首先通过稀疏索引文件找到对应数据的偏移量信息,然后基于[coulumn].mrk文件的对应关系,去[column].bin文件中读取相应的数据。

        上图为主键索引的标记文件,第一列表示id.bin文件中压缩后数据块的偏移量(字节偏移量),第二列表示id.bin文件解压后数据块的偏移量(字节偏移量)。

        注:一个*.bin数据文件是由1至多个数据压缩块组成的,每个压缩块的大小在64KB到1MB之间。

        这4条测试数据是在同一个压缩块里的,此压缩块里有2个index_granularity,每个index_granularity有2条记录。因为id是Int32类型的,占4个字节,所以解压后数据块的偏移量是0、8。

 三个文件的对应关系如下:

primary.idx

id.mrk

id.bin

1

第0个压缩块,块解压后字节偏移量0,行数:2

1

2

3

第0个压缩块,块解压后字节偏移量8,行数:2

3

4

        7.partition.dat

        分区信息文件,用来保存当前分区下分区表达式最终生成的值,使用二进制格式进行存储。

        建表时指定是按月分区的,partition by toYYYYMM(birthday),所以partition.dat中为199001。 

        8.minmax_birthday.idx

        用来记录当前分区下分区字段对应原始数据的最小和最大值,使用二进制格式进行存储。

        8c和89相差3,与插入数据一致。 

        9.default_compression_codec.txt

        用来记录当前分区下数据压缩方式。

        10.skp_idx_age_index.idx与skp_idx_age_index.mrk

        分别为二级索引(age)的索引文件和标记文件。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zcx_bigdata

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值