AVRO了解
Avro是一个数据序列化系统,设计用于支持大批量数据交换的应用。
它的主要特点有:支持二进制序列化方式,可以便捷,快速地处理大量数据;动态语言友好,Avro提供的机制使动态语言可以方便地处理Avro数据。
当前市场上有很多类似的序列化系统,如Google的Protocol Buffers, Facebook的Thrift。这些系统反响良好,完全可以满足普通应用的需求。针对重复开发的疑惑,Doug Cutting撰文解释道:Hadoop现存的RPC系统遇到一些问题,如性能瓶颈(当前采用IPC系统,它使用Java自带的DataOutputStream和DataInputStream);需要服务器端和客户端必须运行相同版本的Hadoop;只能使用Java开发等。但现存的这些序列化系统自身也有毛病,以Protocol Buffers为例,它需要用户先定义数据结构,然后根据这个数据结构生成代码,再组装数据。如果需要操作多个数据源的数据集,那么需要定义多套数据结构并重复执行多次上面的流程,这样就不能对任意数据集做统一处理。其次,对于Hadoop中Hive和Pig这样的脚本系统来说,使用代码生成是不合理的。并且Protocol Buffers在序列化时考虑到数据定义与数据可能不完全匹配,在数据中添加注解,这会让数据变得庞大并拖慢处理速度。其它序列化系统有如Protocol Buffers类似的问题。所以为了Hadoop的前途考虑,Doug Cutting主导开发一套全新的序列化系统,这就是Avro,于09年加入Hadoop项目族中。
Avro所提供的属性:
1.丰富的数据结构
2.使用快速的压缩二进制数据格式
3.提供容器文件用于持久化数据
4.远程过程调用RPC
5.简单的动态语言结合功能,Avro 和动态语言结合后,读写数据文件和使用 RPC 协议都不需要生成代码,而代码生成作为一种可选的优化只值得在静态类型语言中实现。
Avro的Schema
Avro的Schema用JSON表示。Schema定义了简单数据类型和复杂数据类型。
基本类型
其中简单数据类型有以下8种:
类型 | 含义 |
---|---|
null | 没有值 |
boolean | 布尔值 |
int | 32位有符号整数 |
long | 64位有符号整数 |
float | 单精度(32位)的IEEE 754浮点数 |
double | 双精度(64位)的IEEE 754浮点数 |
bytes | 8位无符号字节序列 |
string | 字符串 |
基本类型没有属性,基本类型的名字也就是类型的名字,比如:
{"type": "string"}
复杂类型
Avro提供了6种复杂类型。分别是Record,Enum,Array,Map,Union和Fixed。
Record
Record类型使用的类型名字是 “record”,还支持其它属性的设置:
name:record类型的名字(必填)
namespace:命名空间(可选)
doc:这个类型的文档说明(可选)
aliases:record类型的别名,是个字符串数组(可选)
fields:record类型中的字段,是个对象数组(必填)。每个字段需要以下属性:
- name:字段名字(必填)
- doc:字段说明文档(可选)
- type:一个schema的json对象或者一个类型名字(必填)
- default:默认值(可选)
- order:排序(可选),只有3个值ascending(默认),descending或ignore
- aliases:别名,字符串数组(可选)
一个Record类型例子,定义一个元素类型是Long的链表:
schema文件,用json类型表示。
{
"type": "record",
"name": "RunRecord",
"namespace": "com.hainiu",
"fields": [{
"name": "word",
"type": "string"
}, {
"name": "num",
"type": "long"
}
]
}
# 转换DDL
create table com.hainiu.RunRecord(
word string,
num bigint
)
--将schema文件放到指定的hdfs目录上面
--根据avro.schema.url 对应的目录下的schema文件,创建与文件格式相对应的表结构
CREATE EXTERNAL TABLE IF NOT EXISTS word_avro
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.avro.AvroSerDe'
WITH SERDEPROPERTIES ('avro.schema.url'='/user/suniu/hive/config/schema.avsc')
STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat'
LOCATION '/user/suniu/hive/word_avro';
CREATE TABLE IF NOT EXISTS word_avro
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.avro.AvroSerDe'
WITH SERDEPROPERTIES ('avro.schema.url'='/user/suniu/avroconf/myavro.avsc')
STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat';
导入数据:
insert overwrite table word_avro select word,num from ext_test;
查看导入表的数据文件
如何给avro表增加字段?
1)修改schema文件,给添加新的字段,并给字段设置默认值;如果不给默认值,查询时报错,因为老数据的新加字段没有默认值
然后通过insert into table select 方式插入数据
insert into table word_avro select word,count,1 from ext_test;
如果普通表,想新加字段,只能把字段放到最后面,不能调整字段的顺序,但avro是可以的。
总结:
如果新增字段,需要给新增字段设置默认值,否则查询会报错。
优点:后续数据的字段扩展不影响以前表的使用,或者后续表的修改不影响读取以前的数据。
缺点:做在数据里面存在冗余的数据,会使数据的文件变的很大。
应用场景:最原始的etl数据使用,因为最原始的数据经常变动结果。使用这种数据格式不受影响。