InfluxDB IOx 发布 - 使用 Rust 和 Arrow 构建的 InfluxDB 未来核心
作者:Paul Dix / 产品, 用例, 开发者
2020 年 11 月 10 日
导航至
2013 年 11 月 12 日,我首次公开谈论 InfluxDB,主题为:InfluxDB,一个开源分布式时间序列数据库。在那次演讲中,我介绍了 InfluxDB,并概述了我谈论时间序列时的含义:具体来说,它是您可能随时提出问题的任何数据。作为示例,我展示了指标(这是人们通常在谈论时间序列时想到的),以及金融市场数据、用户分析数据、日志数据、事件,甚至 Twitter 时间线。更广泛地说,我认为您执行分析的所有数据都是时间序列数据。这意味着,无论何时您进行数据分析,您都是在一段时间内或作为时间快照来执行分析。
在这篇文章中,我将阐述 InfluxDB 未来的愿景,并向您介绍一个将构成其基础的新项目:InfluxDB IOx(发音为 eye-ox,iron oxide 的缩写)。正如文章标题所说,这个新项目是用 Rust(iron oxide,当然)和 Apache Arrow 作为核心编写的。在深入探讨该项目及其底层技术之前,我想回顾一下 InfluxDB 最初的目标以及自七年前推出以来发生的变化。
但首先,以下是您在阅读标题后可能产生的一些问题的答案
- InfluxDB 2.x 开源版本将继续并行发展,并定期发布小版本。
- InfluxDB IOx 将支持 SQL(原生支持)、InfluxQL 和 Flux(通过 2.0 和带有独立守护程序的 API)。
- 在未来的小版本中,InfluxDB IOx 将成为 InfluxDB 的可选存储后端。
- InfluxDB Cloud 客户将在明年年初将 InfluxDB IOx 作为新 Bucket 的可选后端。
- InfluxDB Cloud 客户将在 2021 年的某个时候无缝、零停机地过渡到这项新技术。
- InfluxDB Enterprise 客户将在 2021 年下半年获得商业支持版本的 InfluxDB IOx 和 InfluxDB Enterprise。
- InfluxDB IOx 将有自己的构建版本,并且可以与平台的其余部分分开运行。
我对 InfluxDB 的最初愿景是,它将被用于各种分析任务,包括实时和更大规模的分析。它将适用于服务器和应用程序性能监控、传感器数据应用程序以及其他分析应用程序。基本的见解是,时间序列是构建这些领域应用程序的有用抽象,而 InfluxDB 将构成这些应用程序的核心基础设施。
今天的 InfluxDB 是指标用例的绝佳数据库。它也非常适合分析,但需要注意的是,您的数据不能具有显著的基数。也就是说,您定义的标签不应有太多唯一值。随着 Flux 作为轻量级查询和脚本语言的加入,您现在可以在数据库中进行复杂的分析,甚至在查询时与其他第三方 API 和数据库进行交互。
随着用户在数据库中做的事情越来越多,基数限制正日益成为一个障碍。例如,我们希望能够存储和处理分布式追踪数据,但对于当前的底层 InfluxDB 架构而言,这种用例是遥不可及的。我们也希望欢迎更广泛的用户群体,他们可能更喜欢使用 SQL 和其他脚本语言。
在分布式方面,如今的开源 InfluxDB 不是分布式数据库,并且不为用户提供使用它创建分布式操作环境的工具。我们在 Cloud 和 Enterprise 产品中的商业产品中保留了该功能。从我们的开源努力的角度来看,这是一个不幸但必要的限制,因为我们需要建立业务才能支持我们所做的所有开源工作。
自从 InfluxDB 推出以来的七年间,我们看到了许多其他 时间序列数据库 加入开源和闭源领域。我们还看到了基础设施软件领域的重大变化,Kubernetes 崛起为主流,Hadoop 衰落,以及更通用的对象存储的兴起,其上构建了更灵活的软件计算堆栈。
InfluxDB 下一次演进的需求
考虑到更广泛生态系统中的所有这些变化以及用户日益增长的需求,我们认真考虑了 InfluxDB 的未来发展方向,并确定了一组要努力实现的高级需求。
- 无基数限制。写入任何类型的事件数据,无需担心标签或字段是什么。
- 除了我们已良好服务的指标查询之外,在分析查询方面提供一流的性能。
- 将计算与存储分离,并采用分层数据存储。数据库应使用更便宜的对象存储作为其长期持久存储。
- 操作员控制内存使用量。操作员应能够定义用于缓冲、缓存和查询处理的内存量。
- 操作员控制的复制。操作员应能够在每台服务器上设置细粒度的复制规则。
- 操作员控制的分区。操作员应能够定义如何在多台服务器之间以及在每台服务器上分割数据。
- 操作员控制拓扑,包括分解和解耦服务器任务的能力,以用于写入缓冲和订阅、查询处理以及长期存储的排序和索引。
- 设计为在短暂的容器化环境中运行。也就是说,它应该能够在没有本地连接存储的情况下运行。
- 批量数据导出和导入。
- 针对部分或全部数据的细粒度订阅。
- 更广泛的生态系统兼容性。在可能的情况下,我们应力求使用和拥抱数据和分析生态系统中新兴的标准。
- 在边缘和数据中心运行。设计上为联邦式。
- 用于进程内计算的可嵌入脚本。
这是一组相当广泛的需求。此外,诸如复制和分区之类的需求目前不属于我们的开源范畴。尝试朝着这些需求构建有很多影响。我想谈论的第一个是许可。
为什么 MIT 和 Apache 2 许可证很重要
我们在 InfluxData 生产的开源软件是在宽松的 MIT 许可证下许可的。我们长期以来一直认为,我们的开源代码应该真正开源,而我们的商业代码应该独立且闭源。正如我之前提到的,我们为我们的商业产品保留了高可用性和集群功能。鉴于我们的新需求呼吁复制、数据分区和其他分布式方面,我们不得不再次重新审视这个决定。
我们最初创建 InfluxDB 的原因之一是,我们看到许多开发人员和组织在分布式时间序列数据库方面重复造轮子。我们当时认为,正如我们现在所做的那样,时间序列是一个特定的用例,它受益于专门为其设计的系统。
这是我在 Cassandra、Redis 和其他系统之上构建时间序列 API 时的经验。我最终不得不编写大量的应用程序级代码,以实现我需要的那种功能。我认为 InfluxDB 可以成为共享的基础设施。
然而,开源核心项目中没有分布式功能,这在市场上留下了一个巨大的缺口。过去几年中出现的如此多的时间序列数据库就证明了这一点。如果我们希望 InfluxDB 成为未来需要在规模上处理和操作时间序列的项目的构建块,我们需要找到一种方法来开源更多,而不是更少。
此外,这项工作必须在真正的宽松开源许可证下获得许可。如果大型公司无法采用它,他们最终会自己发明它。如果其他公司无法在其基础上建立业务并将其 API 暴露给其用户,他们最终会自己构建它。如果云提供商不托管它,他们最终会创建自己的版本,这些版本可能不兼容,也可能不是基于开放 API 构建的。
在源可用或受限权限下许可的基础设施项目本质上是进化死胡同。有限的用户集可以采用该软件,而更有限的用户集实际上可以在其之上构建产品。他们通常可以将受限许可证项目用于内部目的,但通常不能用于面向外部客户的项目。这些限制意味着许多开发人员别无选择,只能从头开始或从其他真正开源的项目中构建其他东西。
我理解公司为什么选择走这条路,但这非常具有局限性。这也是一种遗憾,因为他们中的许多人都是从最初实际上是开源的核心构建起来的。社区和开源与您的个别公司设法捕获多少价值无关。开源是关于在软件中创造寒武纪大爆发,创造的价值远远超过单个供应商设法货币化的价值。开源不是零和游戏。更大的社区和生态系统为所有供应商带来更多机会。
我们有一个愿景,即 InfluxDB 将成为无数分析、传感器、监控和数据分析项目和公司的基础。实现这一目标的唯一方法是,我们从一个可扩展、可采用且可供任何人商业化的起点出发。
为了实现这个更大的目标,InfluxDB IOx 将在 MIT 和 Apache 2 双重许可下获得许可,且没有任何限制。
话虽如此,InfluxDB IOx 旨在作为松散联邦式的共享无架构运行。操作员应完全控制各个服务器的行为。这也意味着,任何涉及多台服务器的生产场景都可能需要额外的软件来进行操作。
在最基本的情况下,这可能就像一些 shell 脚本和一个 cron 作业一样简单。在涉及短暂环境和多台服务器的更复杂场景中,这可能是一个复杂的软件。这种操作工具是我们商业产品的重点。这将首先在我们的 Cloud 产品中推出,稍后作为 InfluxDB Enterprise 的一部分作为本地部署产品推出。
系统的设计在架构应如何工作以及商业化应如何工作方面都是经过深思熟虑的。我们希望我们的 Cloud 产品运行与开源项目完全相同的代码,而不是一个分支。我们希望本地商业产品是对开源的补充,而不是替代品。
康威定律说你交付的是你的组织结构。Dix 的格言说,无论是有意还是无意,你的许可策略就是你的商业化策略。对于 InfluxDB IOx,我们的策略是拥有宽松许可的开源软件,该软件对其项目目标最大限度地有用,并与开源互补的商业软件配对。
为什么 InfluxDB IOx 是一个新项目
有一些需求使这项工作成为我们无法逐步构建的东西。在理想的世界中,您可以重构并逐步构建在现有代码库之上,以达到您想要的目标。这对于进化式改进非常有用,但对于重大飞跃而言却很困难。
对于 InfluxDB 当前的构建方式而言,最难满足的要求是无限基数。以下是 InfluxDB 中数据的组织方式。数据通过我们的 Line Protocol 发送,如下所示
cpu,host=serverA,region=west user=23.2,system=53.2 1604944036000000000
这是 cpu 测量的数据,带有 host 和 region 标签,以及 user 和 system 两个字段,以及一个尾随的纳秒纪元时间戳。InfluxDB 摄取此数据并按以下方式对其进行索引
测量名称、标签键/值对、字段名称
这是一个单独的时间序列,您可以在其中获得值、时间对的时间顺序列表。此外,测量名称、标签键和值以及字段名称在倒排索引中进行索引。这使得通过测量名称查找时间序列或按标签维度对其进行过滤非常快速。
但是,这意味着任何传入的新标签值都会创建一个新序列,并且必须在倒排索引中进行索引。随着时间的推移,这意味着您的基数越高,您的倒排索引就越大。在病态情况下(例如分布式追踪),您将在每一行上获得唯一 ID。这意味着您的二级索引将大于底层时间序列数据本身。您还在这种持续索引上花费大量的 CPU 周期和内存。
这些用例的一种解决方法是将此数据放入字段中。但是,这会导致用户不得不考虑标签与字段,并且在某些情况下限制了他们在查询时可以执行的操作,因为字段没有任何索引。
如果我们想处理无限基数,则倒排索引和时间序列的分割结构将需要更改。但是,这种结构是数据库设计方式的核心。
严格的内存控制要求也使重构变得困难。这意味着我们不能使用 MMAP,这是当前 InfluxDB 中所有数据和索引文件的使用方式。MMAP 是一个很棒的工具,许多现代数据库都是使用它构建的。但是,在容器化环境中,它很难使用。此外,MMAP 与我们能够在没有本地连接磁盘的情况下运行的要求不太一致。
最后,对于作为持久性层的对象存储以及批量数据导入和导出的要求,使用我们构建的底层存储引擎很难实现。该设计从根本上假设本地连接的 SSD,并且不利于将其中一些文件导出到对象存储并在以后在查询时导入它们。批量数据导入和导出使用我们分支的索引和时间序列数据库结构很难实现。
这些底层更改共同导致了一种情况,即我们无法逐步推进 InfluxDB 的核心。我们需要从根本上重新思考数据库核心的组织方式。
押注 Rust、Apache Arrow 和列式数据库
一旦我们意识到我们需要重做核心的很大一部分,我们便开始考虑可以使用哪些工具来使这项工作更快、更可靠且更面向社区。我长期以来一直是 Rust 作为系统语言 和 Apache Arrow 作为内存分析工具集 的粉丝,这已不是什么秘密。我认为这两者是系统软件、OLAP 和数据分析的长期未来。在过去几年中,它们都取得了巨大的进步。
Rust 使我们能够更精细地控制运行时行为和内存管理。另外,它可以更轻松地进行并发编程并消除数据竞争。它的打包系统 Crates.io 非常出色,并且包含您开箱即用所需的一切。随着去年秋天 async/await 的加入,我认为是时候开始认真考虑它了。
Apache Arrow 定义了列式数据的内存格式,以及 Parquet,一种持久性持久格式,以及 Flight,一种客户端/服务器框架和协议,用于“通过网络接口高性能传输大型数据集”。另外,在 Rust 的 Apache Arrow 工具集中,还有 DataFusion,一个用于 Apache Arrow 的 Rust 原生 SQL 查询引擎。鉴于我们正在使用 DataFusion 作为核心进行构建,这意味着 InfluxDB IOx 将开箱即用地支持 SQL 的一个子集,并且随着 DataFusion 项目的成熟,无论是在 InfluxDB IOx 中使用还是通过 InfluxData 以外的协作者的开发努力在其他地方使用,其功能都将不断扩展。但是,InfluxDB IOx 也支持 InfluxQL 和 Flux。我们再次认真对待向后兼容性。
此架构的最后一部分是数据库的结构。我们的赌注是,针对时间序列优化的列式数据库可以用作未来 InfluxDB 的基础。这是 Apache Arrow 和 DataFusion 的结构,并且与我们更广泛的生态系统兼容性目标非常吻合。以下是我们如何将 InfluxDB 的数据模型映射到列式数据库模型
- 测量名称变为表(即,每个测量名称都是一个表)
- 标签和字段变为这些表中的列(因此它们的作用域限定为测量名称)
- 标签键和字段键在测量名称中必须是唯一的
- 时间是一列
除了这种组织方案之外,我们还选择了 Parquet 作为长期持久化格式。每个 Parquet 文件包含单个表的部分数据,这意味着每个文件都包含单个度量的数据。通过我们的研究,我们发现使用 Parquet 作为持久化格式,我们可以在真实世界数据上实现与我们自己的 TSM 引擎一样好甚至更好的压缩效果。
此外,我们将所有数据分解为多个分区。数据如何拆分为分区由运维人员或用户在创建数据库时定义。最常见的分区方案将简单地基于时间(例如:每 2 小时)。
对于每个分区,我们都保留了其包含内容的概要信息,这些信息可以保存在内存中。此概要信息包括存在的表、表的列以及这些列的最小值和最大值。这意味着查询计划器只需查看分区元数据,就可以在执行之前排除数据集的大部分。
这种分区方案也使我们更容易使用对象存储作为长期存储,并管理从内存到对象存储再到索引化的 Parquet 文件的数据生命周期。
列式数据库并不新鲜,那么我们为什么要构建另一个呢?我们找不到一个针对时间序列进行优化的开源数据库。在查询方面,我们需要字典支持和窗口聚合成为首要且优化的功能。在持久化方面,我们需要一些旨在将计算与存储分离的东西。
这个项目本身并没有什么革命性的东西。在过去的几十年里,列式数据库已经被广泛研究。使用对象存储分离计算和存储是另一件在过去十年中势头渐增的事情。Snowflake 代表了闭源领域中最近更引人注目的例子之一。
我们认为,将这些工具结合和组合在一起,以 Apache Arrow 作为开源服务器项目的核心,代表了开源世界中一种新的且有趣的方案。我们认为,未来的分析和监控项目,无论是实时的还是大规模的,都可以将此作为构建基石。
我们已经在使用 Rust 和 Go 语言回馈 Arrow 社区。这加倍了我们在那里的承诺。然而,我们的一些需求超出了 Apache Arrow 的目标。例如,我们需要一个可以将在内存中保持压缩数据并针对其执行延迟物化查询的系统。为此,我们正在创建 DataFusion 的扩展,这将使 InfluxDB IOx 能够处理比我们原本能够处理的更多的内存中时间序列数据。
项目状态
这个项目仍处于非常早期的阶段。我们目前没有生成构建版本,也没有超出 InfluxDB IOx 项目 README 之外的文档。团队由一小群专注于此的高级工程师组成,我们的工作与我们更大型的工程组织在平台其余部分所做的所有努力并行进行。我们的目标是在明年初发布开源构建版本,并在 InfluxDB Cloud 中提供 alpha 版本。
我们现在谈论这个是因为我们认为向社区告知我们的发展方向非常重要。我们也希望开放这个项目,以便其他对此感兴趣的人可以关注甚至贡献。
InfluxDB 开源用户的历程
对于开源 InfluxDB 2.0 用户,这没有直接影响。这项工作仍处于早期阶段,可能在一段时间内还无法用于生产环境。您可以期待未来的 InfluxDB 2.x 小版本将能够使用 InfluxDB IOx 作为可选的存储和查询后端。
在 InfluxDB IOx 开发期间和之后,InfluxDB 2.x 系列的工作将继续进行。这不会对 API 造成任何重大更改。但是,2.x API 中的其他功能将随着时间的推移陆续推出,并且社区可以在可用时使用它们。InfluxDB IOx 的开发和采用周期应该是渐进式的,而不是像 1.x 到 2.0 版本周期那样一次性完成。
InfluxDB 客户的历程
对于我们的 InfluxDB Cloud 客户,他们可以选择在明年上半年某个时候使用这项新技术作为新存储桶的后端。随着我们技术的成熟和获得更多的运营经验,我们将开始计划升级现有客户和存储桶。这将对 API 没有影响,并且将以零停机时间交付。
对于我们的企业客户,我们将把 InfluxDB IOx 与 InfluxDB Enterprise 集成,并提供一款产品来帮助在 Kubernetes 环境中运行此软件。但是,Kubernetes 不是运行 InfluxDB Enterprise 或 InfluxDB IOx 的必要条件。它只是启用了一组与集群灵活性和弹性相关的更多功能。
参与进来
目前,一切都在 InfluxDB IOx 仓库 本身或我们的 社区 Slack 频道 #influxdb_iox 中进行。您也可以在我们的社区 Discourse 上的 InfluxDB IOx 类别 中发布问题或评论。
在这篇文章中,我还有很多想说的。我甚至没有真正深入到核心技术细节。如果您渴望了解更多信息,我将在太平洋时间每月第二个星期三上午 8:00 主持一个 月度技术深入演示。
最后,如果您对这个项目感兴趣并希望获得全职工作报酬,我们正在招聘。我们正在寻找在以下一个或多个技能领域有经验的人员:Rust、分布式系统和列式数据库。缺点是您必须直接与我合作,但优点是您将有机会与我才华横溢的队友一起工作。请发送电子邮件至 [email protected] 并抄送给我 [email protected]。