RION-一种快速,紧凑,通用的数据格式

原始Internet对象符号(RION)是一种快速,紧凑,通用的数据格式。是的,我知道您在想什么:“还有另一种数据格式。” 这与CSV,XML,JSON,YAML,ProtoBuf,MessagePack,CBOR,Amazon的ION,Apache Avro或ASN.1有​​何不同?继续,我将在整个文章中对此进行解释,但是首先,我将提供一些有关RION的背景信息。

一种有效交换和存储数据的数据格式

RION由Nanosai(一家分布式系统研发公司(我是联合创始人))开发为“开放标准”,这意味着欢迎所有人使用它。RION最初被设计为用于高效数据交换的数据格式。但是,自那时以来,我们已将目标用例扩展到包括结构化数据的有效存储。

我们相信用例之间的联系紧密,以至于这种扩展是有意义的。这两种用例之间的主要区别在于,通过网络发送的消息往往具有固定的大小(至少一次发送),而随着时间的推移,文件可能会不断增长。

实际上,我们将RION既用作网络协议的消息编码,又用作数据流存储引擎中的记录格式,因此我们对RION进行了压力测试,以进行数据交换和数据存储。

多种数据格式

从一开始,我们就希望使RION尽可能地通用,这意味着它应该能够对各种各样的结构化数据进行编码。希望是,有了更通用的数据格式,开发人员将不必经常在不同的数据格式之间切换。我们越常能够默认为RION,就越好。

显然,没有一种数据格式适合每种类型的数据。对于某些用例,例如音频,视频,强格式文档等,特定于域的编码(例如MP3,MP4或PDF)可能更合适。为了适应这种情况,RION被设计为能够将二进制数据与其他结构化数据(例如,元数据)一起嵌入。

RION的设计还使您可以在内置数据类型不足的情况下使用自定义数据类型扩展它。

支持的数据结构

为了实现真正的通用性,RION必须能够代表各种各样的数据结构。目前,RION使您能够代表:

二进制数据。键入的数据字段(布尔值,整数,浮点数,文本,日期时间)。单个字段。无限的字段流。有界的列表(数组)。表格数据(例如CSV文件,其中列名仅包含一次)。对象和映射(键值对)。对象图(带有嵌套对象的对象)。

这些数据结构可以组合以创建更高级的结构。例如,您可以将一个表与其他表嵌套在其中,或者将一个表与对象图嵌套在其中,又可以在其中嵌套表,等等。

栏位类型

RION编码的数据由一个或多个RION字段组成。每个RION字段都有一个类型。RION当前包含以下字段类型:

Bytes.Boolean.Int-Pos.Int-Neg.Float (32 or 64 bit).UTF-8.UTF-8 Short.UTC.(Reference).Array(*).Table.Object.Key.Key Short.Extended.

让我详细介绍一下这些字段类型。

字节字段用于“非结构化”二进制数据。例如,如果您需要在RION中嵌入音频或视频文件(或任何其他类型的文件或二进制数据),则可以将其嵌入到Bytes字段中。这允许有效地传输二进制数据。

布尔字段可以表示值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短代码可以编码15个字节或更少的文本,使用的字符数比UTF-8字段少1个字节。在具有许多文本字段的数据中,每个字段节省的那1个字节可能很重要。

UTC用于在UTC中存储数据和时间。通过网络交换日期时间信息是一个常见的用例,因此我们认为RION应该支持这一点。为避免时区混乱,我们决定“强制”日期时间字段表示为UTC时间。

到目前为止,“参考”字段仅处于构思阶段。它旨在表示对RION数据中较早发现的RION字段的“反向引用”。这可以用来表示循环对象图。这也可用于避免在RDBMS结果集或微服务查询响应中重复冗余信息。我们将来可能会添加其他字段来表示冗余数据的副本(例如,“副本”字段)。

数组字段用于表示RION字段的数组(列表)。因此,RION阵列可以包含嵌套在其中的其他RION字段。因此,数组字段是一个复合字段。请注意,我们已经意识到可以将数组表示为具有单列的表,因此我们实际上可能会删除Array字段,而只有Table字段用于数组和表格数据。

“表”字段用于表示列和行的表格数据,例如CSV文件或针对关系数据库的SQL查询结果。为了有效地对表格数据进行编码,表仅包含一次行的列名(键字段)。列名称之后是列值的行。这类似于CSV文件,其中第一行是列标题,随后的行是每一行的列值。具有单列的表可用于表示Array,因此我们可以删除前面提到的Array字段。表可以包含嵌套在其中的其他RION字段。因此,您也可以使用带有嵌套表的表来更有效地表示树结构。

“对象”字段用于表示键值对的对象或地图(字典)。通常,键/值对将被编码为“键”字段,后跟其他一些字段,但是您可以根据需要省略键(或者也可以省略值-如果在您的用例中有意义)。您可以将其他RION字段嵌套在一个对象中,包括数组或表字段,以表示所需的对象图。到目前为止,您只能表示非循环对象图,但是一旦完成“参考”字段的说明,您也可以表示循环对象图。

扩展字段类型旨在使您能够指定自己的字段类型,因此,您可以嵌入其他类型的数据,而对于核心RION字段类型则无法嵌入。

紧凑

为了有效地交换和存储,紧凑对于RION至关重要。因此,我们竭尽全力使RION编码尽可能紧凑。有时,为了达到其他设计目标(例如较高的读取速度),我们不得不做出一些折衷,但是RION在很大程度上是相当紧凑的。

速度

RION的另一个目标是提高读写速度。每当必须在读取速度和写入速度之间进行权衡时,我们都倾向于读取速度,因为我们希望读取数据的频率要比写入数据的频率高。例如,一个RION文件可能被写入一次,然后被读取多次。网络消息也是如此。它们只被写入一次,然后在传输过程中和处理过程中被读取一次或多次。

RION使用紧凑的二进制编码。与XML,JSON和YAML之类的文本编码相比,它本身使读写速度更快,并且与MessagePack,CBOR和Amazon的ION相当。

此外,RION被设计为直接以其二进制形式使用。当直接以其二进制形式读取而不是首先反序列化为Java对象时,对于简单的用例,我们已经看到了10倍的加速。对于更高级的用例,提速可以更大或更小。

此外,RION设计为允许部分可解析性和任意层次导航。通常,在特定情况下,服务返回的数据可能超过给定客户端所需的数据。通过RION,您不必解析所有返回的数据,就可以高效地浏览不需要的部分,以找到所需的部分。您可以通过以二进制格式浏览RION数据并解析出所需的字段,而跳过其余字段来做到这一点。

二进制编码

为了能够实现紧凑性和速度,RION使用二进制编码。与文本编码相比,二进制编码使数字,日期和二进制数据的编码更加紧凑。

二进制编码的普遍反对意见之一是,在开发,调试,监视等过程中,人类很难阅读它们。为解决此问题,我们目前正在研究RION的文本编码(到目前为止称为TION),因此您可以将RION转换为TION并返回,以便在文本编辑器中轻松阅读和编辑。TION尚未100%准备就绪,但我预计它将在2020年某个时候实现。我们还实现了RION到“格式化的十六进制表示法”转换器,可以在文本编辑器中检查原始字节值。

自我描述

RION使用自我描述的编码,这意味着您不需要架构即可理解RION数据块。使数据格式具有自描述性,可以更轻松地使用它,因为您可以在不了解其模式的情况下浏览数据以查看其结构。这也使得更容易为不知道消息架构的中间节点路由消息。

即使数据格式是自描述的,将其与模式组合仍然有意义。XML + XML Schema和JSON + Swagger / RAML就是这种情况。模式可以对给定字段允许使用哪些值,期望使用哪些字段等提供其他限制。RION目前没有任何模式机制,但正在考虑中,

更多设计目标

为了使RION的这篇介绍性文章简短,我为RION保留了一些“不太重要”的设计目标。您可以在此处查看RION的设计目标的完整列表:

http://tutorials.jenkov.com/rion/rion-design-goals.html

RION与其他数据格式

在本节中,我将尝试向您快速概述RION与当今使用的许多其他流行数据格式的不同之处。但是请记住,完整的概述需要深入了解数据格式。因此,本文的详细信息深度是有限的。

首先,作为二进制数据格式,RION不同于CSV,XML,JSON和YAML。使用二进制表示RION通常比这些格式更紧凑,并且读写速度更快。平均而言,RION比JSON紧凑约10%到33%,如果用于表格数据,则差异可以超过50%。这种紧凑性差异还转化为相似的读/写速度差异。

文本数据格式确实具有在文本编辑器中更易于阅读和编辑的优点,但是我们打算通过使用RION(TION)的文本表示来解决此问题,您可以将其转换为RION和从RION进行转换。这将减少人类可见性/可编辑性问题。

RION可以在文件的根级别包含多个字段。这使RION与XML和JSON区别开来,XML和JSON在文件的根级别只能包含一个元素。这使RION更易于用于流数据结构,例如日志文件和连续追加的数据文件。

RION使用类似于MessagePack,CBOR和Amazon的ION的自描述二进制编码。但是,RION在一些微妙但重要的方面有所不同。首先,RION是这些数据格式中唯一指定表格数据的有效编码的格式。其次,在导航诸如对象图之类的复合数据结构时,RION稍微容易以二进制形式进行任意导航。第三,RION很快将能够表示循环对象图。MessagePack,CBOR和Amazon的ION目前都无法做到这一点。

除此之外,RION与MessagePack,CBOR和Amazon的ION一样紧凑,并且读写速度几乎一样快,而表格数据是RION擅长的例外。

ProtoBuf,ASN.1和Avro都使用需要模式才能解析它们的数据编码。换句话说,它们不是自描述的。在某些情况下,非自描述数据格式可以比自描述数据格式更紧凑,但差异很小。需要模式的数据格式可能比较麻烦,因此这是一个折衷方案。