天天看点

InfluxDB索引

  InfluxDb分为两种索引,一种是TSM文件内置的Series索引,另一种就是倒排索引,

  Series索引:在InfluxDB的内置索引中Series + field就是主键,定位到某项指标的一个索引块,索引块由N个索引实体组成,每个索引实体提供了最小时间和最大时间,以及这个时间范围对应到TSM文件Series数据块的偏移量,TSM文件有多个Series数据块组成,每个Series数据块就包含了时间列表(Timestamps),索引实体的最小时间和最大时间就对应了这个时间列表。因此Series索引块就可以通过Key排序,并通过时间范围进行二分查找,先快速定位某个时间范围上的时序数据,然后再做扫描匹配。

  倒排索引:InfluxDB除了TSM结构之外,还有TSI结构,TSI主要是进行时序数据的倒排索引,例如:通过动环检测-高新区机房为条件查询高新区机房各个区域的各项指标,或者也可以通过动环检测-数据区域为条件查询所有机房的数据区域的各项指标。

  TSI的数据结构为:Map集合<标签名,Map集合<标签值,List列表>>,第一层就是标签名集合,第二层就是某个标签名下的所有标签集合,例如:标签名为区域,就包含了数据区、计算区等标签值,第三层就是具体某个标签对应的数据源了,例如:包含数据区标签的数据源有动环检测-高新区-数据中心,动环检测-西咸新区-数据中心等数。

  通过这种索引方式就能实现通过标签快速索引包含此标签的所有数据源。通过数据源的Series,再从TSM文件中按其他条件查找。

  TSI数据模型使用了与TSM一样的套路,本质上都是基于LSM数据结构,伴随数据写入,倒排索引先写WAL,在写内存In-Memory Index,当达到内存阀值后Flush倒TSI文件,而TSI文件就是基于磁盘的Disk-Based

Index的倒排索引文件,里面包含了Series块和标签块,可以通过标签块中的标签值在Series块中找到对应的所有Series。

  时序库在这种按数据源标签(Tag)分类的分析查询上会表现得非常高效,这也是InfluxDB充分应对了时序数据业务的需要。

  分布式

  InfluxDB在集群方面闭源了,这的确是件非常可惜的事情。不过可以理解,任何技术创业公司都要谋求生存和发展,商业输血是必须的,希望有一天InfluxDB的母公司能被巨头收购,然后再次完全开源。

  我在以前专门讲过一期HBase和Cassandra的对比,有兴趣的朋友可以看看:HBase 与 Cassandra 架构对比分析的经验分享

  InfluxDB更倾向于去中心化的分布式,里面有我对两者分布式的对比,而InfluxDB更接近于Cassandra,Cassandra是一套去中心化的分布式架构,而InfluxDB包括了Meta节点和Data节点,但是Meta节点看似是主节点,但作用很薄弱,主要存储一些公共信息和连续查询调度,数据读写问题主要还是集中在Data节点,而Data节点之间的读写,更贴近于去中心化的方式。

  InfluxDB是CAP定理中的AP分布式系统,非常侧重于高可用,而不是一致性。其次InfluxDB的主要是两级分片,第一级为ShardGroup,次一级是Shard。

  ShardGroup是个逻辑概念,代表一个时间段内的多个Shard,在创建InfluxDb数据库(DataBase)和保留策略(RETENTION POLICY)后就确定了ShardGroup的连续时间段,这就相当于对时序数据首先进行了按照时间段范围的分区,例如1个小时作为一个ShardGroup。

  但是这1个小时内的数据并不是存储在一个数据节点上,这点就大大不同于HBase的Region了,Region首先会朝一个数据节点使劲地写,写饱了才进行Region拆分,然后实现Region迁移分布。

  而InfluxDB应该是参考了Cassandra那一套办法,使用了基于Series作为Key的Hash分布,将一个ShardGroup的多个Shard分布在集群中不同的数据节点上。

  下面定位shard的代码中key就是Series,也就是唯一指定的数据源(表measurement +标签集合 tagset)。

  shard := shardGroup.shards[fnv.New64a(key) % len(shardGroup.Shards)]

  上面代码中shardGroup.Shards就是ShardGroup的Shard数量,该数量为N/X,N是集群中的数据节点数量,X就是副本因子。

  例如:集群有4个节点,2个副本,4/2就得到了需要将1个小时的ShardGroup范围数据拆成2个Shard,并各复制2份,分布在四个数据节点,就是通过这种Hash分布方式,更均匀的分布了时序数据,也充分利用集群每一个数据节点的读写优势。

  InfluxDB是最终一致性,在写入一致性上实现了各种调节策略Any、One、Quorum、All,和Cassandra如出一辙,并且加强了协调节点的Hinted handoff的临时队列持久化作用,这就是完全为了高可用性。

  即便真正的副本节点故障了,就先在协同节点的Hinted handoff队列中持久化保存,等到副本节点故障恢复后,再从Hinted handoff队列中复制恢复。就是为了达到最终一致性。

  另外InfluxDB和Cassandra3.x及以前版本一样,具有后台碎片修复的反熵功能(anti-Entrory),不过有意思的地方是Cassandra在新的4.0版本已经不在保留后台读修复的功能了,而且之前版本也不推荐启用,因为具有了主动读修复能力,后台读修复作用不大,而且还影响性能。

  当然InfluxDB是不是和Cassandra一样,在读取的过程中进行了主动读修复,因为是闭源系统,这点上我还不太清楚。​​郑州治疗精神分裂症哪里好​​​​http://www.juenpt.com/​​

  InfluxDB在删除问题上会表现的非常薄弱,只允许删除一个范围集合或者Series下的一个维度集合,这也是这种时序结构的设计使然,对单个Point的删除会很麻烦,成本很大。

  删除方法上应该也是参考了Cassandra的Tombstone机制:去中心化的问题就是怕大家都删除副本后,某个正好处于故障中的副本节点又恢复了,它不知道发生了什么事情,但修复过程中它会认为被删除的副本大家弄丢了,而去让大家恢复。

  有了Tombstone标记的长期存在,那么存在副本数据的故障节点,当恢复后根据其他副本节点Tombstone标记,也就知道自己故障期间曾经发生了删除的情况,马上进行自身对应副本数据的删除。

  总结