Hadoop中的Avro文件格式
Apache Avro是Hadoop原生的数据序列化系统,它也是独立于语言的。 Apache Avro项目由Hadoop的创建者Doug Cutting创建,目的是提高Hadoop中的数据互操作性。提供了用于C,C ++,C#,Java,PHP,Python和Ruby的Avro实现,从而使在各种平台之间交换数据变得更加容易。
什么是数据序列化
此处要明确,数据序列化是一种将数据(类对象,数据结构)转换为字节流(二进制形式)的机制,以便跨网络发送或者持久存储在文件或者DB中。
Hadoop中的Avro
Hadoop中Avro的主要功能是
Avro与语言无关
它基于架构
为了定义Avro数据的结构,使用了与语言无关的模式。 Avro模式是使用JSON定义的,可帮助实现数据互操作性。
在Avro中使用架构的一些好处是
对于语言互操作性,因为架构是使用JSON定义的。
我们可以将Avro模式保存在扩展名为.avsc的单独文件中。
它允许模式的演变。我们可以添加或者删除列。
使用Avro,我们可以执行序列化和反序列化,而无需生成代码。由于Avro中的数据始终与相应的模式一起存储,因此无论我们是否提前知道模式,都可以始终读取序列化的项目。
Avro文件格式
Avro包含一种简单的对象容器文件格式。文件具有模式,并且必须使用二进制编码根据该模式写入文件中存储的所有对象。对象存储在可以压缩的块中。块之间使用同步标记,以允许有效分割文件以进行MapReduce处理。
Avro文件包括:
文件头
一个或者多个文件数据块。
标题 | 数据块 | 数据块 |
文件头包括:
四个字节,ASCII码" O"," b"," j",后跟1.
包含架构的文件元数据。还包含有关用于压缩块的压缩编解码器的信息。
此文件的16字节随机生成的同步标记。
文件数据块包括:
一个长整数,指示此块中的对象数。
一个长整数,指示在应用任何编解码器后当前块中序列化对象的大小(以字节为单位)。
序列化的对象。如果指定了编解码器,则由该编解码器压缩。
文件的16字节同步标记。
Avro中的架构声明
Schema由JSON之一表示:
JSON字符串,命名已定义的类型。
JSON对象,其形式为:{" type":" typeName"…attributes ...},其中typeName是基元或者派生类型名称,如下所示。允许将本文档中未定义的属性用作元数据,但不得影响序列化数据的格式。
JSON数组,表示嵌入式类型的并集。
Avro中的基本类型
基本类型名称的集合是:
null:没有值
boolean:布尔值,二进制值
int:32位有符号整数
long:64位有符号整数
float:单精度(32位)IEEE 754浮点数
double:双精度(64位)IEEE 754浮点数
bytes:8位无符号字节序列
string:unicode字符序列
基本类型没有指定的属性。
基本类型名称也是定义的类型名称。因此,例如,架构"字符串"等效于:
{"类型":"字符串"}
Avro中的复杂类型
Avro支持六种复杂类型:记录,枚举,数组,映射,联合和固定类型。
记录–记录使用类型名称"记录"并支持以下属性:
name:提供记录名称的JSON字符串(必需)。
名称空间,一个限定名称的JSON字符串;
doc:一个JSON字符串,向该模式的用户提供文档(可选)。
别名:字符串的JSON数组,为该记录提供备用名称(可选)。
字段:一个JSON数组,列出字段(必填)。每个字段都是具有以下属性的JSON对象:
例如,员工记录的架构:
{ "type": "record", "name": "EmployeeRecord", "doc": "Employee Record", "fields": [ {"name": "empId", "type": "int"}, {"name": "empName", "type": "string"}, {"name": "age", "type": "int"} ] }
枚举–枚举使用类型名称"枚举"并支持以下属性:
name:提供枚举名称的JSON字符串(必需)。
名称空间,一个限定名称的JSON字符串;
别名:字符串的JSON数组,为该枚举提供备用名称(可选)。
doc:一个JSON字符串,向该模式的用户提供文档(可选)。
symbol:一个JSON数组,以JSON字符串形式列出符号(必填)。枚举中的所有符号都必须是唯一的;禁止重复。每个符号都必须匹配正则表达式 [A-Za-z_][A-Za-z0-9_]* (与名称的要求相同)。
例如,使用枚举声明星期几:
{ "type": "enum", "name": "WeekDays", "symbols" : ["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"] }
数组–数组使用类型名称"数组"并支持单个属性:
items:阵列项目的架构。
例如,声明一个字符串数组:
{"type": "array", "items": "string"}
地图–地图使用类型名称"地图"并支持一种属性:
values:地图值的架构。
映射键假定为字符串。
例如,从字符串到long的映射声明为:
{"type": "map", "values": "long"}
union –联合使用JSON数组表示,并且数组中的每个元素都是一个架构。例如,[" null"," string"]声明了可以为null或者字符串的架构。确认联合模式的数据必须与联合中的模式之一匹配。
固定-固定使用类型名称"固定"并支持两个属性:
名称:命名为固定值的字符串(必填)。
名称空间,一个限定名称的字符串;
别名:字符串的JSON数组,为该枚举提供备用名称(可选)。
size:整数,指定每个值的字节数(必填)。
例如,声明一个16字节的数量:
{"type": "fixed", "size": 16, "name": "md5"}