YMatrix 姚延栋:专用 vs. 分久必合,关于 InfluxDB 启动新产品 IOx 研发的思考

2021-08-04 · 姚延栋
#博客#行业观察

时序数据库的世界里,InfluxDB 一直是 No.1,多年霸榜 DB-Engines。但是,2020 年底,InfluxDB 官方宣称启动氧化铁项目,再造另一个时序数据库 InfluxDB IOx,这意味着,InfluxDB 将战略性放弃稳居数年的榜首产品。

做过数据库的人都知道,从头写一个数据库是非常难,耗人耗时。把一个数据库做到行业内第一,更是难上加难,InfluxDB 用了 8 年。

2020 年底,也是 YMatrix 团队启动创业的时候,虽然我们的产研方向不是单一服务时序场景数据库,而是超融合数据库。但是,国内当时以时序为研发重点的创业团队,正雨后春笋般涌出。

看到细分领域老大自断后路,再踏新程,也引发了我们的很多思考。经历半年多沉淀,特此回顾并记录分享。

行业 No.1 的重踏征程

物联网时代到来,时序数据加速膨胀,无论数据规模还是应用场景,相比5到10年前,都发生了巨大变迁。同时,基础设施方面,5G普及为千万级设备的实时监控和智能网管,提供了可能性。

亿级网联异构设备覆盖的智能家居场景需要处理频率、指标数量和质量均参差不齐的数据采集和分析,车联网、自动驾驶需要应对数千指标高频采集和实时决策……类似的场景和挑战在每个行业中都正在发生。

作为一名数据库老兵,我们必须承认,过去十几年的产品积累仅能勉强应对,但已经无法满足未来时序场景下持续演进的需求。从国王到民众,无一幸免。

然而,国王终究是国王,看的更长远。InfluxDB 深耕时序数据处理行业多年,见证了整个时序数据发展的历史。从最初的设备监控,扩展到日志采集、事件追踪、用户评论、甚至金融分析等等,无处不在。以历史看未来,InfluxDB 创始人兼 CTO Paul Dix 描述了自己眼中的时序数据: "all data you perform analytics on is time series data. Meaning, anytime you’re doing data analysis, you’re doing it either over time or as a snapshot in time."

可见,任何有分析需求的数据,都是时序数据,数据因时间的存在被赋予了新定义。

InfluxDB IOx设计目标映射的趋势

为了更好的分析新时代的时序数据,InfluxDB IOx 列举了新一代时序数据库的设计目标,行业内称之为"时序十三条": 可以总结出:

  1. 时序数据库需要更好的扩展性以应对日益增长的数据总量和设备规模,同时尽量维持资源的合理开销。 PB级数据规模、亿级接入设备、单次采集上千万指标在很多场景中已经司空见惯,对时序数据库的分布式架构、存储引擎、资源管理机制提出了巨大挑战。
  2. 时序数据为分析而生。 不仅仅是过去用于仪表盘的简单聚合查询,也包括越来越多样化的复杂查询、基于历史数据的机器学习、模型训练,还会涉及到用内置高级语言进行数据分析,甚至通过开放的数据格式与生态其他数据库做联邦分析等等。从查询表达力和性能角度来看,时序数据库和分析型关系数据库的差异正在逐渐减少。
  3. 云边一体的趋势不可逆。 数据库向云原生演进,最大化边缘侧的算力,设计高效的云边数据协同,是新一代时序数据库的必选项。

在产品定位上,InfluxDB IOx 会是面向分析的列存数据库,而不仅仅是原有专用时序数据库,为了更好满足设计目标:

  1. 采用Rust语言,尽可能复用开源组件。
  2. 架构采用存储计算分离,所有状态持久化到对象存储,保证计算资源调度的灵活性。
  3. 存储引擎采用Apache Arrow + Parquet的经典组合,回归关系模型,通过列式存储、稀疏索引降低存储开销。
  4. 计算引擎核心采用Data Fusion,查询接口兼容标准SQL,优化器和执行器泾渭分明。

从 InfluxDB 到 InfluxDB IOx 的演变可以看出下一代时序数据库应该是这样的:

  1. 首先,它必须是一个面向分析的数据库。原有简单的时序聚合查询已经远远无法满足越来越复杂的时序场景,需要应对大规模数据、复杂查询、高性能的数据库,这正是OLAP数据库积累数十年的精华所在。
  2. 其次,在OLAP数据库基础上,除了要征服时序数据与生俱来的数据加载、查询性能和存储成本的三座大山,还要进一步解决日益突显的海量设备规模所带来的High Cardinality问题。
  3. 最后,数据库要成熟稳定,简单易用,无需像大数据系统一样动辄雇佣一个加强排的人力去维护。

回归 YMatrix 在技术路线上的思考

YMatrix 作为超融合时序数据库的开创者,从创立时确立了“一切数据都为分析提供服务”的目标。

InfluxDB 到 InfluxDB IOx,是从时序延申到更通用的架构,在关系数据库上做减法,单独为时序数据定制优化。

而 YMatrix 的产品则是再在关系数据库的基础上,更好的实现对时序数据的支持,以做加法的方式立足时序场景市场。和 InfluxDB IOx 选择从 0 开始写一个数据库不同,我们选择站在巨人的肩膀上,基于 PostgreSQL 在关系数据库上几十年的积累和沉淀,通过其优秀的扩展机制增强分布式架构、存储引擎和计算引擎的能力,将时序数据处理面临的问题在关系数据库核心引擎里完美解决。

我们的方法不同,但交汇在了技术栈“由分到合”的重要转折点,最终的产品形态或许会走向同一条道路。

重温经典,为什么我们选择站在巨人的肩膀上?

自上世纪70年代起,关系数据库诞生,一直都是解决所有数据处理问题的瑞士军刀,精致而简洁。

2000 年前后,互联网的繁荣使得数据量加速膨胀,关系数据库扩展性差的缺点被显著放大。为了解决扩展性问题,一部分选择了保留关系数据库核心能力,采用分库分表结合中间件的方案做替代。

另一部分选择放弃制约关系数据库扩展性的关系模型和事务支持,将数据间原本固有的约束和关联关系从数据库转移给应用,这样即无需再支持标准 SQL、Schema、ACID、优化器这些关系数据库的核心要素,通过极简设计换取最大的扩展性和性能,即所谓的 NoSQL,满足了当时大数据最迫切的海量数据写入性能和存储问题,在包括时序在内的各个场景遍地开花,OpenTSDB、InfluxDB 等优秀的时序数据库都是典型的 NoSQL。

然而,数据终将是需要通过分析体现价值的,尤其是数据量逐渐增大,更是需要复杂的分析来挖掘大数据中潜在的关联价值。分析能力的弱化是所有NoSQL的通病,这是放弃关系模型所必须付出的代价。

时代向前,技术进步,关系数据库也在分布式的道路上探索前行。MP P架构的 OLAP 数据库是大数据分析的标配,NewSQL 的提出将关系模型的扩展性问题得以解决,所有这些在关系数据库能力边界的技术拓展,都成为了构建下一代时序数据库的基石。

所以,YMatrix 选择以关系数据库经典理论为基础,在实践中并没有重新造轮子,而是采用 PostgreSQL,世界上最高级的开源数据库为核心引擎。PostgreSQL 功能完备、稳定可靠、组件化、扩展能力强。YMatrix 基于 PostgreSQL 提供的扩展机制,针对时序场景数据的特征,对分布式架构,存储引擎,计算引擎和资源管理进行全方位的时序化。

1、分布式架构

YMatrix 超融合数据库的分布式架构起源于 Greenplum,一款基于 PostgreSQL 的面向分析型场景的 MPP(Massively Parallel Processing)数据库。

我们采用 Share Nothing 的主从架构,每个节点均是一个完整的 PostgreSQL 数据库实例:主节点 Master 负责集群元信息管理,接收客户端请求,进行查询解析和查询计划生成;从节点 Segment 负责数据的分布式存储和查询执行,查询执行过程中数据交换由高速网络组件 Interconnect 负责。

除了具有大数据存储和分析能力外,YMatrix 还包括如下特性:

  • 高性能。高速数据加载,分布式并行查询执行,对于数据读写均提供极致性能
  • 高可用。系统每个节点均有备份节点,任一节点失效后自动恢复,对业务透明
  • 线性扩展。秒级在线动态扩容,数据自动平衡,无需人工干预
  • 分布式事务。应对强一致性场景,保证数据不重不错不丢,减少应用负担
  • 安全可靠。支持多种安全认证、访问控制机制,以及丰富的数据加密算法
  • 数据联邦。无缝对接关系数据库、NoSQL、大数据生态主流产品,无需移动数据进行联邦查询分析
  • 生态完善。覆盖数据迁移,备份恢复,BI分析等上下游工具链

MatrixGate 组件用于时序场景下流式数据并行加载,提供 HTTP 接口,可接收上万客户端同时并发写入,既保证毫秒级延迟,又保证数据加载过程中事务的强一致性。

2、存储引擎

存储引擎是数据库的底层基础组件,决定了查询引擎如何高效访问数据。

时序数据是设备在不同时间点产生的数据,从存储的角度来看,尽可能保证时序数据在时间(Time)维度和设备(Tag)维度的局部性(Data Locality),将有利于时序数据的查询。 YMatrix 的分布式存储引擎,提供多种机制来优化数据的局部性,尽可能让同一设备连续时间的数据,在同一机器、同一数据库表、以及表内连续存储。 分布式环境下,数据分片(Sharding)是解决单机存储空间和资源限制的主要策略。YMatrix 通过对一个表定义分布策略(Distribution Policy),进行数据分片,分布策略包括:哈希分布、随机分布、复制分布。

在时序场景中,通常按设备标识对时序表做哈希分布,哈希分布的好处是将相同设备的数据存储到同一个 Segment 节点上。数据分布策略是在节点级别保证设备数据的局部性。

在数据分片的基础上,对时序表进行更细粒度的数据分区(Partitioning),有利于在查询执行中进行分区裁剪(Partition Pruning),降低扫描的数据量。YMatrix 支持的数据分区策略(Partition Policy)包括:范围分区,列表分区,哈希分区。

在时序场景中,按时间范围进行数据分区,一方面可以在时间维度上保证数据的局部性, 另一方面,时序数据通常具有冷热特征,按时间分区更适于对数据做生命周期管理。另外,YMatrix 支持多级分区以提供更极致的数据局部性。 例如,按时间做一级分区、设备做二级分区,极端情况下,每一个时间段一个设备一张分区子表,达到设备和时间两个维度上最佳的数据局部性,代价是创建更多的分区表,进而对表管理带来负担。

确定数据分片和分区策略后,接下来是设计每一个分区子表的存储策略,参考依据包括:

  • 数据组织方式:行存、列存,或者行列混存
  • 存储格式:面向行存的 HEAP,还是面向列存的存储格式,或是 PAX 格式如 Parquet、ORC 等
  • 索引类型:选择 BTREE 索引、范围稀疏索引,或是倒排索引,甚至自定义索引
  • 编码压缩方式:不同数据类型如何确定最佳编码,压缩算法选择压缩比优先还是速度优先

YMatrix 具有多态存储特性,支持为分区表的每个子表定制不同的存储策略。时序场景中,冷热数据由于访问模式不同,对存储策略的需求也不同。

热数据对应时间较近的数据,用分区表中时间段最新的分区存储,对存储策略的需求包括:

  • 写入性能好,优先保证时序数据的加载能力
  • 热数据价值密度高,分析需求强,查询类型包括最新值点查、时间范围明细查询,以及按时间段和设备聚合查询等
  • 热数据占数据总量比重小,压缩需求不强烈,但可能伴随潜在的修改删除,以及乱序写入情况

因此采用行存 HEAP 表 + BTREE 索引更适合。HEAP表提供高速数据加载性能,且不对数据写入顺序做要求,同时对修改删除友好。BTREE 索引与数据分离存储,一方面可以加速加载性能,因为时序数据顺序写入 HEAP 表,索引仅为数据引用,维护代价小;另一方面分离带来灵活性的优势,为不同访问需求的列创建不同索引,如创建设备+时间的组合索引,相当于利用索引精确组织每个设备逻辑上的数据局部性, 进而加速相应查询性能。

冷数据对应历史数据,用分区表中除最新分区外的其他分区存储,对存储策略的需求是:

  • 历史数据占数据总量比重高,且随时间持续增长,对存储空间敏感
  • 查询主要为聚合分析查询,几乎无点查需求
  • 历史数据无修改更新需求,某一时间点后统一进行生命周期管理

YMatrix 超融合数据库针对时序历史数据特征设计了全新的 MARS(Matrix Append-optimized Resilient Storage)存储引擎,存储格式为行列混存,每一个行列分组单元为一个 RowGroup,包括一个设备一个时间段按时间排序的全部数据,RowGroup 是在分区表基础上保证每个设备时序数据的物理局部性。 RowGroup 内设备数据按列组织,一个列组为一个 Chunk,Chunk 在分组内保证具有相同数据类型的单列数据的局部性。

MARS 存储引擎极致的保证时序数据局部性有很多好处。首先,Chunk 内列数据的局部性有助于编码压缩,同一列数据类型相同压缩比高。MARS针对不同时序类型选择最适合的编码方式,time 列采用 delta 编码,浮点数采用 Gorilla编码,压缩算法支持 ZSTD、LZ4 等,对于典型时序数据,压缩比可达 1:10。

其次,RowGroup 根据设备数据局部性,可以预先计算好 RowGroup 内每个列的常见聚集信息,如 COUNT、MIN/MAX、FIRST/LAST、SUM 等,对于聚合查询,智能的根据查询条件直接获取预聚集结果,避免直接遍历计算每一个原始数据点,大幅提升查询性能。

最后,预聚集信息中 MIN/MAX 可以做为稀疏索引,替代空间占比高的BTREE索引。在带过滤条件的查询中,快速过滤不在(MIN,MAX)范围内的 RowGroup,进而大幅降低 IO 开销。在可能的候选 RowGroup 中,因为设备数据已经排好序,通过二分查找可以快速定位到具体的行,如果是范围型查询,后续根据有序性来进行顺序扫描即可。MARS 存储引擎的稀疏索引,在点查、范围型查询的性能上接近BTREE,但空间开销仅为BTREE的百分之一甚至千分之一。 对于时序数据的生命周期管理,YMatrix 提供自动分区管理机制,包括自动创建热数据分区,自动冷热分区转换,历史数据过期自动删除(Data Retention)等,全程无需任何人工参与,应用只需将数据写入数据库即可。

3、计算引擎

计算引擎由优化器和执行器组成,YMatrix Database 优化器基于代价模型,在 Master 节点生成分布式查询计划,分发给所有 Segment 并行执行。

分布式查询计划进行最大粒度的拆分,每个拆分的查询计划片段均可以在 Segment 上由一组独立的 QE(Query Executor)进程执行,查询计划片段之间通过网络进行数据传输,最终将并行执行结果汇总到 QD(Query Dispatcher)进程并返回给用户。

YMatrix MPP 查询引擎的优势,是在最大化切分查询计划的基础上,充分调用所有集群资源,以达到最佳的查询性能。 针对时序场景, YMatrix 计算引擎充分感知存储引擎的数据局部性,提供多种优化策略。对于典型的时序查询,常规优化器和面向时序优化的查询计划分别为:

常规查询计划的执行流程为,通过时间过滤条件确定时序数据表的子分区表集合,依次遍历每个子分区表,收集每一个符合过滤条件的元组,执行分组排序,最终返回结果。其中,过滤条件可通过为time列建立BTREE索引加速访问。这种查询执行方式有如下问题:

  • 资源开销大:大量执行时间在扫描和分组排序操作上,扫描导致IO资源开销,分组排序导致CPU和内存资源开销,如果数据量过多,会导致外排序引起的额外IO。
  • 索引空间大:为了快速定位符合时间过滤条件的元组,需要在时间列建立BTREE索引,空间开销大,如果不用BTREE索引,则需要进行全表扫描,IO代价大。
  • 造成资源浪费:时序场景中,此类查询通常反复执行,唯一变化的是时间过滤条件,反复执行时,相同分组的聚集计算导致大量重复操作。

针对以上问题,YMatrix 查询优化器会充分感知数据分布特征和数据局部性,对于涉及 MARS 存储引擎的分区表,自动应用聚集下推优化。执行流程为:在每一个符合时间过滤条件的子分区表,通过 MARS 稀疏索引快速定位查询涉及的分块列表,对于块内元素都符合条件的分块,直接获取分块预聚集结果作为该分组的聚集结果,对于块内元素部分符合条件的分块,通过二分查找确定条件边界,然后顺序扫描完成分组计算。整个执行过程最大化节约了 CPU、IO 和内存资源,保证系统更大的扩展性和并发能力。

MARS 存储配合聚集下推在时序冷数据的查询性能和资源开销均达到了最优效果。然而,聚集下推并不能在全部场景发挥效果,例如:

  • 时序热数据采用HEAP存储,数据的局部性是通过BTREE索引间接维护的,没有物理分块策略,因此无法直接计算预聚集信息
  • 当涉及非常见的聚集类型,如每个分组的DISTINCT值,或业务变更导致分组规则改变,如时间分组单位不是预定义分组单位的整数倍,则无法直接利用现有预聚集信息

YMatrix 针对此类场景,设计了持续聚集功能,用户可以在时序表上定义感兴趣的持续聚集视图,视图中包括用户指定的聚集函数。当数据持续加载到表的过程中,聚集查询在后台持续运行,当用户想获取时序表的对应聚集结果时,直接查询持续聚集视图即可,最大程度避免了重复计算。当聚集需求在某个时间点消失时,直接删除持续聚集视图,对原始数据无任何影响。

除时序聚合查询外,还有机会涉及到一些为了模型训练而进行的复杂分析,如与其他数据表进行关联操作,与其他外部数据源数据,如 HDFS、Hive、PostgreSQL 进行联合查询,查询中还可能涉及大量文本搜索、地理数据处理等。YMatrix 对于复杂查询提供丰富的功能和组件:

  • 支持现代 SQL 从 SQL-1992 到 SQL-2016 标准的各种高级特性,如嵌套子查询、递归 CTE、窗口函数等。
  • 丰富的类型系统和索引能力,如文本类型、JSON 类型、ARRAY 类型,GIS 类型,以及类型对应的高效索引方式,如倒排索引、通用搜索树索引等;
  • 以半结构化数据类型为主的时序场景定制的 KV 类型,无需预先定义 Schema,列数无上限,且压缩比和查询性能大幅优于 JSON 和 JSONB 类型;
  • 支持与多种外部数据源进行联邦查询,如 Hadoop 生态 HDFS、Hive、HBase 等,关系型数据库 PostgreSQL、MySQL、Oracle 等,以及 NoSQL 数据库如 MongoDB、Redis 等。

同时,对于复杂查询,通常涉及大量数据的复杂运算,YMatrix 除了提供丰富的功能支持外,还提供自适应并行计算引擎,充分利用多核等硬件资源来加速查询。

YMatrix 优化器根据查询特征智能的决定查询执行的并行度,如查询涉及的数据量、进程间通信代价等。确定并行度后对数据进行动态分片,通过每一个算子的并行执行,最大化资源使用,从而进一步提升查询性能。并行查询执行在涉及关联、聚集等计算密集型操作时效果尤其明显。复杂查询和并行计算的支持,使得 YMatrix 可以在典型时序场景之外,更好的胜任 OLAP 分析型场景。

4、资源管理

针对时序场景,通过对存储引擎和计算引擎的精细化设计,使得资源开销得以最大化节约。

  • 存储资源方面,通过类型定制的编码压缩,整体数据压缩比 1:10,索引压缩比 1:100。多态存储机制更是支持将存档类历史时序数据从数据库转移到更廉价的存储系统,如 HDFS、S3 等,进一步降低数据库存储开销而不影响任何业务查询。
  • 内存资源方面,无论是数据加载还是查询执行,内存开销均不与设备规模有关,系统根据查询计划和可用资源自动为每个算子分配合适的内存,在达到查询性能最优的同时,很好的解决了当前主流时序数据库面临的 High Cardinality难题。
  • CPU 和 IO 资源方面,极致的压缩比降低了查询时的 IO 开销,聚集下推和持续聚集通过减少重复计算节约 CPU 和 IO 资源,提升系统查询性能和扩展能力。
  • 网络资源方面,在数据加载过程中,对数据传输时进行压缩,进一步提升网络资源利用率。

对资源管理全方位细粒度控制和优化,使得 YMatrix 除了获得更好的扩展性和并发能力,也可以满足大部分 OLTP 场景的需求。

不忘初心,砥砺前行

站在巨人的肩膀上,通过精巧的设计,YMatrix 超融合数据库可以优雅的解决时序数据库面临的全新挑战。但这仅仅是开始。

在研发规划中,除了优先实现对关系数据、时序数据、地理位置的支持,YMatrix 的超融合架构将陆续实现对知识图谱、流数据等更多类型数据的支持,并且不断丰富包括高并发低延迟增删改查、点查、明细查询、聚合查询、窗口查询、关联查询、多维查询、库内机器学习在内的复杂分析功能。

未来,不断提升应用开发效率,简化运维负担,持续满足不同场景对数据处理的需求,不再需要用复杂技术栈解决通用大数据问题,让大数据处理回归简洁高效,是YMatrix 一直追求的目标,也是超融合数据库理念创立的初衷。

在产品名称的选取上,Influx 表示流入,代表数据随时间单向传递;Matrix 则表示矩阵、是汇聚,更看重数据随时间不断融合到一起,来分析数据之间纵横交错的关联。

由时序数据库参与推动的技术栈探索,是行业的一个重要节点。对于绝对路径和终点的讨论,目前还是开放性问题。这条路走起来会很坎坷,很漫长,YMatrix 很有幸成为首批探索者之一。