InfluxDB 源码分析(五): 数据存储(tsdb模块)
tsdb模块是influxdb最核心的模块,包揽了influxdb最核心存储的实现,在了解tsdb模块之前,我们需要先了解tsdb模块下的一些概念。主要有: store
, shard
, tag
, series
, point
等。
tsdb 基本概念
store
store
是influxdb
的存储模块,全局只有一个该实例。主要负责将数据按一定格式写入磁盘,并且维护influxdb
相关的 存储概念。例如:创建/删除Shard
、创建/删除retention policy
、调度shard
的compaction、以及最重要的WriteToShard
等等。在store
内部又包含index
和engine
2个抽象概念,index
是对应shard
的索引,engine
是对应shard
的存储实现, 不同的engine
采用不同的存储格式和策略。后面要讲的tsdb
其实就是一个engine
的实现。在influxdb
启动时,会创建 一个store
实例,然后Open
它,初始化时,它会加载已经存在的Shard
,并启动一个Shard
监控任务, 监控任务负责调度每个Shard
的Compaction
和对使用inmem
索引的Shard
计算每种Tag
拥有的数值的基数(与配置中max-values-per-tag
有关)。
shard
shard
是一组存储单元,用于存放一段时间范围内的数据,shard
和 rp
强关联,这种强关联指的是 shard
属于某个rp
下。每个shard
底层对应一个TSM
存储引擎。当过期策略检查到某一个shard
过期后,会释放其对应的资源。
series
series
保存的是一组数据的集合。在同一个database中,retention policy、measurement、tag sets 完全 相同的数据同属于一个series,同一个series的数据在物理上会按照时间顺序排列存储在一起。
series的key为measurement加所有tags的序列化字符串
tag 和 field
tag
和 field
最本质的区别是,tag可以建立索引,优化查询,而filed不行,根据filed查询需要遍历某个时间范围内的所有数据。tag和field在向数据库中插入数据的时候会有区别,tag在前,并以英文逗号分隔,field在后,以空格分隔。influxdb根据分隔符的不同,来判断是filed或者是tag。
point
由timestamp
、measurements、
retention policy、
tag和
field等 组成的一组数据为一个point。
ponit的key 由
measurement 和 tag 的hash。数据写入时,通过point的key进行fnv64算法计算之后可以得到HashId, 根据hashID 来选择要写入的shar
细心的人可能会发现,这里是没有shardGroup
的,正如我们在 mete 解析中提到的,shardGroup 只是influxdb的meta维护的一个逻辑的概念,它的作用仅仅是把某个时间范围内的一些shard聚合在一起,所以这部分基本概念没有纳入进去。
转载自:https://juejin.cn/post/7352763226529366079