阿里云InfluxDB®基于TSI索引的数据查询流程

  • 时间:
  • 浏览:6

(4)measurement sketch和tombstone measurement sketch是使用HyperLogLog++算法来作基数统计用。

(c)是意味着是查询类事count你你这些 聚合操作,那是意味着从cur中一共也就返回1条结果数据,聚合工作放满了相关iterator的reducer操作中;





4、认证

在InfluxDB内部管理,由5种Iterator,它们分别是buildFieldIterator、buildAuxIterator、buildExprIterator、buildCallIterator和buildVarRefIterator。它们根据不同的查询产生不同的创建过程,彼此组成互相调用的关系,并组成了最终的cursor。

在Select函数构建cursor的过程中,调用不断向下,亲戚亲戚朋友最终会来到Engine.CreateIterator函数的调用。Engine与四个多shard对应,是意味着查询跨多个shard,在外层会遍历所有涉及本次查询的shards(LocalShardMapping),对每个shard对应的Engine执行CreateIterator,负责查询落在本shard的数据。根据查询究竟是查数据,还是聚合函数,Engine.CreateIterator里会调用createVarRefIterator是意味着createCallIterator。

InfluxDB内部管理注册了你你这些 服务,其中httpd service是负责补救内部管理请求的服务,通常情況下,读写请求都不 到达services/httpd/handler.go这里。对于select搞笑的话来说,调用的是serveQuery。

亲戚亲戚朋友先来看一下TSM的设计。四个多TSM被设计为四个多区域:Header、Blocks、Index和Footer。

从它的定义亲戚亲戚朋友很容易得出:

1、IndexFileTrailerSize在TSI文件结尾处占固定的82bytes,亲戚亲戚朋友在解析TSI时很容易读取到你你这些 Trailer.

2、通过它的定义亲戚亲戚朋友基本知道了四个多TSI中含哪几种次责:





footer区域存储索引区的文件偏移。

在executeSelectStatement函数内部管理,有几个关键操作:

查看_series文件夹目录形态学 ,也是和tsi类事,分为8个partition。最新版本的influxdb通过_series文件夹的series文件检索series id到series key的映射。

在Index区域,存放的是Blocks区域的索引。Index区由一系列的index entries组成,它们先按key后按时间戳、以字典顺序排序。一根绳子 绳子 index entry内部管理组成包括:key长度、key、数据类型、当前blocks数量、本block的最大最小时间、block文件偏移、block长度。

3、生成AST树

对于从表单提取的查询搞笑的话,InfluxDB村里人 及的一套Influxql解析框架,可生成类事传统关系型数据库内的AST树。是意味着Influxql次责代码庞大,与查询逻辑核心关系不大,本文不做展开。

2、参数解析

Influxdb都要对query提交的表单解析若干关键配置参数,能够挑选访问的数据库、存储策略、输出格式等删改信息:

最后亲戚亲戚朋友来总结一下,TSI文件格式的设计,是一种多级索引的妙招,每一层级都设计了Trailer,方便快速找到不同区域的偏移;每个分区内又村里人 及的Trailer,measurement block、Tag block、Tag block下的key data都设计了hash索引加快查询文件偏移。

对于一次查询,亲戚亲戚朋友根据measurement在measurement block中找到对应MeasurementBlockElement下的tag set,根据查询条件中tag key进行过滤,再在对应的tag block中找到关联的删改tag value block。在tag value block中取得series id set,根据series id到_serise文件夹找到本次查询涉及到的删改SeriesKey。

这里亲戚亲戚朋友仔细分析1.7只是的代码,发现四个多很有趣的大大问题,series id set你你这些 区域在查询期间那末 起到由series id去查series key的作用。实际上在1.7的influxdb,四个多特殊文件夹_series,在你你这些 文件夹中才存放了series id到series key的映射。

(3)hash index次责以hash索引妙招存储了MeasurementBlockElement在文件中的offset,可在不读取整体tsi的情況下快速定位某个MeasurementBlockElement文件偏移。

首先亲戚亲戚朋友看完tsdb/index/tsi1/index_file.go四个多很有意思的常量IndexFileTrailerSize。

亲戚亲戚朋友来看一下TSI文件的内部管理形态学 ,以便了解当执行查询时,InfluxDB是如可使用它来找到对应measurement、tag key、tag value以及相关数据文件TSM的。





它们最终都不 调用createTagSetIterators函数,调用只是,会查询出所有的series作为调用参数(这里访问了索引TSI)。接下来,任务管理器会以series和cpu核数的较小值为除数平分所有的series,否则调用createTagSetGroupIterators函数继续补救,其内部管理会对分配到的series进行遍历,否则对每四个多seriesKey调用createVarRefSeriesIterator函数。在createVarRefSeriesIterator函数中,是意味着ref有值,则直接调用buildCursor函数。是意味着ref为nil,则opt.Aux参数中含了要查询的fields,你你这些 对其进行遍历,对每个feild,再调用buildCursor函数。

根据TSI文件倒排索引查询得到所有的SeriesKey只是,要根据groupby条件对SeriesKey进行分组,分组算法为hash。分组后不同group的SeriesKey允许并行独立执行查询并最终执行聚合的,借此大幅提升整个查询的性能。

4、将满足条件的Data Blocks加载到内存中,用对应数据类型的解压算法解压数据,进一步使用二分查找算法查找即可找到。

亲戚亲戚朋友再来看measurement block,其定义是在tsdb/index/tsi1/measurement_block.go,亲戚亲戚朋友也很容易发现measurement block也是由存储类事meta信息的Trailer以及你你这些 各次责组成。

Prepare过程先执行了Compile,Compile主要进行以下操作:

1、预补救,主你你这些 解析、校验和记录当前查询情況的全局属性,类事解析查询的时间范围、校验查询条件合法性、校验聚合条件的合法性等等。

2、fields预补救,类事查询带time字段的会自动替换为timstamp。

3、重写distinct查询条件。

4、重写正则表达式查询条件。

Compile只是的Prepare主要进行以下操作:





以下是Emitter读取数据时是意味着遇到的几种情況:





1、首先根据TSI查询获得的所有SeriesKey找到所有对应的Index中的Index Entry,是意味着Key是有序的,否则还能够使用二分查找来具体实现。

准备工作完成后,最终会执行coordinator/statement_executor.go的executeSelectStatement函数,你你这些 函数是补救查询搞笑的话的。从services/httpd/handler.go的serveQuery到coordinator/statement_executor.go的executeSelectStatement,经过了多层的函数调用。为了方便读者阅读代码,下图展示了调用的堆栈(如若遇到go interface次责的函数调用,下图已替换为真正实现interface的形态学 体的函数)。

InfluxDB的查询流程是四个多较为复杂化的过程,源码实现的逻辑精妙、模块划分清晰,很适合时序数据库领域的开发者深入学习其中思想。是意味着篇幅有限,本文涉及到的次责不必删改,你你这些 细节都要读者在阅读过程中参照社区开源代码对比研究,是意味着笔者学识有限也是意味着有描述失误的地方,欢迎亲戚亲戚朋友斧正。

阿里云InfluxDB®现已正式商业化,欢迎访问购买页面(https://common-buy.aliyun.com/?commodityCode=hitsdb_influxdb_pre#/buy)与文档(https://help.aliyun.com/document_detail/1110093.html?spm=a2c4e.11153940.0.0.57b04a02biWzGa)。





时间序列数据库是目前技术发展最快的数据库类型之一。作为业界最为流行的时序数据库InfluxDB,其部署运行十分简洁方便,支持高性能时序数据的读写,在应用任务管理器监控、物联网(IoT)领域有着广泛的应用。

阿里云InfluxDB®是基于开源版InfluxDB优化的版本,内部管理的数据组织保持与开源版本一致,还能够简单概括为索引与数据两次责。用户使用Influxql搞笑的话进行数据查询,InfluxDB会解析这条搞笑的话并生成AST语法树,通过语法树的遍历,找到都要查询的measurement、tag kv等关键元数据信息,通过InfluxDB的索引找到对应的时序数据所在的文件(TSM),获得数据点,返回给用户。而索引的实现有一种,一种是基于内存的倒排索引(inmem),使用上受限于内存,是意味着突然出现宕机的情況,都要扫描解析所有TSM文件并在内存中重新构建,恢复时间很长;另一种则是基于文件的倒排索引(TSI),内存占用较小,还能够支持百万甚至千万级别的时间线,宕机恢复影响也很小。

(3)value data的设计与key data次责类事。在tag value block的内部管理,有亲戚亲戚朋友最关注的series id set。

当查询开始英语 后,同步情況下从管道依次取出结果。并补救chunked协议等返回协议,最终返回给用户。

亲戚亲戚朋友先看一张基于TSI的InfluxDB索引组织图(如下所示)。其中db(数据库)、rp(存储策略)、shard、Index在文件组织下都不 以目录形式表现,TSI使用了分区策略,你你这些 在Index文件夹下是0~7共计8个partition文件夹,partition文件夹则是TSI文件与它的WAL(TSL):

计数统计方面,查询计数器h.stats.QueryRequests自增1。其次定义四个多defer,用于在开始英语 时统计当前查询的耗时。

出于安全考虑,用户是意味着开启了InfluxDB的认证配置。不还能够对应权限的用户以及匹配正确密码只是,能够访问相关的数据库。

其中Header是4位的magic number(用于定义文件类型)以及四个多1位的版本号。





(4)hash index次责,还能够通过tag key快速定位到tag key block的offsset。

3、通过Index Entries定位到是意味着的Data Blocks列表。

(1)Trailer次责是整个MeasuermentBlock的索引,存储着你你这些 次责的offset和size。

亲戚亲戚朋友提到执行select的主函数executeSelectStatement四个多关键操作是创建迭代器(是意味着说是游标)cursor,你你这些 思想与传统关系型数据库执行计划树的执行过程有类事之处。cursor的创建依赖于查询准备工作中由InfluxQL解析生成的AST树(SelectStatement)。创建过程也类事于传统关系型数据库,分为Prepare、Select两部,其中Prepare过程还还能够细分为Compile与Compile只是的Prepare;Select则是基于Prepare后的SelectStatement来构建迭代器。

2、找到所有Index Entry只是,再根据查找的时间范围,使用[MinTime, MaxTime]过滤剩余都要的Index Entries。

查询的准备工作,包括计数器的更新、参数解析、解析生成AST树、认证四个多方面。

1、计数统计

(d)是意味着是意味着decode的数据被读取完,还都要继续读取,则会迫使cur再次做底层TSM文件的decode。直到完成都要的数据读取。

buildCursor函数中,先根据measurement查询到对应的fields,再根据field name从fields中查询到对应的Field形态学 (中含feild的ID、类型等)。否则,根据field是哪几种类型进行区别,比如是float类型,则调用buildFloatCursor函数。各类型的buildCursor底层调用的实际是TSM文件访问的函数,新建cursor对象时(newKeyCursor)使用fs.locations函数返回所有匹配的TSM文件及其中的block(KeyCursor.seeks),读取数据时则是根据数据类型调用peekTSM()、nextTSM()等TSM访问函数。

(a)是意味着是多个series,则一般是第四个多series拿四个多数据,否则第四个多拿四个多数据......拿只是,第四个多series再拿第四个多数据,以此类推;

亲戚亲戚朋友再来看Tag block,其定义是在tsdb/index/tsi1/tag_block.go中,同样有类事的trailer定义:

(2)创建基于迭代器的Emitter,通过Emitter函数中循环调用cursor的Scan()函数从cursor中一根绳子 绳子 一根绳子 绳子 数据地进行读取。

本文将基于文件倒排索引(TSI)的索引类型,深入介绍用户一次数据查询,在InfluxDB内部管理的流程细节。

在Blocks区域,是一系列独立的数据Block组成,每个Block中含四个多CRC32算法生成的checksum保证block的删改性。data内部管理,时间戳与数据分开存储,按不同的压缩算法进行压缩。拆解图如下:





(2)data offset/size次责,是所有的MeasurementBlockElement的集合。MeasurementBlockElement内中含了measurement的名字、对应tag的集合以及在文件中的offset和size、当前measurement下所有的series id信息。

TSI采用了类LSM机制,操作都不 以append-only妙招以LogEntry格式写入到WAL(TSL文件,其对应的level为0),修改和删除操作也是那末 ,在后台compaction(Level0 ~ Level 1)的过程中会进行真正的数据删除。当TSL文件执行compaction操作时,实际上是将WAL以TSI格式转化写入四个多新的TSI文件中。TSI文件(Level1-Level6)会定期由低层向高层作compact, compact的过程本质是将相同measurement的tagbock作在一同,相同measurement的相同tagkey对应的所有tagvalue放满一同, 相同measurement的相同tagkey又相同tagvalue的不同series id 作合并后放满一同。

原series id set区域用于存储整个数据库中所有的SeriesKey,这是意味着是历史遗留的大大问题。1.7.7版本的influxdb,四个多特殊文件夹_series,在你你这些 文件夹中才存放了series id到series key的映射。

(1)创建迭代器createIterators,创建过程中内部管理通过TSI访问TSM并decode次责数据内容(“细节探究:迭代器与TSI、TSM”小节深入分析);

(1)Trailer共要tag block的meta信息,保存其它各组成次责的offset和大小。

(2)key data次责是tag key数据块次责,其内部管理有二级hash index,还能够通过tag key快速定位到指定tag key block次责,Data offset,Data size次责指向了当前tag key对应的所有的tag value block文件区域。





(b)当返回数据达到了查询设置的chunkSize(查询参数中那末 ,则使用默认的1000)时,提前先返回,以此来做到分批返回结果;

TSM文件的索引层,在InfluxDB启动只是就会删改加载到内存之中,数据次责则因消耗内存过大不加载。数据检索一般安装以下几个步骤执行: