上一篇Clickhouse介绍大概描述了clickhouse的特性,这里讲讲实际底层的存储结构

MergeTree存储结构

查看clickhouse磁盘上的表数据结构,基本上就是下方的目录结构。表名目录下有很多分区,除非表没有设置分区,完全就只在all分区上。

└─clickhouse
    └─table
        └─partition_1
            └─checksum.txt(当前目录各个文件的大小以及各文件内容的hash)
            └─columns.txt(设计所有列和列的类型)
            └─count.txt(此part数据行数)
            └─primary.idx (主键稀疏索引,找到bin里面对应的block)
            └─[Column].bin (对应列的实际数据内容)
            └─[Column].mrk (对应列的标记文件,辅助索引进一步找到block内的granularity)
用了分区键   └─partition.dat (用了分区间)
用了分区键   └─minmax_[Column].idx
用二级索引   └─skp_idx_[Column].idx
用二级索引   └─skp_idx_[Column].mrk

一次数据写入请求

  • 数据根据index_granularity(默认8192)切成多个颗粒(granularity)
  • 多个granularity在内存中积攒一定大小,按照其压缩前的数据字节大小,都被严格的控制在64K~1M之间,其上下限分别由min_compress_block_size(默认65536)与max_compress_block_size(默认1048576)参数指定。满足条件后触发压缩和落盘,形成一个block(clickhouse与磁盘交互扫描的最小单位)
    • 头文件(压缩方法,压缩前后大小)
    • 压缩数据
  • 多个block落地成一个bin文件(数据内容),和其他相关文件一起落到同一个part。即新增了一个目录,所以官方才会建议insert频率降低或者一次insert的batch size要足够大,否则会影响IO和目录数过大耗尽inode,影响数据合并性能

参考