16.1.4 对象容器文件
序列化后的数据需要存入文件中。Avro包含一个简单的对象容器文件,一个文件拥有一个模式,文件中所有存储的对象必须根据模式使用二进制编码写入。对象存储在可以压缩的块中,块之间使用同步机制为MapReduce处理提供高效的文件分离。文件中可能包含用户随意指定的元数据。那么一个文件包含:
文件头。
一个或多个文件数据块。
其中文件头包含:
4个字节,分别是ASCII码的o、b、j、1。
包含模式的文件元数据。
为此文件随机生成的16字节同步器。
文件的元数据包含:
指示元数据的一个键/值对的长整型。
每个对的字符串键和字节值。
所有以"Avro"开头的元数据属性是保留的,以下文件元属性主要用于:
avro. schema,包含存储在文件中对象的模式,如JSON数据(必须)。
avro. codec,编解码器名称,其编码器用来压缩诸如字符串的数据块。需要实现支持"null"和"deflate"编解码器,如果没有编解码器,那假设为"null"。
"null"编解码器不需要对数据解压缩,而"deflate"编解码器使用文档RFC1951中指定的deflate算法写入数据块并使用zlib库实现,要注意的是这个格式(不像RFC1950中的zlib格式)没有校验和。
一个文件头需要按照如下模式进行描述:
{"type":"record","name":"org.apache.avro.file.Header",
"fields":[
{"name":"magic","type":{"type":"fixed","name":"Magic","size":4}},
{"name":"meta","type":{"type":"map","values":"bytes"}},
{"name":"sync","type":{"type":"fixed","name":"Sync","size":16}},
]
}
文件数据块包括:
一个长整型,用于指示块中对象数目。
一个长整型,用于表示使用编解码器后,所在块中序列化对象的字节大小。
序列化对象,如果编解码器是指定的,则用它进行压缩。
16字节的文件同步器。
这样,即使不用反序列化,每个块的二进制数据也可以高效获得或跳过。这种块的大小、对象数目和同步器的结合可以检测出坏的块并且帮助保持数据的完整性。
图16-3表示了对象容器文件的具体格式。
图 16-3 对象容器文件的具体格式