了解 InfluxDB IOx 及对开源的承诺
作者:Anais Dotis-Georgiou / 产品, 用例
2022 年 12 月 12 日
导航至
注意:要利用 InfluxDB 3.0(以前称为 IOx)以及本文中提到的进展,请在此处注册注册。
如果您一直在关注 InfluxDB,您可能听说过 InfluxDB IOx,它是为 InfluxDB Cloud 提供支持的存储引擎的下一个发展方向。但是,我想更多地了解新引擎的开源组件如何帮助实现新 InfluxDB 引擎的要求,以及为什么选择它们。这篇文章涵盖了 precisely 这个主题。我们还将了解 InfluxDB 为什么选择为这些开源项目做出贡献,以及我们今天对开源的承诺是什么样的。
新的 InfluxDB 引擎是使用 Rust、Apache Arrow(和 Arrow Flight)、DataFusion 和 Parquet 构建的。为了理解这些技术如何帮助构建 IOx,我们需要了解它们是什么,我们将在以下章节中详细讨论。但是,在深入研究之前,对每个组件都有一个广泛的了解非常重要
-
Rust 是一种性能非常出色且提供精细内存管理的编程语言。
-
Apache Arrow 是一个用于定义内存中列式数据的框架。
-
Parquet 是一种面向列的持久文件格式。
-
Arrow Flight 是一个“新的通用客户端-服务器框架,用于简化通过网络接口进行大型数据集的高性能传输”。
-
DataFusion 是一个“用 Rust 编写的可扩展查询执行框架,它使用 Apache Arrow 作为其内存格式”。
我们还需要了解 InfluxDB IOx 的要求,以便理解这些技术如何满足这些要求。下表概述了 InfluxDB IOx 的要求以及哪些技术对于实现这些要求至关重要。这些要求直接来自 Paul Dix 的帖子 Announcing InfluxDB IOx - The Future Core of InfluxDB Built with Rust and Arrow。
功能 | Rust | Arrow | DataFusion | Parquet |
---|---|---|---|---|
|
X | X | X | X |
|
X | X | X | X |
|
X | X | ||
|
X | |||
|
X | |||
|
X | X | X | X |
|
X | X |
但是,值得一提的是,投资这些技术的决定是多年来形成的。我鼓励您阅读 Paul 的早期博文,了解 Apache Arrow、Parquet、Flight 及其生态系统如何成为 OLAP 的游戏规则改变者。
为什么选择 Rust?
根据 文档,Rust 是“一种使每个人都能构建可靠高效软件的语言”。选择 Rust 是因为它具有出色的性能和可靠性。Rust 在语法上类似于 C++,并且具有相似的性能,因为它也编译为本机代码。但是,它比 C++ 具有更好的内存安全性。内存安全性是防止导致过度内存使用或内存泄漏的错误或安全漏洞的保护。Rust 通过其创新的类型系统实现了这些内存安全性的改进。它也是一种系统级语言,默认情况下不允许悬空指针或缓冲区溢出。悬空指针指向无效内存。悬空指针是导致 C++ 等语言中可利用的安全漏洞的主要错误类别之一。
现在我们知道了 Rust 是什么,让我们看看它如何满足 InfluxDB IOx 的要求。
1. 对基数没有限制。写入任何类型的事件数据,无需担心标记或字段是什么。
Rust 帮助满足此要求,因为 InfluxDB IOx 是基于 Apache Arrow 的 Rust 实现(下一节将详细介绍)构建的。此外,处理无限基数的方法在查询处理期间需要大量的 CPU。因此,您非常依赖于从 CPU 中榨取最多的性能,而 Rust 非常适合这样做。
2. 除了我们已经很好地服务的指标查询外,在分析查询方面提供一流的性能。
Rust 间接满足此要求,因为它为 Arrow、Parquet 和 DataFusion 的实现提供了基础(有关这些其他组件如何在稍后章节中为此目标做出贡献的更多信息)。Rust 内存优化的好处直接影响新引擎的存储性能和查询性能。如果没有查询执行框架 (DataFusion),您就无法进行出色的分析查询。如果没有通过持久存储 (Parquet) 以及内存存储和数据交换 (Arrow) 提供的数据来查询,您就无法利用这些分析查询。
4. 操作员控制内存使用量。操作员应该能够定义每个缓冲、缓存和查询处理使用多少内存。
IOx 使用 Rust 进行内存控制。根据 Paul Dix 的说法,“Rust 使我们能够更精细地控制运行时行为和内存管理。额外的好处是,它使并发编程更容易,并消除了数据竞争。它的打包系统 Crates.io 非常出色,并且包含您开箱即用所需的一切。随着 async/await 的添加以修复竞争条件”。例如,buffering crate 保证了防止缓冲区溢出和边界检查的保护。cached crate 确保了 线程安全、异步缓存结构,这有助于防止数据竞争。要了解更多关于 Rust 程序中内存和线程安全实践之间关系的信息,我建议您查看 此视频。本质上,Rust 提供了您在 C/C++ 中期望的精细内存控制,但改进了许多这些语言的缺点,包括安全性和多线程。
6. 更广泛的生态系统兼容性。在可能的情况下,我们应该努力使用和拥抱数据和分析生态系统中新兴的标准。
InfluxDB IOx 是基于 Apache Arrow 的 Rust 实现构建的这一事实满足了此要求。更多信息请参见以下章节。
7. 在边缘和数据中心运行。通过设计进行联邦化。
使用 Rust 优化您的内存使用量意味着 InfluxDB IOx 也在边缘或数据中心提供这些内存优化。
为什么选择 Apache Arrow?
根据 Wikipedia,Apache Arrow 是“一个与语言无关的软件框架,用于开发处理列式数据的 数据分析 应用程序”。
以下是 Apache Arrow 如何满足 InfluxDB IOx 的要求的。
1. 对基数没有限制。写入任何类型的事件数据,无需担心标记或字段是什么。
Apache Arrow 通过提供高效的列式数据交换来克服与高基数用例相关的内存挑战。让我们看看 InfluxDB IOx 如何存储数据,以及列式数据存储如何实现更高效的压缩。
假设我们正在将以下行协议行写入 InfluxDB IOx
measurement1,tag1=tagvalue1 field1=1i timestamp1
measurement1,tag1=tagvalue2 field1=2i timestamp2
measurement1,tag2=tagvalue3 field1=3i timestamp3
measurement1,tag1=tagvalue1,tag2=tagvalue3 field1=4i,field2=true timestamp4
measurement1, field1=1i timestamp5
IOx 返回下表,其中标记集和时间戳标识写入的新行。
名称:measurement1 | |||||
field1 | field2 | tag1 | tag2 | tag3 | 时间 |
1i | null | tagvalue1 | null | null | timestamp1 |
2i | null | tagvalue2 | null | null | timestamp2 |
3i | null | null | tagvalue3 | null | timestamp3 |
4i | true | tagvalue1 | tagvalue3 | tagvalue4 | timestamp4 |
1i | null | null | null | null | timestamp5 |
但是,IOx 以列式格式存储数据,如下所示
1i | 2i | 3i | 4i | 1i |
null | null | null | true | null |
tagvalue1 | tagvalue2 | null | tagvalue1 | null |
null | null | tagvalue3 | tagvalue3 | null |
null | null | null | tagvalue4 | null |
timestamp1 | timestamp2 | timestamp3 | timestamp4 | timestamp5 |
或者,换句话说,数据将像这样存储
1i, 2i, 3i, 4i, 1i;
null, null, null, true, null;
tagvalue1, tagvalue2, null, tagvalue1, null;
null, null, null, tagvalue3, tagvalue3, null;
null, null, null, tagvalue4, null;
timestamp1, timestamp2, timestamp3, timestamp4, timestamp5.
请注意,相邻的值是相同的数据类型并且相似,甚至相同。这为廉价压缩提供了机会,从而实现了高基数用例。这还使用所有现代 CPU 中发现的 SIMD 指令实现了更快的扫描速率。根据您对数据的排序方式,您可能只需要查看第一列数据即可找到特定字段的最大值。
与面向行的存储相比,您需要查看每个字段、标记集和时间戳才能找到最大字段值。换句话说,您必须读取第一行,将记录解析为列,将字段值包含在您的结果中,然后重复。借助 Apache Arrow,IOx 提供了更快、更高效的流程。
2. 除了我们已经很好地服务的指标查询外,在分析查询方面提供一流的性能。
Arrow 通过上述内存优化和高效数据交换,在分析方面提供一流的性能。如果没有 Arrow 提供的有效内存列式存储,您就无法进行高性能分析。
3. 将计算与存储分离,并分层数据存储。数据库应使用更便宜的对象存储作为其长期持久存储。
Arrow 提供内存中的列式存储,而 Parquet 提供磁盘上的面向列的数据文件格式。Parquet 和 Arrow 都是面向列的格式,并且两者之间具有出色的互操作性以及读写 API。这种互操作性实现了期望的存储分离。Parquet 还充当 IOx 长期持久存储的更便宜的对象存储(更多信息请参见 Parquet 章节)。
4. 操作员控制内存使用量。操作员应该能够定义每个缓冲、缓存和查询处理使用多少内存。
请记住,新的存储引擎是基于 Apache Arrow 的 Rust 实现构建的。这就是 Apache Arrow 能够获得对内存使用量的精细控制的方式。
6. 更广泛的生态系统兼容性。在可能的情况下,我们应该努力使用和拥抱数据和分析生态系统中新兴的标准。
使用 Arrow 作为底层格式,可以与庞大的、不断增长的、基于 Arrow 的生态系统进行快速轻松的数据交换。有 C、C++、Java、JavaScript、Python、Ruby 等语言(总共至少 12 种)编写的库。Apache Arrow 的广泛生态系统兼容性是 Google 的 BigLake、Apache Spark、Snowflake、Amazon Athena 和 RISELab 的 Ray 等技术将其集成到各自堆栈中以实现高效数据交换的部分原因。
为什么选择 DataFusion?
DataFusion 是一个“用 Rust 编写的可扩展查询执行框架,它使用 Apache Arrow 作为其内存格式”。
让我们看看 DataFusion 如何满足 InfluxDB IOx 的要求。
1. 对基数没有限制。写入任何类型的事件数据,无需担心标记或字段是什么。
如果没有能够处理高基数数据的查询引擎,您实际上就无法对其进行太多操作。虽然 DataFusion 不会帮助用户写入高基数数据,但它确实可以帮助用户查询、处理和转换该数据。
2. 除了我们已经很好地服务的指标查询外,在分析查询方面提供一流的性能。
IOx 使用 DataFusion 来执行逻辑查询计划、优化查询优化,并提供一个能够使用线程进行并行化的执行引擎。许多不同的项目和产品都使用 DataFusion,并且它拥有一个蓬勃发展的贡献者社区,他们添加了广泛的 SQL 支持和复杂的查询优化。这种社区投资使 IOx 的查询引擎比我们自己编写自定义引擎时更加成熟和高性能。由于 DataFusion 也建立在 Rust 之上,使用 Arrow 作为其内存列式格式,并使用 Parquet 作为其持久格式,因此这些技术的性能优势得以延续。
3. 将计算与存储分离,并分层数据存储。数据库应使用更便宜的对象存储作为其长期持久存储。
DataFusion 具有从对象存储读取 Parquet 文件的原生能力(无需在本地下载它们)。此外,DataFusion 可以选择性地读取 Parquet 文件中需要的部分*。它通过投影下推和对象存储范围扫描来实现这种选择性。DataFusion 还利用其他先进技术,进一步减少处理数据所需的字节数(例如,谓词剪枝、页面索引下推、行过滤、后期物化等)。所有这些功能都有助于针对存储在更便宜的对象存储上的数据进行快速查询,并分离计算。
请关注即将发布的关于此主题的文章。我们将在发布后在此处添加链接。
6. 更广泛的生态系统兼容性。在可能的情况下,我们应该努力使用和拥抱数据和分析生态系统中新兴的标准。
DataFusion 支持与 postgres 兼容的 SQL 和 DataFrame API。这意味着新的 InfluxDB 引擎将支持来自更广泛生态系统中大量使用 SQL(并最终使用 Pandas DataFrames)的用户。
为什么选择 Parquet?
Parquet 文件是一种压缩的列式数据格式。
让我们看看 Parquet 如何满足新 IOx 引擎的要求。
2. 除了我们已经很好地服务的指标查询外,在分析查询方面提供一流的性能。
由于 Arrow 和 Parquet 都是列式数据格式,因此与列式数据相关的所有已提及的优势都得以延续,并且也提高了它们的性能。Parquet 实现了出色的压缩,几乎与自定义文件格式一样好,甚至更好。Parquet 还支持与多种分析和 ML 工具的互操作性。
3. 将计算与存储分离,并分层数据存储。数据库应使用更便宜的对象存储作为其长期持久存储。
Parquet 文件需要很少的磁盘空间。面向列的文件格式设计支持快速过滤和扫描。事实上,Parquet 文件的存储成本比 CSV 文件便宜 16 倍。我建议阅读这篇关于 Apache Arrow 和 Apache Parquet:为什么我们需要用于列式数据、磁盘和内存的不同项目 的文章,以更好地理解这些工具的历史背景和演变,以及分离的好处。总而言之,RAM 的进步和 diskIO 造成的瓶颈推动了对这种分离和这些工具的需求。
5. 批量数据导出和导入。
Parquet 文件专门用于分析 (OLAP) 用例,因为它们支持批量数据导出和导入到生态系统中的其他工具,这些工具可以读取和写入 Parquet 文件。
6. 更广泛的生态系统兼容性。在可能的情况下,我们应该努力使用和拥抱数据和分析生态系统中新兴的标准。
Parquet 提供与几乎所有现代 ML 和 分析 工具的互操作性,这些工具提供一流的分析。DataFusion 支持针对 Parquet 文件的逻辑查询计划、查询优化和执行引擎的 SQL 和 DataFrame API。InfluxDB IOx 在这个大数据生态系统(Arrow、Parquet 和 Flight)中使用 SQL 支持查询。Parquet 实现了互操作性,因为许多最流行的语言(如 C++、Python 和 Java)在 Arrow 项目中都具有一流的支持,用于读取和写入 Parquet 文件。我个人对 Python 支持感到非常兴奋。这意味着您可以直接从 InfluxDB 查询 Parquet 文件,并将它们直接转换为 Pandas DataFrames,反之亦然 。您还将与其他支持 Parquet 的工具(如 Tableau、PowerBI、Athena、Snowflake、DataBricks、Spark 等)具有互操作性。
7. 在边缘和数据中心运行。通过设计进行联邦化。
由于 Parquet 文件非常高效,因此它们有助于并提高边缘数据存储的容量。
对上游项目的贡献以及对开源的承诺
InfluxData 认真对待其对开源的承诺。开源是 InfluxData 商业模式和文化的核心。InfluxData 的大部分代码(包括 influxdb_iox 存储库)都属于宽松的 MIT 或 Apache 2.0 许可证。宽松许可证为开发者提供
-
自由——能够使用代码在开源代码之上构建自己的应用程序和业务。
-
演进——能够演进软件或制作衍生产品。
-
影响——当聪明的人可以使用好的工具时,他们拥有自由、创造力和控制力来创造有影响力的解决方案。
InfluxDB IOx 工程师对 DataFusion 和 Arrow 等上游项目做出的贡献也反映了他们对开源的承诺。IOx 开发人员为构建 IOx 所使用的技术贡献的代码和社区参与度越高,IOx 就越好。这是一种值得投资的前馈、共生关系。两位 Influxer 是 Apache Arrow PMC 的成员,这有助于项目治理。IOx 工程师积极为该社区做出贡献,不仅包括代码,还包括评论、文档、博客和其他布道。
一些值得注意的代码贡献包括
-
对 Arrow-flight SQL 的贡献。
object_store 库的贡献
提议并将整个 object_store
crate 捐赠给 arrow-rs
。对象存储按需提供几乎无限的高可用性和持久键值存储。您可以在 Rush Object Store Donation 博客文章 和 apache/arrow-rs#2030 中阅读所有相关信息。Carol Goulding (@carols10cents) 主要撰写了这项工作,Marco Neumann (@crepererum) 也做出了重大贡献。Raphael Taylor-Davies (@tustvold) 和 Andrew Lamb (@alamb) 也向社区发布了 3 个版本的 object_store
crate。
对 Arrow 的贡献
InfluxDB IOx 团队管理 https://crates.io/crates/arrow 和 https://crates.io/crates/parquet 版本的每周发布。他们还帮助撰写和支持 DataFusion 博客文章,例如:Apache Arrow DataFusion 项目更新 和 2022 年 6 月 Rust Apache Arrow 和 Parquet 16.0.0 亮点。
对 Arrow 的其他贡献包括
对 Parquet 的贡献
InfluxDB IOx 团队通过有效地重写 Parquet crate 的大部分内容,为 Parquet 做出了重大贡献。Raphael Taylor-Davies (@tustvold) 因贡献而值得认可
- 优化的大量工作
- 读取 Parquet(例如,apache/arrow-rs#1284 和 apache/arrow-rs#1965)。
- 写入 Parquet,包括
- 直接将 Parquet 读取到 Arrow
- 用于与对象存储集成的异步读取器。
- 指导和帮助实施谓词下推的大量工作,例如定义 API (apache/arrow-r#2335)。
- 支持读取/写入任意嵌套数据。要了解有关此贡献的更多信息,请阅读 Arrow 和 Parquet 第 1 部分:原始类型和可空性。
- 重做了 Arrow 模式推断,以处理各种向后兼容性规则。
- 为增加更好的测试覆盖率、分类社区问题报告等做了大量工作。
Rust 生态系统贡献
-
对 Rustlang 的 Async Tokio 的贡献,包括优化线程池以管理 InfluxDB IOx 内 CPU 密集型和 I/O 工作的执行 (tokio-rs/tokio#4105)。
-
修复了广泛使用的 flatbuffers crate 中的健全性错误。
DataFusion 贡献
对 DataFusion 的贡献 包括内存优化,以更有效地查询 InfluxDB IOx。 具体而言,优化了执行真正大型的 groupbys 和 joins(当一个或两个输入不适合可用 RAM 时)。 此外,还有一些贡献可以对需要大量内存的函数(如 sort、groupby 和 join 函数)进行可选控制和限制内存使用。 InfluxDB IOx 开发人员还贡献了额外的 SQL 功能。 例如
-
帮助重写 Parquet 读取器,该读取器可以从对象存储中读取数千个文件
-
支持近似百分位数(中位数):(apache/arrow-datafusion#1539)。
-
常量表达式求值:(arrow-datafusion#1153)。
-
排序保留合并:(apache/arrow-datafusion#379)。
技术写作贡献
一些技术写作贡献包括
DataFusion 教育和推广
-
DataFusion 和 Arrow:使用 Rusty 查询引擎为您的数据分析工具增压 - Data + AI Summit 2022 - Databricks
-
UCS 数据库系统实现 演讲:Apache Arrow 及其对数据库行业的影响。
-
The Data Thread 2022:Apache Arrow 和 DataFusion:改变数据库系统实施的游戏规则.
与 IOx 开发人员联系并获取更多资源
要充分利用 InfluxDB IOx 的所有进步,请在此处注册 here。
如果您想联系 InfluxDB IOx 开发人员,请加入 InfluxData 社区 Slack 并查找 #influxdb_iox 频道。 我鼓励您参加每月一次的技术讲座和社区办公时间,该项目在每月第二个星期三太平洋时间上午 8:30 举行。 要了解更多信息,请在该频道留言。
查看以下关于 InfluxDB IOx 的内容以了解更多信息
我希望这篇博文能激励您探索 InfluxDB IOx。 如果您需要任何帮助,请使用我们的 社区网站 或 Slack 频道与我们联系。 我很乐意了解您尝试实现的目标以及您希望 InfluxDB 中的任务系统具有哪些功能。
最后,如果您正在 InfluxDB 之上开发一个很酷的 IoT 应用程序,我们很乐意了解它,因此请务必在社交媒体上使用 #InfluxDB 分享它!
请随时在我们的社区 slack 频道中直接与我联系,分享您的想法、疑虑或问题。 我很乐意收到您的反馈并帮助您解决遇到的任何问题! 或者 分享您的故事 并获得免费的 InfluxDB 连帽衫。