6

时序数据库Influx-IOx源码学习一(项目背景)

 3 years ago
source link: https://my.oschina.net/u/3374539/blog/5015114
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

为什么会发起IOx项目

原文请参见: https://www.influxdata.com/blog/announcing-influxdb-iox/

1. 下一步的目标

原文中介绍到,过去的7年时间的发展中,InfluxDBmetrics 数据的处理上已经成为了非常出色的数据库,并且在 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,分别是hostregion;有两个field,分别是usersystem;最后是一个纳秒的时间戳。数据被存储和索引为:

measurement, tag key/value pairs, field name

基于时间排序的(time-value)的键值对被存储为了一个单独的时间序列。measurementtag (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的通信协议框架,传输大数据集的高性能网络接口)。使用RustArrow还有一个额外的好处就是DataFusion(为Apache Arrow提供Rust原生支持的SQL查询引擎)。使用DataFusion作为核心,意味着InfluxDB IOx将提供一个开箱即用的SQL子集。当然除了SQL之外,还会继续支持InfluxQLFlux

基于列式存储的数据模型:

  • Measurements会变为Table(每一个measurement都是一张表)
  • Tags和Fields会成为表中的列(这样就需要通过measurement来锁定一个范围)
    • Tag和Field的Key在一个measurement中必须是唯一的
  • 时间也会作为表中的列

除了scheme的组织,还选择了Parquet作为持久化文件格式。每个Parquet文件都包含了一张表中的部分数据,也就是每个Parquet文件只包含一个measurement的数据。实验表明,ParquetInfluxDB自己的TSM引擎具有更好的压缩比。

另外是用户必须在创建数据库的时候指定分区策略(比如基于时间的每2个小时)。对于每个分区,可以存储一些摘要性的数据在内存中,包含分区都拥有哪些表,有什么列,这些列的最大最小值等。这意味着查询计划可以在执行前通过这个元数据排除大量的分区数据。同时这种分区方案更容易使用对象存储作为长期存储,并管理从内存到对象存储再到索引的Parquet文件的数据生命周期。

现有的列式数据库,并没有单独针对于时序数据做优化并且分离计算和存储,尤其是具有非常优秀的字典和窗口聚合查询。

最后文中提到了一点很有意思的研究方向,他说:我们需要一个能够在内存中保存压缩数据并对其执行查询的系统。所以正在积极扩展DataFusion使其能够处理更多的内存中的时序数据。

5.个人总结

整体看来,InfluxDB想把所有功能开源、分离计算和存储,支持对象存储的方式、精细的控制内存、并且可以在内存中处理压缩的数据。不是什么颠覆式创新,只是为了更好的处理时序数据。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK