二级索引生成文件
数据分区
![]
数据是以分区目录的形式进行组织的,每个分区的数据独立分开存储;横向切分是分片;纵向切分是分区。
数据分区合并
t0时刻,有三批数据写入。
第一批数据是 2021-05-01,因分区键是年-月,则会得到分区目录202105_1_1_0
202105表示年月的分区id,第一个1表示最小的blockNum,第二个1表示最大的blockNum,第一批数据,maxBlockNum=minBlockNum=blockNum=1,最后一个0表示合并的次数,此时还未发生合并所以是level=0
第二批数据是2021-05-02,则会得到202105_2_2_0,因blockNum=2=minBlockNum=maxBlockNum,还未合并所以level是0
第三批数据是2021-06-02,则会得到202105_3_3_0,因blockNum=3=minBlockNum=maxBlockNum,还未合并所以level是0
t1时刻,202105的分区发生合并
202105_1_1_0和202105_2_2_0合并得到202105_1_2_1
分区id不变还是202105
最小blockNum合并结果为1,因为一个是1一个是2,取最小值即为1
最大blockNum合并结果为2,因为一个是1一个是2,取最大值即为2
level结果是1,因为一个是0,另外一个也是0,取两者的最大值再加1即为1
所以合并之后的分区目录为202105_1_2_1
合并之后,老的分区目录则会处于非激活状态,不对外提供服务,默认8分钟之后,异步被清理。
一级索引
- • primary.idx文件内的一级索引(主键索引)采用稀疏索引实现
- • 稀疏索引占用的索引存储空间较小。数据量大的场景可以利用primary.idx内的索引数据常驻内存,加快查询速度
- • 默认索引粒度大小为8192
- • 每隔一个索引粒度会取该粒度范围内的第一个主键值作为索引保存到primay.idx文件中
二级索引(跳数索引)
二级索引由数据块按粒度分割后,各部分数据聚合信息构成
索引a表示:粒度范围内price*size即总价的最小值和最大值
- • minmax 存储指定表达式的极值
- • set(max_rows) 存储指定表达式的不重复值,max_rows表示重复值的个数限制,比如max_rows=10表示只有10个不同的值可重复;0表示无限制
- • ngrambf_v1 存储一个包含数据块中所有ngram的布隆过滤器,用于字符串的equals、like、in过滤。ngram是统计语言模型的算法,用于分词
- • tokenbf_v1 跟ngrambf_v1类似,但是它不是用ngrams进行分词,而是使用token,token是非字母数字的符号分割的序列比如分号;
- • bloom_filter 指定列存储的布隆过滤器
数据压缩-- 压缩数据块
- • bin压缩文件是由多个压缩数据块组成的,而每个压缩数据块的头信息则会基于CompressionMethod_CompressedSize_uncompressedSize公式生成
- • 压缩方法包含:LZ4、ZSTD、Multiple、Delta多种算法
数据压缩-- 压缩方式
- • 单个间隔数据不超过64KB,则累积到64KB生成下一个压缩块
- • 单个间隔数据大于64KB,不超过1MB,则直接生成下一个压缩块
- • 单个间隔数据大于1MB,则直接生成多个压缩快
数据标记
.mrk标记文件为一级索引和数据文件之间建立关联,主要保存两个信息
- • 一级索引对应的编号信息
- • bin压缩数据块的起始偏移量和解压缩块的起始偏移量
每个索引粒度内取第一条重新写入。每个索引值都会有一个下标。第一个索引粒度内,使用第一条数据保存到索引池,下标编号为0,对应start0~start1区间。索引文件中保存了编号信息,通过编号信息找到压缩数据的起始偏移量和解压缩数据的起始偏移量
MergeTree写入的过程
每一批数据写入到数据目录里去,有三种不同的压缩方式,随着压缩文件的生成也伴随着一级索引和标记文件的构建,最终使得压缩文件、标记、索引一一对应。
MergeTree的读取过程
通过查询语句的filter过滤条件,根据分区索引找到唯一满足的分区目录,进入到分区目录,会根据一级索引来进行过滤,排除掉不符合的一些索引信息,保留索引2和索引3,然后根据二级索引排除掉索引2,那么就只剩索引3这个一级索引,数据标记能够为一级索引和数据文件进行关联,找到对应的压缩块,然后解压缩,然后根据标记中的起始偏移量找到对应的数据,这就是MergeTree的读取过程。
如果没有过滤条件则会通过多线程的操作对这些分区目录并行的进行读取,加速查询过程。