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數據使用,因爲最原始的數據經常變動結果。使用這種數據格式不受影響。