全文共5703字,预计学习时长17分钟
来源:Pexels
原始互联网对象符号(RION)是一种快速、紧凑、通用的数据格式。你可能会想:“又一个数据格式。”它和CSV、 XML、JSON、YAML、ProtoBuf、MessagePack、CBOR、亚马逊的ION、 ApacheAvro 或者ASN.1有什么不同呢?稍后我会在本文中解释清楚,但首先必须介绍一下RION的背景信息。
用于高效数据交换和数据存储的数据格式
RION由Nanosai研发,Nanosai是一家分布式系统研发公司,持“开放标准”——这意味着欢迎所有人使用。设计RION的最初目的是用于高效数据交换。然而现在扩展了目标用例,使其还包括结构化数据的高效存储。
相信这两个用例是紧密相关的,所以这个扩展是有意义的。它们的主要区别在于,通过网络发送的信息通常具有固定的大小(至少发送一次),而文件的大小可能会随时间推移而增长。
实际上,我们使用RION作为网络协议的消息编码和数据流存储引擎的记录格式。因此,我们对RION的数据交换和数据存储进行了压力测试。
通用的数据格式
从一开始,我们想使RION尽可能的通用化,这意味着可以对多种结构化数据进行编码。愿景在于,通过使用更加通用的数据格式,开发人员将无需经常在不同数据格式间转换。越经常地默认使用RION,就越好。
很明显,没有哪种数据格式能完美适用于所有数据类型。对于如视频、音频、强格式化文档等特定域的编码, MP3、MP4或PDF等格式可能更合适。为了适应这种情形,RION被设计为能够嵌入二进制数据和其他结构化数据(如元数据)。
RION的设计还允许在内置数据类型不足时通过自定义数据类型对其进行扩展。
来源:Pexels
支持的数据结构
要使RION真正通用,RION必须能表示各种各样的数据结构。目前,RION可以表示:
二进制数据
键入数据字段(布尔型、整型、浮点型、文本、日期时间)
单个字段
无界字段流
字段(数组)的有界列
表格数据(如CSV文件,只包含一次列名)
对象和映射(键-值对)
对象图(具有嵌套对象的对象)
可将这些数据结构组合起来以创造更高级的结构。例如,可以在表中嵌套表,或者在表中嵌套对象图,该表中也可以有表。
字段类型
RION编码的数据包含一个或多个RION字段。每个字段都有一个类型。目前,RION包含以下字段类型:
字节
布尔型
正整型
负整型
浮点型(32或64位)
UTF-8
短UTF-8
UTC
(参考)
数组(*)
表格
对象
键
短键
扩展
接下来对这些字段类型进行详细描述。
字节字段用于“非结构化”二进制数据。例如,如果需要在RION中嵌入音频或视频文件(或者任何其它类型的文件或二进制数据),可将其嵌入字节字段中。这样可以高效传输二进制数据。
布尔型字段可将值表示为true或false。
正整型和负整型表示正整数和负整数。正整型是编码的,只包含有效字节。因此,包含数字127的正整型字段可用2个字节表示,1024可用3个字节表示。另一方面,负数更具有挑战性。
例如,32位的负整型需要4个字节,因为所有字节都是有效的。为了更高效地对负数进行编码,我们创建了包含负整数的绝对(正)值-负1的负整型字段。这允许使用与处理正整数时相同高效的“有效字节”编码。
浮点型可以是32位或64位浮点数。
UTF-8或短UTF-8用于以UTF-8格式存储的文本数据。短UTF-8使用比UTF-8少1字节的文本来编码不高于15个字节的文本。在包含许多文本字段的数据中,每个字段节省的1个字节汇总起来可能非常之大。
UTC是以UTC的格式存储数据和时间。在网络上交换日期-时间信息是常规用例,所以我们认为RION也应该支持这一点。为避免时区紊乱,我们决定“强制”用UTC时间来表示日期时间字段。
截至目前,参考字段还停留在设想阶段。它旨在表示对RION数据中较早RION字段的“反向引用”。这可以用于表示循环对象图,也可避免在RDBMS结果集或微服务查询响应等中重复冗余信息。我们可能会添加其他字段,以表示未来的冗余数据的副本(如复制字段)。
数组字段用于表示RION字段的数组(列表)。因此,RION数组能包含嵌套其中的其它RION字段。所以数组字段是一个复合字段。请注意,可以把数组表示为具有单列的表,因此,实际上我们可以删除数组字段,只保留用于数组和表格数据的表字段。
表字段用于表示具有列和行的表格数据,如CSV文件或对相关数据库的SQL查询结果。为了高效地编码表格数据,表只包含行的列名称(键字段),列名后面是列值行。这与CSV文件相似,第一行是列标题,后续行是每一行的列值。单列的表可表示数组,因此可以像前面所提到的那样删除数组字段。表可以包含嵌套在其中的其它RION字段。因此,也可以使用具有嵌套表的表来更高效地表示树结构。
对象字段用于表示键值对的对象或映射(字典)。通常,键值对将被编码为键字段,后跟一些其它字段,但是如果需要,可以保留键(或值——如果这在你的用例中有意义)。可以在对象(包括数组或表字段)中嵌套其它RION字段,以表示需要的对象图。截至目前,只能表示非循环对象图,但若一旦完成了参考字段的规范,也能表示循环对象图。
扩展字段类型旨在能够指定自己的字段类型,因此除了核心的RION字段类型外,还能嵌入其它数据类型。
紧凑性
为了高效交换和存储,紧凑性对于RION至关重要。因此,我们已经尽最大努力使RION编码尽可能紧凑。有时为了实现其他设计目标如高读取速度,我们不得不做出一些妥协,但在大多数情况下RION还是很紧凑的。
速度
来源:Pexels
对于RION的另一个设计目标是加快读写速度。不论何时在读取速度和写入速度之间权衡时,我们都倾向于读取速度,因为我们期望数据的读取频率高于写入频率。例如,RION文件可能只写入一次,但要读取多次。这同样适用于网络消息,它们只写入一次,然后在传输处理过程中读取一次或多次。
RION使用紧凑的二进制编码,使其读写速度高于XML、JSON、YAML、MessagePack、CBOR以及亚马逊的ION等文本编码。
此外,RION直接以二进制形式使用。当直接以二进制形式读取而非先反序列化到Java对象时,简单用例的速度可加快10倍。对于更高级的用例,加速量不定,可能更大也可能更小。
另外,RION的设计允许部分可解析性和任意分层导航。在特定情境中,服务往往可能返回比给定客户端所需的更多数据。RION不必分析所有的返回数据,从而略过不需要的部分,以导航至需要的部分。也可以二进制形式浏览RION数据,分析出所需字段,略过其余字段。
二进制编码
为了实现高度紧凑性和高速度,RION使用二进制编码。比起文本编码,二进制编码能实现对数字、日期以及二进制数据更紧凑的编码。
对二进制编码常见的异议是,在开发、调试、监视等过程中,人们很难阅读它。为了解决这一问题,我们正在研究RION的文本编码(目前称其为TION),即可以将RION转换为TION并返回,以实现在文本编辑器中的轻松阅读和编辑。TION还未完全就绪,但预计将在2020年某个时间点完成。我们还实现了从RION到“格式化十六进制表示法”的转换器,使其可在文本编辑器中检查原始字节值。
自描述
RION使用自描述编码,意味着不需要架构来理解RION数据块。自描述的数据格式使其更容易使用,因为可以在不知道其架构的情况下通过浏览数据来查看结构。这也使得未知信息架构的中间节点发送信息变得更容易。
即使数据格式是自描述的,但将其与架构相结合仍然有意义。XML + XML架构和JSON + Swagger/RAML架构就是如此。架构可以对给定字段的允许值、预期字段等提供额外限制。目前的RION没有任何架构机制,但正在考虑之中。
更多设计目标
为使本文尽可能简短,我略去了一些“不太重要”的RION设计目标,可在这里查看完整版。
RION vs.其它数据格式
本节将简要讲述RION与今天所使用的其它流行数据格式的不同之处。不过,请记住,完整的概述需要对数据格式有深入的了解,因此本文所讲的细节深度有限。
首先,RION作为一种二进制数据格式,与CSV、XML、JSON以及YAML不同。二进制的RION意味着它比这些格式更紧凑且读写速度更快。平均来讲,RION的紧凑性比JSON高10%到33%,如果用于表格数据,其差异可超过50%。这种紧凑性差异也被转换为类似的读/写速度差异。
文本数据格式确实更易于在文本编辑器中读取和编辑,但是我们打算通过RION的文本表示(TION)来解决这个问题,使得RION和TION能相互转换。这应该可以减少人的可见性/可编辑性问题。
RION在文件的根级别包含多个字段,这将RION与XML、JSON区分开来,后两者只能在文件的根级别包含单个元素。这使得RION更易用于流数据结构,如日志文件和连续附加的数据文件。
RION使用类似于MessagePack、 CBOR以及亚马逊的ION的自描述二进制编码。然而,RION在一些细微且重要的地方与这三者不同。首先,在这些数据格式中,只有RION能指定表格数据的有效编码。其次,在浏览复合数据结构如对象图时,RION更容易以二进制形式进行任意浏览。第三,RION即将能表示循环对象图,而MessagePack、 CBOR或者亚马逊的ION目前都不能做到这一点。
此外, RION除了对表格数据更擅长这点较为突出外,与MessagePack、CBOR以及Amazon’s ION在紧凑性和读写速度方面都大致相同。
ProtoBuf、ASN.1和 Avro都使用需要架构来分析的数据编码。换句话说,它们不能自描述。某些情况下,非自描述数据格式比自描述数据格式更紧凑,但差别较小。但是需要架构的数据格式可能使用起来比较麻烦,所以这是一个折衷方案。
有关更详细的概述,请见“比较页面”,会有不时更新。其中缺失一些数据格式,包括亚马逊的ION、YAML、XML等,最后会添加上。
.
在性能方面,测量结果显示RION能与MessagePack和CBOR的速度相匹配,同时接近ProtoBuf的速度。但是所有的基准都基于序列化和反序列化对象。如果直接使用RION的二进制形式,并/或者只解析它的一部分,可以极大地提高速度。我们的基准有点老旧,因此需要尽快重做。点击链接可查看目前的基准:
总结和进一步的细节
来源:Pexels
总之,我们相信RION是目前最好的全方面数据格式之一。它提供了快速高效的二进制编码、通用灵活的字段类型集,可直接以二进制形式读取和写入(为了提高速度),或用于对象的序列化和反序列化。在速度方面,它能匹配大多数流行的数据格式,甚至能用表格数据格式超越它们,或者直接以二进制形式读取RION。
我们(Nanosai)已经花费大量时间分析RION并将其与其它数据格式做比较,但是我们相信当前的编码提供了一个很好的扩展基础。目前仍有一些地方需要处理(如参考),但是我们期望在2020年大多数问题能够得到解决。当RION变得越来越完整时,我们将再次发布推文。
我们目前正在使用RION作为网络协议IAP的消息编码,IAP是HTTP的替代物,用于在应用层实现高效灵活的网络通信。IAP仍在研究中,但其基础已经定义明确了。
我们还在Java的流操作中使用RION作为记录格式——可嵌入式数据流引擎。流操作就像一束“卡夫卡之光”。虽然目前还处于概念验证阶段,但是我们期望能在整个2020年度来改进它。
流操作使用RION,因此可以获得很好的记录处理吞吐速度。现在已经能在开发人员的笔记本电脑上将其压缩到每秒19.5万条记录(小记录)。希望能在数据中心级的硬件上看到更高的数字。从长远看,我们争取达到每秒10亿条记录,这可以在1BRS 挑战中看到。
目前,我们的RION开源工具包是在Java中实现的,一旦它们稳定下来,我们计划扩展到其它语言。首先可能是性能语言,如C#、C/C++,然后是Python,因为它被大量用于数据科学。但这仍待决定。
因此,如果你正在寻求一种快速、紧凑、通用的全方面数据格式,不论你是使用Kafka、Pulsar、Hazelcast等进行高性能微服务、数据科学还是事件驱动架构,都有必要去看看RION。
关于RION的更多信息
原始互联网对象符号(RION)是这种数据格式当前的工作标题。我们最开始使用的名字是ION,但是一年后,亚马逊发布了一款名为ION的内部使用的数据格式,所以我们改名为RION。将来可能会再次改名,但就目前来看,数据格式本身是十分稳定的。
来源:Pexels
如果你对RION的详细信息感兴趣,请查看RION教程。
我们还开发了一个名为“Rion Ops for Java”的开源工具包,用于在Java中使用RION。点击以下链接查看。
留言点赞关注
我们一起分享AI学习与发展的干货
如转载,请后台留言,遵守转载规范