Hadoop中的Avro文件格式

时间:2020-01-09 10:34:36  来源:igfitidea点击:

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"}