原文链接: https://www.influxdata.com/blog/announcing-influxdb-iox/
翻译:stukid
选题:Cerdore
2013 年 11 月 12 日,我第一次做了关于 InfluxDB 的公开演讲,名叫 InfluxDB:一个开源的分布式时序数据库。在那次演讲中,我介绍了 InfluxDB ,并概述了当我讨论时序时的意思:具体来说,随着时间推移你可能会问到的任何问题。例如,我介绍了指标(当你讨论时序时人们一般会想到的),以及金融市场数据、用户分析数据、日志数据、事件,甚至 Twitter 时间线。更宽泛的说,我声称你分析的所有数据都是时序数据。也就是说,你在做数据分析的任何时候,都要么是随着时间推移分析,要么是分析某个时刻的快照。
在这篇文章中,我将展示InfluxDB 未来的愿景,并向你介绍一个形成其基础的新项目:InfluxDB IOx(读作 eye-ox,是 iron oxide 的缩写)。像文章标题所说的,这个新项目是用 Rust 写的,用 Apache Arrow 作为核心。在我深入介绍这个项目和它的底层技术之前,我想先看看 InfluxDB 最开始的目标和它诞生 7 年来的变化。
但是,首先回答你看到标题时可能会问的问题:
- InfluxDB 2.x 会并行地按照正常的节点继续开源。
- InfluxDB IOx 会支持 SQL(原生的),InfluxSQL,和 Flux(通过2.0和单独守护进程的 API)。
- InfluxDB IOx 会在未来的某个发布节点成为 InfluxDB 的可选存储后端。
- InfluxDB Cloud 客户会在明年的早些时候可以将 InfluxDB IOx 作为可选后端。
- InfluxDB Cloud 客户会在 2021 年的某个时候无缝、无宕机地切换到这个新技术。
- InfluxDB Enterprise 客户会在 2021 年下半年拥有 InfluxDB IOx 和 InfluxDB Enterprise 的商业支持版本。
- InfluxDB IOx 会有自己的构建并独立于平台其他部分运行。
我对 InfluxDB 最初始的愿景是它会用于所有类型的分析任务,包括实时和更大的规模。那样它会对服务器和应用性能监控、传感器数据应用和其他分析应用都有用。基本的看法是,时间序列是对构建这些领域的应用的有用抽象,而 InfluxDB 会构成这些应用的核心基础设施。
如今的 InfluxDB 是个指标场景中的伟大数据库。对分析场景也很好,但需要注意你的数据不能有非常大的基数。也就是,你定义的 tag 不能有太多不同的值。加上 Flux 这个轻量的查询和脚本语言,你可以用这个数据库做复杂分析甚至 查询时和其他第三方的 API和数据库交互。
随着用户在数据库上做的更多,基数的限制越来越频繁地成为障碍。比如,我们想存储和分析分布式 tracing 数据,但这个场景超出了当前 InfluxDB 架构的能力。我们也希望欢迎更多的用户,他们可能更希望使用 SQL 和其他脚本语言。
从分布式角度来说,InfluxDB 今天的开源版本不是个分布式的数据库,也并没有提供给用户工具来创建一个分布式的可运行环境。我们在云上和企业产品中为商业产品提供了这个功能。从我们努力开源的视角来说,这是不幸的但当时又有必要的限制,因为我们需要构建商业来支持我们所有的开源工作。
在引入 InfluxDB 后的 7 年中,我们已经看到了很多其他时序数据库加入到开源或闭源的环境中。我们也看到了基础软件领域的巨大变化,Kubernetes 崛起,Hadoop 衰落,和其他更多通用对象存储以及其上灵活的软件计算技术栈的兴起。
随着更广泛的生态系统的这些变化和我们用户增长的需求,我们考虑InfluxDB 将向何处去并定下来一些高层次的需求。
- 基数无限制。写入任何事件数据并且不用担心 tag 或者 field 是什么。
- 在我们已经支持得很好的指标查询基础上分析查询也有同类最好的性能。
- 存算分离和分层存储。会使用更便宜的对象存储作为长期存储介质。
- 算子控制内存使用。算子应该有能力定义缓冲区、缓存和查询处理分别使用多少内存。
- 由算子控制的副本。算子应该有能力在每台服务器上设置精细的副本策略。
- 算子控制的分区。算子应该有能力定义数据如何在很多服务器之间和每个服务器中分割。
- 算子控制拓扑,包括分解和解耦服务器任务、写缓存和订阅、查询、排序和长期存储索引的能力。
- 设计使能运行在短暂的容器环境中。即应该有能力在没有本地存储的环境中运行。
- 批量数据导出和导入。
- 对部分或所有数据的精细的订阅。
- 更广的生态系统的兼容性。如果可能,我们应该使用和接受在数据和分析生态中新兴的标准。
- 在边缘和数据中心运行。设计时即支持联邦计算。
- 用于进程内计算的可嵌入式脚本。
这是个非常大的需求集,而且像副本和分区这类的需求目前还没进入我们的开源范畴。试图满足这些需求会产生很多后果,我第一个想讨论的是许可。
我们在 InfluxDB 生产的开源软件都在 MIT 许可证的许可之下。我们长期认为我们的开源代码应该真正开放,而我们的商业代码应该是分离且封闭的。像我之前提到的都那样,我们在商业产品中保留了高可用和集群特性。鉴于我们的新需求需要多副本、数据分区和其他分布式的特性,我们必须重新审视这个决定。
我们首先创造 InfluxDB 的原因之一是因为我们看到了很多开发者和组织当需要分布式时序数据库时都在重复造轮子。我们当时认为,就像我们现在做的,时间序列是一个得益于为其明确设计的系统的特殊用例。
这是我在 Cassandra、Redis 和其他系统之上构建时序 API 的经验。我最后不得不写一大堆应用层的代码获得我需要的功能。我想 InfluxDB 可以成为共享的基础设施。
然而,在核心的开源项目中没有分布式特性,这和市场需求有很大的差距。过去几年那么多时序数据库的出现证明了这一点。如果我们想让 InfluxDB 成为未来需要与时序数据合作和运行的项目中的一块,我们需要找到一种方式来更多的开源,而不是更少。
此外,这项工作必须在一个真正的开源许可证许可之下。如果大公司无法采用它,那他们最终将自己发明一个。如果其他公司不能在它之上构建他们的业务然后把 API 暴露给他们的用户,他们将自己构建它。如果云厂商们不能托管它,他们将最终创建他们自己的版本,也许不能兼容和基于 open API 构建。
源代码开放或受限的许可下的基础设施项目本质上是进化的死胡同。有限的用户可以使用该软件,更少的用户可以在上面构建产品。他们经常用受限许可的项目作内部使用,但通常不用户面向外部客户的产品。这些限制意味着很多开发者别无选择,只能从头或从真正开源的其他项目开始构建。
我理解公司为什么选择走这条路线,但这有很严重的限制。这也是个遗憾,他们中很多都是从一个实际上是开源的核心开始构建的。社区和开源不是关于你的公司能获得多少价值。开源是在软件领域创造一个寒武纪大爆发,其所创造的价值远远超过单个供应商的盈利能力。开源不是零和游戏。大的社区和生态为所有供应商带来更多的机会。
我们有个愿景,InfluxDB 成为无数的分析、传感器、监控和数据分析项目和公司的基础。这可能成为现实的唯一一条路就是我们从一个可被任何人扩展、适配和商业化的起点开始。
为这个更大的目标服务,InfluxDB IOx 会在 MIT 和 Apache 2 的双许可,没有任何限制。
也就是说,InfluxDB IOx 会被设计为松散的联邦的 shared-nothing 架构。运维人员应该能完全控制每个服务器的行为。这也意味着任何包含多个服务器的产品场景都需要额外的运维软件。
在大多数基本场景中,这就像一些 shell 脚本和定时任务一样简单。在更复杂的场景中,涉及短暂的环境和很多服务器,这会是个复杂的软件。这个运维工具会在我们的商业产品中提供。首先在我们的云产品中,然后会作为 InfluxDB Enterprise 中的一部分中内置。
系统的设计考虑了架构应该如何工作,也考虑了如何商业化。我们想让我们的云产品完全像开源项目一样运行,而不是一个分支。我们想让内置的商业产品作为开源的补充,而不是替代品。
康威定律说发出你的组织架构图。Dix 的格言说你的许可证策略就是你的商业策略,无论是偶然的还是出于设计。有了 InfluxDB IOx,我们的策略是拥有许可的开源软件,这些软件最大限度地满足项目目标,并配合商业软件,其是对开源的补充。
有一些需求使得这种努力成为我们无法逐步实现的目标。在一个理想的世界中,你可以在现有代码库上重构和增量构建来达到想达到的目的。这对于逐步的改进很好,但对重大的飞跃很难。
要满足当前构建 InfluxDB 的要求,最困难的是无限基数。这是在 InfluxDB 中数据是如何组织的。数据是通过 Line 协议发送的,就像这样:
cpu,host=serverA,region=west user=23.2,system=53.2 1604944036000000000
这是带着 host 和 region 标签、user 和 system 两个字段的cpu测量数据,后面跟着纳秒级的时间戳。InfluxDB 在通过以下索引摄入这个数据:
measurement, tag key/value pairs, field name
这是个独立的时间序列,其中包含按时间排序的值和时间对。此外,度量的名称、标签的键值和字段名在倒排索引中被索引。索引 InfluxDB 的核心实际上是两个数据库:一个倒排索引和时间序列。这使得它根据度量名称查找时间序列数据,或者通过标签维度过滤掉都非常快。
然而,这意味着任何进来的新tag 值创建了一系列并且必须被索引在倒排索引中。随着时间推移,这意味着基数越大,倒排索引越大。在比如分布式追中的极端情况下,每一行都有唯一的 ID。这意味着你的二级索引会比底层的时序数据本身还要大。也会在这连续的索引上消耗大量的 CPU 和内存。
这些场景有一个解决办法是把这些数据放到字段里。但是,这会导致用户不得不想 tag 和 field在某些情况下的查询限制,因为 field 是没有索引的。
如果我们想应对无限基数,这种倒排索引和时序数据的分裂架构需要改变。但是,这个结构是这个数据库设计的核心。
严格的内存控制要求也让重构很困难。这意味着不能用 MMAP,这是当前 InfluxDB 中所有的数据和索引文件都在用的。MMAP 是个伟大的工具,很多现代数据库都在用。但是在容器化的环境中很难处理。而且在我们的不能在本地磁盘上运行的要求中,MMAP 也不能满足。
最终,对象存储作为持久化存储层和批量数据导入导出的要求很难在我们构建的底层存储引擎上满足。这个设计基本假设一个本地的 SSD,并且不能把一些文件导出到对象存储然后在查询时再导入回来。批量数据导入导出在我们的分支索引和时间序列数据库结构下也很难实现。
这些潜在的变化共同造成了一种情况,我们不能在 InfluxDB 的核心上逐步往前走。我们需要彻底的重新思考数据库的核心如何组织。
一旦我们认识到我们需要对核心中相当大的部分返工,我们开始考虑什么工具可以让我们做的更快、更可靠和更面向社区。我是系统语言 Rust 和内存分析工具集 Apache Arrow 的粉丝,这不是什么秘密。我认为这两个会是系统软件以及 OLAP 和数据分析领域的未来。它们在过去的两年都取得了巨大的进步。
Rust 让我们对运行时行为和内存管理有更细力度的控制。作为附加好处,它使得并发变成更容易,而且消除了数据竞争。它的打包系统 Crates.io 非常棒,并包含了你所需要的一切还开箱即用。加上去年秋天增加的 async/await,我认为是时候认真的考虑它了。
Apache Arrow 为列式数据定义了内存格式,以及 Parquet,一种持久化存储的格式,和 Flight,一个client/server 框架和为通过网络接口高性能传输大数据集的协议。作为额外的好处,Apache Arrow 工具中的 Rust 集中有 DataFusion,一个 Rust 原生的 SQL 查询引擎。考虑到我们正在一 DataFusion 为核心构建,这意味着随着 DataFusion 项目的成熟,不管是用于 InfluxDB IOx,还是通过 InfluxData 之外的合作者的开发努力,Influx IOx 会支持一个开箱即用的 SQL 子集,并有扩展的功能。但是,InfluxDB 也支持 InfluxQL和 Flux。再说一次,我们会认真对待向后兼容。
架构的最后一部分是数据库的结构。我们打赌,为时间序列优化的列式数据库可以作为未来 InfluxDB 的基础。这是 Apache Arrow 和 DataFusion 的结构,并且符合我们更大的生态兼容性的目标。这是我们如何把 InfluxDB 的数据模型映射到一个列式数据库的模型:
- 度量变为表(每个度量都是一个表)
- Tag 和 field 变为表中的列(他们的范围取决于度量)
- Tag 键和 field 键在一个度量中必须是唯一的
- 时间是一列
除了这个组织方案外,我们还选择了 Parquet 作为长期持久化格式。每个 Parquet 文件包含单表的部分数据,也就是说每个都包含单个度量的数据。根据我们的研究,我们发现真实世界的数据用 Parquet 作为持久化格式可以得到比我们自己的 TSM 引擎更好的压缩比。
此外,我们把所有数据分成分区。数据如何分到分区由创建数据库的运维人员或用户定义。最常见的分区策略是简单的基于时间(例如:每两个小时)。
对每个分区,我们在内存里保存了它包含内容的摘要。这个摘要包含什么表存在、它们的列是什么。和那些列的最大最小值。这意味着查询规划器可以在执行前简单的查看下分区元数据就可以排除大部分数据集。
这个分区策略也让我们更容易使用对象存储作为长期存储,并管理从内存到对象存储到带索引的 Parquet 文件的数据生命周期。
列式数据库并不新鲜,那为什么我们会再构建一个呢?我们在开源中没找到为时间序列优化的列式数据库。从查询这边来看,我们需要字典的支持和窗口聚合作为一等公民并优化。从持久化来看,我们需要支持存算分离。
这个项目中没什么特别的东西是革命性的。列式数据库在过去几十年已经被广泛的研究。使用对象存储的存算分离在过去十年也获得了发展。Snowflake 在闭源领域是最近一个比较有代表性的例子。
我们认为,这些工具的组合,用 Apache Arrow 在一个开源服务项目作为核心,在开源世界中代表着一个新的且有趣的产品。我们认为这是未来的实时和大规模分析和监控项目中可能使用的一块。
我们已经用 Rust 和 Go 语言回馈给 Arrow,这加倍实现了我们的承诺。然而,我们的一些需求超出了 Apache Arrow 的目标。比如,我们需要一个能把压缩后的数据放在内存中并在执行查询时再物化的系统。为了这个目的,我们正在扩展 DataFusion 来使得 InfluxDB IOx 可以在内存中处理更多的时序数据,这在其他情况下是做不到的。
这个项目仍然非常早期。我们还没有产出构建,除了 InfluxDB IOx 项目的 README 之外也没有更多的文档。这是个专注的高级工程师团队,我们的努力与我们平台其他大的工程团队的努力并行。我们的目标是在明年早些时候产出一个开源构建并在 InfluxDB 云上提供 alpha 版本。
我们现在谈论这个是因为我们认为让社区知道我们的方向很重要。我们也想开放这个项目,这样其他感兴趣的人可以跟进甚至贡献。
对开源的 InfluxDB 2.0 用户来说,没有直接的影响。这项工作仍然非常早期,看起来离准备好生产使用还有一段时间。可以预期将来的 InfluxDB 2.x 版本可以使用 InfluxDB IOx 作为可选的存储和查询后端。
InfluxDB 2.x 的工作在 InfluxDB IOx 的开发期间和之后都会持续。这代表在 API 上没有破坏性的变化。但是,2.x API 的附加功能会随着时间落地,并且会在它可用之后被社区使用。InfluxDB 的开发和采用周期会是渐进性的,而不是像 1.x 到 2.0 那样一次性升级。
对我们的 InfluxDB 云客户来说,他们在明年上半年的某个时候可以选择这个新科技作为新 bucket 的后端。随着我们使这项技术成熟和获得更多的运维经验,我们会开始升级已有的客户和 bucket。这对 API 不会有影响,并且不停服升级。
对我们的企业级客户,我们将集成 InfluxDB IOx 和 InfluxDB 企业版,并提供一个产品来帮助这个软件运行在 Kubernetes 的生产环境中。但是 Kubernetes 对运行 InfluxDB 企业版或者 InfluxDB IOX 不是必须的,它只是让和集群灵活性和弹性有关的一些特性可用。
现在所有的事情跟进都在 InfluxDB IOx 仓库或者我们社区的 Slack channel #influxdb_iox。你也可以在我们的社区论坛上 InfluxDB IOx 类别中发表问题或评论。
我在这篇文章中也没有更多想说的了,也没有深入核心的技术细节。如果你希望了解更多,我会在每个月的第二个周三上午 8 点主持一个月度的深度技术交流。
最后,如果你对这个项目感兴趣,并且想全职为之工作并获得报酬,我们也在招聘。我们正在找有一项或多项技能的人:Rust,分布式系统,和列式数据库。缺点是你得和我一起工作,但优点是你可以和我出色的团队成员们一起工作。发送邮件到 [email protected]并抄送我 [email protected]。