seriesfile 持久化 存储了当前DB下所有的Series(measurement + tag key) 信息。
series 存储结构
与 series file 相关的源码部分位于tsdb目录下面,主要涉及四部分的源码:
series_file.go
series_partion.go
series_segment.go
serise_index.go
1 每个DB下面的series文件最多分成8个partion, 每个partion可以分为多个segment
2 series_index 为 partion 下面所有segment file 的内存索引
series_segment
可以看到segment的存储结构:
1 每个series_segment下面包含多个series_entry;
2 每个serise_entry 包含flag、id、SeriesKey总写入长度、measurement长度、measurement、 tag数量、 具体的tag信息等数据;
series_index
SeriesIndex是对某个Partition下所有Segment file的内存索引,分析series_index.go 中包含的索引结构:
// SeriesIndex represents an index of key-to-id & id-to-offset mappings.
type SeriesIndex struct {
// 相当于一个大数组,对key进行hash后存储对应的(entry_id + offset)
// key 为 segment_entry 的数据部分:(写入长度 + 具体数据内容)
// 存储位置具体计算方式:pos = hash&idx.mask,
// pos 为该元素在数组的位置
// 真实的存储位置:keyIDData[(pos * SeriesIndexElemSize):]
// offset = segment id + (segment_entry 在 segment 中的 pos)
keyIDData []byte // key/id mmap data
// 与 keyIDData 类似,
// 相当于一个大数组,对 segment_entry_id 进行hash后, 作为pos
// 存储( entry_id + offset)
idOffsetData []byte // id/offset mmap data
...
// In-memory data since rebuild.
// key 为 series_entry中除去flag、id以外剩余的部分
// value 为 segment_entry 的id
keyIDMap *rhh.HashMap
// key 为 segment_entry的 id
// value 为 (segment id) +(segment_entry 在 segment 中的 pos )
idOffsetMap map[uint64]int64
...
}
SeriseIndex 数据一部分保存在Map中( keyIDMap, idOffsetMap), 另一部分数据保存在 []byte 结构中,方便写入磁盘文件以及从磁盘文件恢复(可以采用mmap 的方式从文件映射到内存中的一个[]byte结构体中);
SeriesPartion
SeriesPartion 里面一个重要的方法:
该方法把新的segment entry相关的索引信息(id, offset) 压缩到[]byte结构体中, 然后就可以写入磁盘文件中保存;
同时也可以采用mmap的方式将已有的索引信息从磁盘文件映射到index结构体中keyIDData,idOffsetData字段中;
func (c *SeriesPartitionCompactor) Compact(p *SeriesPartition) error {
...
}
SeriesFile
seriesfile 负责管理所有的series 文件,对外提供操作series的公共接口,屏蔽了内部的segment, segment等结构。
参考:series 源码解析