上一篇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,影响数据合并性能