原始互联网对象符号 (RION) 是一种快速、紧凑、多功能的数据格式。是的,我知道你在想什么:”还有另一种数据格式。这与CSV、XML、JSON、YAML、ProtoBuf、消息包、CBOR、亚马逊的ION、ApacheAvro或ASN.1有什么不同? 请稍等,我将在本文中解释这一点,但首先我必须提供一些关于 RION 的背景信息。
用于高效交换和存储数据的数据格式
RION是由Nanosai开发的,一家分布式系统研发公司(我是该公司的联合创始人)作为”开放标准”——这意味着欢迎大家使用它。RION 最初设计为用于高效数据交换的数据格式。但是,我们自扩展了目标用例,以包括结构化数据的有效存储。
我们相信用例密切相关,这种扩展是有意义的。这两种用例之间的主要区别是,通过网络发送的消息往往具有固定大小(至少一次发送),而文件可能会随着时间的推移而合理预期增长。
实际上,我们使用 RION 作为网络协议的消息编码,以及数据流存储引擎中的记录格式,因此,对于数据交换和数据存储,我们都有经过压力测试的 RION。
多功能数据格式
从一开始,我们希望使RION尽可能的通用性,这意味着它应该能够编码各种各样的结构化数据。希望借助更通用的数据格式,开发人员不必经常在不同的数据格式之间切换。我们越是能够默认使用 RION,情况就越好。
显然,没有数据格式是完美的每种类型的数据。对于某些用例,如音频、视频、强格式文档等特定于域的编码,如 MP3、MP4 或 PDF 可能更合适。为了适应这种情况,RION 旨在能够将二进制数据与其他结构化数据(例如元数据)一起嵌入。
RION 还旨在使您能够在内置数据类型不足的情况下使用自定义数据类型扩展它。
您可能还喜欢:
使用ApacheSpark数据框架处理表格数据。
支持的数据结构
要真正多才多艺,RION 必须能够代表各种数据结构。目前,RION 使您能够表示:
-
二进制数据。
-
键入的数据字段(布尔、int、float、文本、日期时间)。
-
单个字段。
-
无界字段流
表格数据(如 CSV 文件,其中列名称仅包含一次)。
对象和贴图(键值对)。
对象图(具有嵌套对象的对象)。
这些数据结构可以组合起来以创建更高级的结构。例如,您可以有一个表中嵌套其他表,或者一个表中嵌套了对象图形,其中可能还有表,等等。
字段类型
RION 编码的数据由一个或多个 RION 字段组成。每个 RION 字段都有一个类型。RION 当前包含以下字段类型:
-
字节。
-
布尔。
-
Int-Pos.
-
因特-内格。
-
浮动(32 或 64 位)。
-
UTF-8.
-
UTF-8 短。
-
Utc。
-
(参考)。
-
数组(*)。
-
表。
-
对象。
-
关键。
-
键短路。
-
扩展。
让我详细阐述一下这些字段类型。
字节字段用于”非结构化”二进制数据。例如,如果需要在 RION 中嵌入音频或视频文件(或任何其他类型的文件或二进制数据),则可以将其嵌入字节字段中。这允许有效地传输二进制数据。
布尔字段可以表示值为 true 和 false。
Int-Pos 和 Int-Neg 字段表示正数和负整数。正整数是编码的,因此它们仅包含重要的字节。因此,包含数字 127 的 Int-Pos 字段可以使用 2 个字节表示,使用 3 个字节表示 1024,等等。另一方面,负数更具挑战性。
例如,32 位负整数需要 4 个字节,因为所有字节都很大。为了更有效地编码负数,我们创建了一个负整数字段,其中包含负整数的绝对(正)值 – 负 1。这使我们能够使用与正整数相同的高效”有效字节”编码。
浮点可以是 32 位或 64 位浮点数。
UTF-8 和 UTF-8 短用于以 UTF-8 格式存储的文本数据。UTF-8 Short 可以编码 15 字节或更少的文本,使用比 UTF-8 字段少 1 个字节。在具有许多文本字段的数据中,每个字段保存的 1 个字节可能很重要。
UTC 用于以 UTC 存储数据和时间。通过网络交换日期时间信息是一个常见的用例,因此我们认为 RION 应该支持这一点。为了避免时区混淆,我们决定”强制”将日期时间字段表示为 UTC 时间它旨在表示对 RION 数据中较早的 RION 字段的”反向引用”。这可用于表示循环对象图。这还可用于避免在 RDBMS 结果集或微服务查询响应中重复冗余信息。我们可能会添加其他字段,用于表示将来的冗余数据的副本(例如,复制字段)。
数组字段用于表示 RION 字段的数组(列表)。因此,RION 数组可以包含嵌套在其中的其他 RION 字段。因此,数组字段是复合字段。请注意,我们意识到可以将数组表示为具有单个列的表,因此,我们实际上可以删除 Array 字段,并且只具有数组和表格数据的表字段。
“表”字段用于表示列和行的表格数据,如 CSV 文件或针对关系数据库的 SQL 查询结果。为了有效地对表格数据进行编码,表只包含行的列名称(键字段)。列名称后,列值行后。这类似于 CSV 文件,其中第一行是列标题,后续行是每行的列值。具有单个列的表可用于表示 Array,因此,我们可以删除前面提到的 Array 字段。表可以包含嵌套在其中的其他 RION 字段。因此,也可以使用具有嵌套表的表来更有效地表示树结构。
“对象”字段用于表示键值对的对象或映射(字典)。通常,键值对将编码为 Key 字段,后跟一些其他字段,但如果需要,可以保留键(或值 – 如果使用情况有意义)。您可以在对象(包括数组或表字段)内嵌套其他 RION 字段,以表示所需的对象图。到目前为止,您只能表示不循环对象图,但一旦我们完成了参考字段的规范,您也可以表示循环对象图。
扩展字段类型旨在允许您指定自己的字段类型,因此可以使用核心 RION 字段类型嵌入其他类型的数据。
压 实 度
为了有效地交换和存储,紧凑性对于 RION 至关重要。因此,我们竭尽全力使 RION 编码尽可能紧凑。有时,为了达到其他设计目标(如高读取速度),我们不得不做出一些妥协,但在大多数情况下,RION 相当紧凑。
速度
我们为 RION 的另一个目标是使其快速读取和写入。每当必须在读取速度和写入速度之间进行权衡时,我们倾向于读取速度,因为我们期望数据读取的频率高于写入频率。例如,RION 文件可能写入一次,之后会多次读取。网络消息也是如此。它们被写入一次,然后在传输和处理过程中读取一次或多次这本身就使得它的读写速度比XML、JSON和YAML等文本编码更快,并且与MessagePack、CBOR和亚马逊的ION一样。
此外,RION 设计为直接以二进制形式使用。当直接以二进制形式读取而不是首先反序列化到 Java 对象时,我们已经看到简单用例的加速 10 倍。对于更高级的用例,加速可以更大和更小。
此外,RION 旨在允许部分可解析性和任意分层导航。通常,在特定情况下,服务返回的数据可能比给定客户端需要的数据多。RION 无需分析返回的所有数据,而是使您能够高效地浏览不需要到达所需部分的部分。为此,您可以浏览 RION 数据的二进制形式,并分析所需的字段,跳过其余字段。
二进制编码
为了实现紧凑和速度,RION 使用二进制编码。与文本编码相比,二进制编码可实现对数字、日期和二进制数据的更紧凑的编码。
对二进制编码的常见异议之一是,在开发、调试、监视等过程中,人类很难阅读它们。为了解决这一问题,我们目前正在研究 RION 的文本编码(到目前为止称为 TION),因此您可以将 RION 转换为 TION 和返回,以便在文本编辑器中轻松阅读和编辑。TION 并非 100% 就绪,但我预计将在 2020 年的某个时候。我们还实现了一个 RION 到”格式化十六进制表示法”转换器,从而可以在文本编辑器中检查原始字节值。
自我描述
RION 使用自描述编码,这意味着您不需要架构来理解 RION 数据块。将数据格式自描述使使用起来更容易,因为您可以在不知道其架构的情况下浏览数据以查看其结构。这还使得为不知道消息架构的中间节点路由消息变得更加容易。
即使数据格式是自描述的,将其与架构组合仍然有意义。XML + XML 架构和 JSON = 斯瓦格/RAML 就是这种情况。架构可以提供有关给定字段允许的值、预期字段等的其他限制。RION目前没有任何架构机制,但它正在考虑中,
更多设计目标
为了缩短 RION 的这篇介绍性文章,我留下了一些”不太重要”的 RION 设计目标。您可以在此处查看 RION 设计目标的完整列表:
http://tutorials.jenkov.com/rion/rion-design-goals.html
RION vs. 其他数据格式
在本节中,我将尝试为您提供 RION 与当前使用的许多其他常用数据格式的简要概述因此,在本文中,我可以进入的细节深度是有限度的。
首先,作为二进制数据格式将 RION 与 CSV、XML、JSON 和 YAML 分开。二进制意味着 RION 通常比这些格式更紧凑,读写速度更快。平均而言,RION 比 JSON 紧凑约 10% 到 33%,如果用于表格数据,差异可能超过 50%。这种紧凑性差异也转化为类似的读/写速度差异。
文本数据格式的优点是更易于在文本编辑器中读取和编辑,但我们打算通过具有 RION (TION) 的文本表示形式来解决这一问题,您可以将其转换为 RION 并从 RION。这应该会降低人的可见性/可编辑性问题。
RION 可以在文件的根级别包含多个字段。这使得 RION 与 XML 和 JSON 不同,后者只能在文件的根级别包含单个元素。这使得 RION 更易于用于流数据结构,如日志文件和连续追加的数据文件。
RION 使用类似于 MessagePack、CBOR 和 Amazon ION 的自描述二进制编码。然而,RION在几个微妙但重要的方面是不同的。首先,RION 是其中唯一一种用于指定表格数据高效编码的数据格式。其次,在导航复合数据结构(如对象图)时,RION 稍微更容易以二进制形式任意导航。第三,RION 将很快能够表示循环对象图。目前,无论是消息包、CBOR 还是亚马逊的 ION 都不能做到这一点。
除此之外,RION 与 MessagePack、CBOR 和 Amazon 的 ION 一样紧凑,读取和写入速度大致相同,其中表格数据是 RION 擅长的例外。
ProtoBuf、ASN.1 和 Avro 都使用需要架构才能分析它们的数据编码。换句话说,它们不是自我描述的。在某些情况下,非自描述数据格式比自描述数据格式紧凑一些,但差异很小。但是,需要架构的数据格式处理起来可能比较麻烦,因此这是一种权衡。
有关更详细的概述,您可以看到我们自己的比较页面,我们会不时更新该页面。缺少一些数据格式,如亚马逊的 ION、YAML 和 XML,但我们最终将添加它们:
http://tutorials.jenkov.com/rion/rion-vs-other-formats.html.
从性能上看,我们的测量表明 RION 能够与 MessagePack 和 CBOR 的速度相匹配,同时接近 ProtoBuf 的速度。不过,我们所有的基准都基于序列化和反序列化对象。如果您直接使用 RION 的二进制形式,并且/或仅解析其中的部分,则可以大大提高速度。我们的基准有点老,所以我们需要尽快重新做jenkov.com/rion/rion-performance-benchmarks.html”rel=”nofollow”[http://教程.jenkov.com/rion/rion-性能基准.html
摘要和进一步详细信息
总之,我们相信 RION 是当今最好的全方位数据格式之一。它提供快速、高效的二进制编码、一组多功能且灵活的字段类型,旨在直接以二进制形式(速度)读取和写入,或用于序列化对象和从对象进行反序列化。在速度方面,它将匹配最流行的数据格式,甚至可以超过它们与表格数据格式,或者如果直接读取RION的二进制形式。
我们(Nanosai)花了相当长的时间分析RION并将其与其他数据格式进行比较,但我们相信当前的编码提供了一个良好的基础来扩展。我们仍然有几个角落要处理(如参考),但我们希望在2020年解决大多数问题。我们将再次发布,因为RION变得越来越完整。
我们使用 RION 作为网络协议 IAP 的消息编码,它是 HTTP 的替代,用于在应用层进行高效灵活的网络通信。IAP 仍在进行中,但基础知识已经明确定义。
我们还在 Java 的流操作中使用 RION 作为记录格式 – 我们的可嵌入数据流引擎。流行动就像一个”卡夫卡光”。目前,流运营正处于概念验证阶段,但我们希望在整个 2020 年改进它。
因为流操作使用 RION,我们可以实现一些相当不错的记录处理吞吐量速度。现在,我们已经能够将其压缩到每秒 1950 万条记录(小记录),这些记录位于开发人员笔记本电脑上。我们希望看到数据中心级硬件上的数字更高。长期而言,我们实际上是拍摄10亿记录每秒,你可以阅读我们的1BRS挑战。
目前,我们的RION开源工具包是在Java中实现的,但是一旦它们稳定下来,我们计划也扩展到其他语言。可能首先是性能语言,如 C#、C/C++,然后是 Python,因为它被大量用于数据科学。但这仍有待决定。
因此,如果您在市场上拥有快速、紧凑、多功能的全方位数据格式,无论您是在使用 Kafka、Pulsar、Hazelcast 等进行高性能微服务、数据科学、事件驱动架构,您都值得您看看 RION。
有关 RION 的更多信息
原始互联网对象符号 (RION) 是我们当前此数据格式的工作标题。我们从ION开始,但一年后亚马逊发布了一个名为ION的数据格式,他们一直在内部使用,所以我们切换到RION。将来我们可能会再次更改名称,但数据格式本身现在相当稳定。
对于那些对 RION 的所有详细信息感兴趣的人,请查看 RION 教程:
com/rion/index.html”rel=”nofollow”[http://教程.jenkov.com/rion/index.html
我们还正在开发一个开源工具包,用于在 Java 中使用 RION,称为 Rion Java 操作。您可以在此处找到 Java 的 RION 操作:
https://github.com/nanosai/rion-ops-java