摘要:为大家带来当下时序数据模型的支流TSDB剖析及云厂商在时序数据模型方面的最新动静。
本文分享自华为云社区《【万字干货】OpenMetric与时序数据库存储模型剖析(下)》,作者:麻利的小智 。
在上篇《【万字干货】OpenMetric与时序数据库存储模型剖析(上)》文章中,咱们理解了时序数据模型的相干常识内容,接下来为大家剖析当下支流TSDB及云厂商在书序数据模型方面的最新动静。
支流TSDB剖析
InfluxDB
InfluxDB[9]是一个一站式的时序工具箱,包含了时序平台所需的所有:多租户时序数据库、UI和仪表板工具、后盾解决和监控数据采集器。如下图9所示。
图9
InfluxDB反对动静shcema,也就是在写入数据之前,不须要做schema定义。因而,用户能够随便增加measurement、tag和field,能够是任意数量的列。
InfluxDB底层的存储引擎经验了从LevelDB到BlotDB,再到自研TSM的历程。从v1.3起,采纳的是基于自研的WAL + TSMFile + TSIFile计划,即所谓的TSM(Time-Structured Merge Tree)引擎。其思维相似LSM,针对时序数据的个性做了一些非凡优化。TSM的设计指标一是解决LevelDB的文件句柄过多问题,二是解决BoltDB的写入性能问题。
Cache: TSM的Cache与LSM的MemoryTable相似,其外部的数据为WAL中未长久化到TSM File的数据。若过程故障failover,则缓存中的数据会依据WAL中的数据进行重建。
WAL (Write Ahead Log) : 时序数据写入内存之后依照SeriesKey进行组织。数据会先写入WAL,再写入memory-index和cache,最初刷盘,以保障数据完整性和可用性。根本流程包含:依据Measurement和TagKV拼接出乎series key;查看该series key是否存在;如果存在,就间接将时序数据写入WAL、时序数据写缓存;如果不存在,就会在Index WAL中写入一组entry;根据series key所蕴含的因素在内存中构建倒排索引、接着把时序数据写入WAL和缓存。
TSM Files: TSM File与LSM的SSTable相似。在文件系统层面,每一个TSMFile对应了一个 Shard,单个最大2GB。一个TSM File中,有寄存时序数据(i.e Timestamp + Field value)的数据区,有寄存Serieskey和Field Name信息的索引区。基于 Serieskey + Fieldkey构建的形似B+tree的文件内索引,通过它就能疾速定位到时序数据所在的数据块。在TSMFile中,索引块是依照 Serieskey + Fieldkey 排序 后组织在一起的。
TSI Files:用户如果没有按预期依据Series key来指定查问条件,比方指定了更加简单的查问条件,技术手段上通常是采纳倒排索引来确保它的查问性能的。因为用户的工夫线规模会变得很大,会造成倒排索引耗费过多的内存。对此InfluxDB引入了TSIfiles。TSIFile的整体存储机制与TSMFile类似,也是以 Shard 为单位生成一个TSIFile。
在InfluxDB中有一个对标传统RDB的Database概念。逻辑上每个Database上面能够有多个measurement。在单机版中每个Database理论对应了一个文件系统的目录。
InfluxDB作为时序数据库,必然包含时序数据存储和一个用于度量、标记和字段元数据的倒排索引,以提供更疾速的多维查问。InfluxDB在TSMFile上依照上面的步骤扫描数据,以取得高性能查问成果:
• 依据用户指定的工夫线(Serieskey)和FieldKey在索引区找到Serieskey+FieldKey所在的 索引数据块。
• 依据用户指定的工夫戳范畴在索引数据块中查找数据对应在哪个或哪几个索引条目
• 把检索出的索引条目所对应的时序数据块加载到内存中进一步扫描取得后果
和 Prometheus 一样,InfluxDB 数据模型有键值对作为标签,称为标签。InfluxDB 反对分辨率高达纳秒的工夫戳,以及 float64、int64、bool 和 string 数据类型。相比之下,Prometheus 反对 float64 数据类型,但对字符串和毫秒分辨率工夫戳的反对无限。InfluxDB 应用日志构造合并树的变体来存储带有预写日志,按工夫分片。这比 Prometheus 的每个工夫序列的仅附加文件办法更适宜事件记录。
Prometheus
下图是Prometheus官网架构图[10],包含了一部分生态组件,它们大多是可选项。其中最外围的是Prometheus 服务器,它负责抓取和存储工夫序列数据,并对这些数据利用规定,从而聚合出新的工夫序列或生成警报,并记录存储它们。
图10
TSDB是Prometheus的要害内核引擎。最新的V3引擎[7]相当于面向TSDB场景优化后的LSM(Log Structured Merge Tree,结构化合并树)。LSM树核心思想的外围就是放弃局部读能力,换取写入的最大化能力;其假如前提就是内存足够大。通常LSM-tree实用于索引插入比检索更频繁的利用零碎。V3存储引擎也采纳了Gorilla论文思维。它包含了上面几个TSDB组件:块头(Head Block)、预写日志WAL及检查点、磁盘上Chunk头的内存映射、长久化block及其索引和查问模块。下图11是Prometheus的磁盘目录构造。
图11
在V3引擎中一个chunk内会蕴含很多的工夫线(Time series)。Chunk目录下的样本数据分组为一个或者多个段(segment),每个缺省不超过512MB。index是这个block下的chunk目录中的工夫线依照指标名称和标签进行索引,从而反对依据某个label疾速定位到工夫线以及数据所在的chunk。meta.json是一个简略的对于block数据和状态的一个形容文件。Chunks_head负责对chunk索引,uint64索引值由文件内偏移量(下4个字节)和段序列号(上4个字节)组成。
Prometheus将数据按工夫维度切分为多个block。只有最近的一个block容许接管新数据。最新的block要写入数据,会先写到一个内存构造中,为了保证数据不失落,会先写一份预写日志文件WAL,按段(大小128MB )存储在目录中。它们是未压缩的原始数据,因而文件大小显著大于惯例块文件。Prometheus 将保留三个或者多个WAL文件,以便保留至多两个小时的原始数据。
V3引擎将2个小时作为块(block)的默认块持续时间;也就是块按2h跨度来宰割(这是个经验值)。V3也是采纳了LSM一样的compaction策略来做查问优化,把小的block合并为大的block。对于最新的还在写数据的block,V3引擎则会把所有的索引全副hold在内存,保护一个内存构造,等到该block敞开再长久化到文件。针对内存热数据查问,效率十分高。
Prometheus官网再三强调了它的本地存储并不是为了长久的长期存储;内部解决方案提供缩短的保留工夫和数据持久性。社区有多种集成形式尝试解决这个问题。比方Cassandra、DynamoDB等。
通过指标实现利用的可察看性(observability)是IT监控运维零碎的第一步。指标提供汇总视图,再联合日志提供的无关每个申请或事件的明细信息。这样更容易帮忙问题的发现与诊断。
Prometheus 服务器彼此独立运行,仅依赖其本地存储来实现其外围性能:抓取、规定解决和警报。也就是说,它不是面向分布式集群的;或者说以后它的分布式集群能力是不够弱小的。社区的Cortex、Thanos等开源我的项目就是针对Prometheus的有余而涌现进去的胜利解决方案。
Druid
Druid[11]是有名的实时OLAP剖析引擎。Druid的架构设计比拟简洁(如下图12)。集群中节点分3类:Master节点、Query节点和Data节点。
图12
Druid数据存储在datasource中,相似于传统RDBMS中的表(table)。每个datasource都按工夫(其余属性也能够)分区(partition)。每个工夫范畴称为一个“块(Chunk)”(例如,一天,如果您的数据源按天分区)。在一个Chunk内,数据被分成一个或多个 “段(Segment)”。每个段都是一个文件,通常蕴含多达几百万行数据。如下图13所示。
图13
Segment的目标在于生成紧凑且反对疾速查问的数据文件。这些数据在实时节点MiddleManager上产生,而且可变的且未提交的。在这个阶段,次要包含了列式存储、bitmap索引、各种算法进行压缩等。这些Segment(热数据)会被定期提交和公布;而后被写入到DeepStorage(能够是本地磁盘、AWS的S3,华为云的OBS等)中。Druid与HBase相似也采纳了LSM构造,数据先写入内存再flush到数据文件。Druid编码是部分编码,是文件级别的。这样能够无效减小大数据汇合对内存的微小压力。这些Segment数据一方面被MiddleManager节点删除,一方面被历史节点(Historical)加载。与此同时,这些Segment的条目也被写入元数据(Metadata)存储。Segment的自描述元数据包含了段的架构、其大小及其在深度存储中的地位等内容。这些元数据被协调器(Coordinator)用来进行查问路由的。
Druid 将其索引存储在按工夫分区的Segment文件中。Segment文件大小举荐在 300MB-700MB 范畴内。Segment文件的内部结构,它实质上是列存的:每一列的数据被安排在独自的数据结构中。通过独自存储每一列,Druid 能够通过仅扫描查问理论须要的那些列来缩小查问提早。共有三种根本列类型:工夫戳列、维度列和指标列,如下图14所示:
图14
维度(Dimension)列须要反对过滤和分组操作,所以每个维度都须要以下三种数据结构:
1) 将值(始终被视为字符串)映射到整数 ID 的字典,
2) 列值的列表,应用 1 中的字典编码。 【服务于group by和TopN查问】
3) 对于列中的每个不同值,一个批示哪些行蕴含该值的位图(实质就是倒排索引,inverted index)。【服务于疾速过滤,不便AND和OR运算】
Druid中每列存储包含两局部:Jackson 序列化的 ColumnDescriptor和该列的其余二进制文件。 Druid强烈推荐默认应用LZ4压缩字符串、long、float 和 double 列的值块,应用Roaring压缩字符串列和数字空值的位图。尤其在高基数列场景中匹配大量值的过滤器上Roaring 压缩算法要快得多(比照CONCISE 压缩算法)。
值得一提的是Druid反对Kafka Indexing Service插件(extension),实现实时摄入(ingestion)工作,那么此时能够立刻查问该segment,只管该segment并没有公布(publish)。这更能满足对数据的产生到可查问可聚合剖析的实时性要求。
Druid另外一个重要个性就是在数据写入的时候,能够开启rollup性能,将选定的所有dimensions 依照你指定的最小工夫距离粒度(比方1分钟,或者5分钟等)进行聚合。这样能够极大的缩小须要存储的数据大小,毛病是原始的每条数据就被抛弃了,不能进行明细查问了。
Druid为了让查问更高效,有如下设计思考。
• Broker修剪每个查问拜访哪些Segment:它是 Druid 限度每个查问必须扫描的数据量的重要形式。首先查问先进入Broker,Broker 将辨认哪些段具备可能与该查问无关的数据。而后,Broker 将辨认哪些Historian和 MiddleManager正在为这些段提供服务,并向这些过程中的每一个发送重写的子查问。Historical/MiddleManager 过程将接管查问、解决它们并返回后果。Broker 接管后果并将它们合并在一起以取得最终答案,并将其返回给原始调用者。
• Segment内利用索引过滤:每个Segment内的索引构造容许 Druid 在查看任何数据行之前确定哪些(如果有)行与过滤器集匹配。
• Segment内只读取特定关联的行和列:一旦 Druid 晓得哪些行与特定查问匹配,它只会拜访该查问所需的特定列。在这些列中,Druid能够从一行跳到另一行,防止读取与查问过滤器不匹配的数据。
工夫戳也是Druid数据模型的必备项。只管Druid不是时序数据库,但它也是存储时序数据的自然选择。Druid数据模型能够反对在同一个datasource中,能够同时寄存时序数据和非时序数据。因而,Druid不认为数据点是“工夫序列”的一部分,而是将每个点独自解决以进行摄入和聚合。比方正统的TSDB反对的时序数据插值计算,在Druid中就不复存在的必要了。这会给一些业务场景的解决带来很大的便利性。
IoTDB
Apache IoTDB[12] 始于清华大学软件学院,2020年9月为 Apache 孵化器我的项目。IoTDB 是一个用于治理大量工夫序列数据的数据库,它采纳了列式存储、数据编码、预计算和索引技术,具备类 SQL 的接口,可反对每秒每节点写入数百万数据点,能够秒级取得超过数万亿个数据点的查问后果。次要面向工业界的IoT场景。
IoTDB 套件由若干个组件形成,独特造成数据收集、数据摄入、数据存储、数据查问、数据可视化、数据分析等一系列性能。如下图15所示:
图15
IoTDB 特指其中的工夫序列数据库引擎;其设计以设施、传感器为外围,为了方便管理和应用时序数据,减少了存储组(storage group的概念)。
存储组(Storage Group): IoTDB提出的概念,相似于关系数据库中的Database的概念。一个存储组中的所有实体的数据会存储在同一个文件夹下,不同存储组的实体数据会存储在磁盘的不同文件夹下,从而实现物理隔离。对IoTDB外部实现而言,存储组是一个并发管制和磁盘隔离的单位,多个存储组能够并行读写。对用户而言,不便了对设施数据的分组治理和方便使用。
设施 (Device):对应事实世界中的具体物理设施,比方飞机发动机等。在IoTDB中, device是时序数据一次写入的单位,一次写入申请局限在一个设施中。
传感器(Sensor): 对应事实世界中的具体物理设施本身携带的传感器,例如:风力发电机设施上的风速、转向角、发电量等信息采集的传感器。在IoTDB中,Sensor也称为测点(Measurement)。
测点/物理量(Measurement,也称工况、字段 field):一元或多元物理量,是在理论场景中传感器采集的某时刻的测量数值,在IoTDB外部采纳<time, value>的模式进行列式存储。 IoTDB存储的所有数据及门路,都是以测点为单位进行组织。测量还能够蕴含多个重量(SubMeasurement),比方GPS 是一个多元物理量,蕴含 3 个重量:经度、维度、海拔。多元测点通常被同时采集,共享工夫列。
IoTDB的存储由不同的存储组形成。每个存储组是一个并发管制和资源隔离单位。每个存储组外面包含了多个Time Partition。其中,每个存储组对应一个WAL预写日志文件和TsFile时序数据存储文件。每个Time Partition中的时序数据先写入Memtable,同时记入WAL,定时异步刷盘到TsFile。这就是所谓的tLSM时序解决算法。
摄入性能方面:IoTDB 具备最小的写入提早。批处理大小越大,IoTDB 的写入吞吐量就越高。这表明 IoTDB 最适宜批处理数据写入计划。在高并发计划中,IoTDB 也能够放弃吞吐量的稳定增长(受网卡、网络带宽束缚)。
聚合查问性能方面:在原始数据查问中,随着查问范畴的扩充,IoTDB 的劣势开始浮现。因为数据块的粒度更大,列式存储的劣势体现进去,所以基于列的压缩和列迭代器都将减速查问。在聚合查问中,IoTDB应用文件层的统计信息并缓存统计信息。多个查问只须要执行内存计算,聚合性能劣势显著。
数据存储比照
基于后面的剖析,咱们尝试用上面的表格比照来阐明这些时序数据处理系统的特点。
表3
对于时序数据的解决,要害能力次要包含数据模型定义、存储引擎、与存储严密合作的查问引擎和反对分区扩大的架构设计。支流的TSDB根本都是基于LSM或者联合时序数据场景专门优化的LSM tree来实现(包含InfluxDB号称的TSM,IoTDB的tLSM,实质上都还是LSM机制)。其中只有IoTDB独创采纳了tree schema来对时序数据建模。为了谋求极致性能和极致老本,大家都在针对海量数据和应用场景,继续改良和优化数据的存储结构设计、各种高效索引机制、和查问效率。从单点技术或者关键技术上来讲,有趋同性和同质化的大趋势。
云厂商最新动静
除了开源社区新陈代谢外,国内外泛滥云服务厂商也陆续公布了相干的时序数据库产品或者服务。
华为云
华为云的GaussDB for Influx[13]云服务,基于InfluxDB进行深度优化革新,在架构、性能和数据压缩等方面进行了技术创新,获得了很好的成果。实现了存储与计算拆散架构,其中采纳了华为云自研的高性能分布式存储系统,显著晋升了时序数据库的可靠性;同时不便计算节点分钟级扩容和存储空间的秒级扩容,同时大幅升高存储老本。反对亿级工夫线(开源的能力在千万工夫线级别),写入性能根本保持稳定;可能反对更高的高散列聚合查问性能;在压缩算法上,相比原生的InfluxDB,重点针对Float、String、Timestamp这三种数据类型进行了优化和改良。。
华为云MRS云服务蕴含了IoTDB[14],其中 IoTDB定位为面向工业设施、工业现场的时序数据库库。IoTDB优化后性能更好,千万级数据点秒级写入,TB级数据毫秒级查问;优化后的数据压缩比可达百倍,进一步节俭存储空间和老本;通过采纳对等分布式架构,双层多Raft协定,边云节点同步双活,做到7*24小时高可用。在工业化场景,真正做到一份时序数据兼容全场景、一套时序引擎买通云边端和一套框架集成云边端。
阿里云
据公开材料[15],阿里云时序时空数据库TSDB的倒退演变经验了三个阶段。在v1.0阶段基于OpenTSDB,底层实现了双引擎——HBase和HiStore。在v2.0阶段中,把OpenTSDB引擎换成了自研的TSDB引擎,补救了OpenTSDB不反对的倒排索引、面向时序场景的非凡编码、分布式流计算聚合函数等个性。随后实现了云和边缘计算一体化,TSQL兼容Prometheus生态。其中TSDB for Spatial Temporal反对时空数据,它基于自研的S3时空索引和高性能电子围栏。最新TSDB同样基于 Gorilla, 将单个数据点的均匀应用存储空间降为1~2个字节,能够升高90%存储应用空间,同时放慢数据写入的速度。对于百万数据点的读取,响应工夫小于 5 秒,且最高能够撑持每秒千万数据点的写入。相较于开源的 OpenTSDB 和 InfluxDB,读写效率晋升了数倍,同时兼容 OpenTSDB 数据拜访协定。
腾讯云
腾讯云也推出了TencentDB for CTSDB[16]云服务,它是一款分布式、可扩大、反对近实时数据搜寻与剖析的时序数据库,兼容 Elasticsearch 罕用的 API 接口和生态。它撑持了腾讯外部20多个外围业务。性能方面能够做到每秒千万级数据点写入,亿级数据秒级剖析。CTSDB也是采纳LSM机制,先写内存再周期性刷写到存储;而后通过倒排索引减速任意维度数据查问,能实现数据秒级可查。也反对像histogram、percentile、cardinality这样的通用聚合计算函数;也通过配置 Rollup 工作定时聚合历史数据保留至新的数据表,实现降精度(Downsampling)个性。在集群中节点数量超过30个时,须要新购集群或者将通用集群架构优化降级为混合节点集群架构,以保障多节点超大集群的性能稳固。从这些个性推断,CTSDB内核应该是借鉴了ElasticSearch内核深度优化教训的根底上构建的时序数据库能力。
国内其余厂商
除了云服务厂商提供的开箱即用的云服务外,还有一些创新型产品涌现进去,比拟有名的包含TDengine[17]、字节跳动的TerarkDB[18]、DolphinDB[19]等等。他们也在疾速演进倒退中,值得大家继续跟踪关注,尤其是国内孵化进去的一些TSDB产品。
总结与瞻望
InfluxDB、IoTDB和OpenTSDB等除了社区版本外,也有云厂商提供原生InfluxDB(阿里云TSDB for InfluxDB)、IoTDB(华为云MRS IoTDB)或OpenTSDB(华为云MRS OpenTSDB)云化服务,方便使用。更支流的做法是各云厂商依据本身的技术积淀和研发实力,借鉴、优化甚至从新研发了时序数据库内核,能提供更强的集群能力,更高性能写入,更快的查问和聚合剖析能力。国外厂商AWS有Timestream[20],一种Serverless时序数据库服务,国内华为云的GaussDB for Influx,汇聚顶级数据库专家团队打造的新一代时空剖析数据库;腾讯云的TencentDB for CTSDB,兼容ES生态;阿里云的HiTSDB等等。这些开箱即用的、可扩大的、高可用的时序数据库,为云原生利用的开发与部署带来了福音,无需治理底层基础设施,只需专一于业务构建。
Promeheus倒退过程中,其须要长期保留的历史数据(long-term)存储是其短板之一。业界有一些折中的集成计划。比方采纳Cassandra作为Prometheus的长久化存储;还有采纳InfluxDB作为Prometheus的长久化存储,一方面充分利用Prometheus监控相干能力和社区生态(包含反对分布式集群的Cortex);另一方面利用好InfluxDB时序数据库长处,尤其是超PB级的分布式数据库能力,以补救Prometheus在海量历史数据存储上的短板。
Apache Druid在OLAP即时剖析畛域有着很强的竞争力,也为泛滥大厂所采纳。业界最大的集群领有4000多个节点。不论是时序指标,还是业务数据,利用日志等,都能够利用Druid的Kafka Indexing Service和其弱小的数据预处理能力,转换为时序数据进入Druid。目前Druid SQL个性倒退也很快,包含跨表join,subquery和泛滥函数、算子的继续丰盛。
不论是正统的时序数据库,还是适宜时序数据的OLAP剖析零碎;不论是开源社区的热门我的项目,还是云厂商提供更弱小的云原生时序数据库,都为各种时序数据(包含指标、业务数据)的存储、检索和剖析提供多样化的抉择。用户联合本人的业务场景,肯定能找到绝对适宜的工具或服务,满足业务诉求。
参考资料
[9] https://www.influxdata.com/pr...
[10] https://prometheus.io/docs/in...
[11] https://druid.apache.org/docs...
[12] https://iotdb.apache.org/Syst...
[13] https://bbs.huaweicloud.com/b...
[14] https://bbs.huaweicloud.com/b...
[15] https://developer.aliyun.com/...
[16] https://cloud.tencent.com/dev...
[17] https://www.taosdata.com/cn/
[18] https://github.com/bytedance/...
[19] https://www.dolphindb.cn/
[20] https://aws.amazon.com/cn/tim...
点击关注,第一工夫理解华为云陈腐技术~