Avro
简介
Apache Avro是一个数据序列化方法。
Avro提供:
- 丰富的数据结构。
- 紧凑、高效的二进制数据格式。
- 容器文件,用于存储持久数据。
- 远程过程调用(RPC)。
- 易于集成到动态语言的特性。
- 无论是读写数据文件,还是使用或实现RPC协议,都无需代码生成。代码生成是一个优化选项且只对静态类型语言的实现有意义。
Schema
schema是一种metadata(元数据,是用于描述数据的数据),用于描述avro数据;
schema通过JSON定义,下面是一个record类型的schema:
{
"type": "record",
"name": "test",
"fields" : [
{"name": "a", "type": "long"},
{"name": "b", "type": "string"}
]
}
解析avro数据(来自对象容器文件或序列化数据)时,必须根据数据的schema进行分析;
通常,schema和其描述的数据一起存放,例如:在avro支持的对象容器文件(Object Container File)中就在头部包含了文件中存储的数据的schema;在RPC应用中,通信双方也必须确保拥有对方所发送数据的schema。
Avro依赖于schema。当读取Avro数据时,总是能够获取到写入该数据时用到的schema。这样一来,每次写入数据都无需多余的开销,进而加快序列化速度、减小序列的大小。在动态的、脚本式语言中使用Avro也会变得更加容易,因为数据配合它的schema可以进行完整的自我描述。
当把Avro用于RPC时,客户端和服务器在连接握手时互换schema。(这一点还可以优化,对于大部分调用而言,实际上不会传输schema)。客户端和服务器都拥有对方的全部的schema,因此,在通信中的命名域、缺失域、附加域等都可以很容易被处理。
Avro与JSON的类型映射
Avro数据的序列化和反序列化
Avro指定两种序列化方法:
- 二进制:更小、更快,用于大部分应用中;
- JSON:易读,常用于调试和基于web的应用中;
序列化原则:深度优先、从左到右。
序列化之后的数据,可以通过反序列化而得到原数据(首先获取schema是必须的)。
同类比较
Thrift、Protocol Buffers等也提供了和Avro类似的功能。Avro区别于它们的主要方面如下:
- 动态类型:Avro不要求代码生成。数据总是和schema一起,无需代码生成和静态数据类型等就可以完整解析。这有助于在多种语言中构建通用的数据处理方法。
- 无标记数据:由于读取数据时总可以获取到schema,因此,极少的类型信息会被编码到数据中。这样使得序列化之后的大小更小。
- 无手动分配的域标识:当一个schema发生变化,处理数据时新的和旧的schema都可以获取到。所以,二者的差异使用域名即可解决。