InfluxDB是一个由InfluxData开发的开源时序数据库,专一于海量时序数据的高性能读、写、高效存储与实时分析等,在DB-Engines Ranking时序型数据库排行榜上常年排名第一。数据库
InfluxDB能够说是当之无愧的佼佼者,但 InfluxDB CTO Paul 在 2020/12/10 号在博客中发表一篇名为:Announcing InfluxDB IOx – The Future Core of InfluxDB Built with Rust and Arrow的文章,介绍了一个新项目 InfluxDB IOx,InfluxDB 的下一代时序引擎。编程
接下来,我将连载对于InfluxDB IOx的源码解析过程,欢迎各位批评指正,联系方式见文章末尾。服务器
为何会发起IOx项目
原文请参见: https://www.influxdata.com/blog/announcing-influxdb-iox/微信
1. 下一步的目标
原文中介绍到,过去的7年时间的发展中,InfluxDB
在 metrics
数据的处理上已经成为了很是出色的数据库,而且在 analytics
方面也很不错。但对于现有的架构来说有一个限制就是不能处理很是大的基数 (significant cardinality
),也就是说tags
里不能设置太多的值。好比说:不能处理分布式追踪数据 (distributed tracing data
) 的这种场景。网络
另外在开源方面,InfluxDB
仅仅支持单机版本的开源,对于分布式版本只有企业版本或者云上才会提供,这个决定给分布式时序数据库留下了很大一块空白的市场。数据结构
因此在大方向上,InfluxDB
定义了13个要求,你们能够在原文中找到,总结为:架构
- 从设计上减小对于用户的限制:好比
tag
或者field
. - 交给用户更多的控制权:好比
内存
、分区
、副本
、读写
、索引
等 - 支持
container
的运行环境 - 大数据的倒入倒出
- 细粒度的订阅数据
- 兼容更多的生态,包括数据标准及分析等
- 能够运行在边缘或者数据中心
- 能够支持内嵌脚本(我理解为UDF这类)
2. 更开放的许可
InfluxDB
对于分布式版本是闭源的,这使得它在市场上和其它产品相比存在很大的差距,使得过去的几年中出现了不少时序数据库。而且若是开源协议对商业是有限制的,那么一些大的公司就会再开发本身的数据库出来,或者是采用其它开源的数据库,这样就形成了你们相互之间的不兼容的。并发
若是开源的协议采用有限制的协议,那么不少开发者除了内部使用外,即使是已经拿到开源的代码都别无选择的须要从新再开发。框架
开源创造了一个寒武纪大爆发,会创造出一个很是大的价值。开源不是零和博弈,一个很是大的社区和生态会为全部人和供应商带来更多的机会。运维
若是InfluxDB
想成为无数公司的传感器、监测、数据分析的基础方案,那么惟一的方法就是可扩展、可采用、任何人能够商业化。综上所述,InfluxDB
选择了 MIT & Apache 2
双重许可。
那么InfluxDB
如何盈利呢?在分布式的版本中,可能须要一系列的运维、监控等外围的工具,做为盈利的点。这样不管是云产品仍是开源版都是相同的代码,不产生fork
。
3. 更新的设计
在现有的InfluxDB
中,数据是这样:
cpu,host=serverA,region=west user=23.2,system=53.2 1604944036000000000
意思是,存储的cpu
这个measurement
;他有两个tag
,分别是host
和region
;有两个field
,分别是user
和system
;最后是一个纳秒的时间戳。数据被存储和索引为:
measurement, tag key/value pairs, field name
基于时间排序的(time-value)的键值对被存储为了一个单独的时间序列。measurement
、tag (key-value)
、field
被保存成了一个倒排索引。因此InfluxDB
其实是两个数据库,一个倒排索引和一个时间序列。这意味着,只要tag中存在里新的值,就必须存储在倒排索引中。好比在分布式追踪(distributed tracing
) 的场景里,每行数据都有一个惟一的id,这意味着二级索引比时序数据还要大,服务器就须要浪费大量的cpu和内存来处理索引数据。
有一个解决的方案就是使用field
来存储,可是这样限制来用户的使用,必须考虑何时为标签、何时是字段,查询的时候也须要考虑是否能使用到索引。
若是修改为为无限的基数(cardinality
),惟一的方式就是合并时序数据和倒排索引,这是数据库设计的核心。
文章中还提到了严格的内存控制,若是想作内存控制,就不能使用MMAP,全部的数据(索引和时序数据)在InfluxDB
中使用到的内存都须要被计算。
对象存储做为持久性层和批量数据导入导出的需求很难经过InfluxDB
构建的底层存储引擎来实现。现有的设计基本上假定是一个本地SSD,而且不容许将其中的数据导出到对象存储并在查询时导入。采用这种索引和时间序列数据分开的存储结构也难以实现大量数据的导入和导出。
这些潜在的问题致使没法让InfluxDB
作的更好,因此须要从根本上从新思考数据库的存储结构及核心架构是该如何组织。
4. Rust, Arrow, 列式存储
在决定重构核心的功能时,就必需要考虑使用什么工具可以让这个重构的过程变得更快、更可靠、更面向社区。Rust
做为系统级编程语言及Apache Arrow
做为内存分析工具集,这两款开源工具在过去的几年中,取得了巨大的进步。
Rust
能够为咱们提供了运行时行为和内存管理的更细粒度控制。还有一个额外的好处就是并发编程更容易,消除了数据竞争。在Crates.io
中又几乎包含了全部你须要用到的东西。
Apache Arrow
定义了一个内存的列式数据结构而且能够对接Parquet
(列式持久化文件格式)、Flight
(一个client/server的通讯协议框架,传输大数据集的高性能网络接口)。使用Rust
和Arrow
还有一个额外的好处就是DataFusion
(为Apache Arrow提供Rust原生支持的SQL查询引擎)。使用DataFusion
做为核心,意味着InfluxDB IOx
将提供一个开箱即用的SQL子集。固然除了SQL以外,还会继续支持InfluxQL
和Flux
。
基于列式存储的数据模型:
- Measurements会变为Table(每个measurement都是一张表)
- Tags和Fields会成为表中的列(这样就须要经过measurement来锁定一个范围)
- Tag和Field的Key在一个measurement中必须是惟一的
- 时间也会做为表中的列
除了scheme
的组织,还选择了Parquet
做为持久化文件格式。每一个Parquet
文件都包含了一张表中的部分数据,也就是每一个Parquet
文件只包含一个measurement
的数据。实验代表,Parquet
比InfluxDB
本身的TSM
引擎具备更好的压缩比。
另外是用户必须在建立数据库的时候指定分区策略(好比基于时间的每2个小时)。对于每一个分区,能够存储一些摘要性的数据在内存中,包含分区都拥有哪些表,有什么列,这些列的最大最小值等。这意味着查询计划能够在执行前经过这个元数据排除大量的分区数据。同时这种分区方案更容易使用对象存储做为长期存储,并管理从内存到对象存储再到索引的Parquet
文件的数据生命周期。
现有的列式数据库,并无单独针对于时序数据作优化而且分离计算和存储,尤为是具备很是优秀的字典和窗口聚合查询。
最后文中提到了一点颇有意思的研究方向,他说:咱们须要一个可以在内存中保存压缩数据并对其执行查询的系统。因此正在积极扩展DataFusion
使其可以处理更多的内存中的时序数据。
5.我的总结
总体看来,InfluxDB想把全部功能开源、分离计算和存储,支持对象存储的方式、精细的控制内存、而且能够在内存中处理压缩的数据。不是什么颠覆式创新,只是为了更好的处理时序数据。
欢迎关注微信公众号:
或添加微信好友: liutaohua001