小編給大家分享一下Hive中AVRO數(shù)據(jù)存儲格式的示例分析,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
薊州網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站建設(shè)等網(wǎng)站項目制作,到程序開發(fā),運營維護。創(chuàng)新互聯(lián)2013年開創(chuàng)至今到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。
Avro(讀音類似于[?vr?])是Hadoop的一個子項目,由Hadoop的創(chuàng)始人Doug Cutting(也是Lucene,Nutch等項目的創(chuàng)始人,膜拜)牽頭開發(fā),當(dāng)前最新版本1.3.3。Avro是一個數(shù)據(jù)序列化系統(tǒng),設(shè)計用于支持大批量數(shù)據(jù)交換的應(yīng)用。它的主要特點有:支持二進制序列化方式,可以便捷,快速地處理大量數(shù)據(jù);動態(tài)語言友好,Avro提供的機制使動態(tài)語言可以方便地處理Avro數(shù)據(jù)。
當(dāng)前市場上有很多類似的序列化系統(tǒng),如Google的Protocol Buffers, Facebook的Thrift。這些系統(tǒng)反響良好,完全可以滿足普通應(yīng)用的需求。針對重復(fù)開發(fā)的疑惑,Doug Cutting撰文解釋道:Hadoop現(xiàn)存的RPC系統(tǒng)遇到一些問題,如性能瓶頸(當(dāng)前采用IPC系統(tǒng),它使用Java自帶的DataOutputStream和DataInputStream);需要服務(wù)器端和客戶端必須運行相同版本的Hadoop;只能使用Java開發(fā)等。但現(xiàn)存的這些序列化系統(tǒng)自身也有毛病,以Protocol Buffers為例,它需要用戶先定義數(shù)據(jù)結(jié)構(gòu),然后根據(jù)這個數(shù)據(jù)結(jié)構(gòu)生成代碼,再組裝數(shù)據(jù)。如果需要操作多個數(shù)據(jù)源的數(shù)據(jù)集,那么需要定義多套數(shù)據(jù)結(jié)構(gòu)并重復(fù)執(zhí)行多次上面的流程,這樣就不能對任意數(shù)據(jù)集做統(tǒng)一處理。其次,對于Hadoop中Hive和Pig這樣的腳本系統(tǒng)來說,使用代碼生成是不合理的。并且Protocol Buffers在序列化時考慮到數(shù)據(jù)定義與數(shù)據(jù)可能不完全匹配,在數(shù)據(jù)中添加注解,這會讓數(shù)據(jù)變得龐大并拖慢處理速度。其它序列化系統(tǒng)有如Protocol Buffers類似的問題。所以為了Hadoop的前途考慮,Doug Cutting主導(dǎo)開發(fā)一套全新的序列化系統(tǒng),這就是Avro,于09年加入Hadoop項目族中。
上面通過與Protocol Buffers的對比,大致清楚了Avro的特長。下面著重關(guān)注Avro的細(xì)節(jié)部分。
Avro依賴模式(Schema)來實現(xiàn)數(shù)據(jù)結(jié)構(gòu)定義。可以把模式理解為Java的類,它定義每個實例的結(jié)構(gòu),可以包含哪些屬性??梢愿鶕?jù)類來產(chǎn)生任意多個實例對象。對實例序列化操作時必須需要知道它的基本結(jié)構(gòu),也就需要參考類的信息。這里,根據(jù)模式產(chǎn)生的Avro對象類似于類的實例對象。每次序列化/反序列化時都需要知道模式的具體結(jié)構(gòu)。所以,在Avro可用的一些場景下,如文件存儲或是網(wǎng)絡(luò)通信,都需要模式與數(shù)據(jù)同時存在。Avro數(shù)據(jù)以模式來讀和寫(文件或是網(wǎng)絡(luò)),并且寫入的數(shù)據(jù)都不需要加入其它標(biāo)識,這樣序列化時速度快且結(jié)果內(nèi)容少。由于程序可以直接根據(jù)模式來處理數(shù)據(jù),所以Avro更適合于腳本語言的發(fā)揮。 不是列存儲,而是一種序列化的方式而已。
Avro的模式主要由JSON對象來表示,它可能會有一些特定的屬性,用來描述某種類型(Type)的不同形式。Avro支持八種基本類型(Primitive Type)和六種混合類型(Complex Type)?;绢愋涂梢杂蒍SON字符串來表示。每種不同的混合類型有不同的屬性(Attribute)來定義,有些屬性是必須的,有些是可選的,如果需要的話,可以用JSON數(shù)組來存放多個JSON對象定義。在這幾種Avro定義的類型的支持下,可以由用戶來創(chuàng)造出豐富的數(shù)據(jù)結(jié)構(gòu)來,支持用戶紛繁復(fù)雜的數(shù)據(jù)。
Avro支持兩種序列化編碼方式:二進制編碼和JSON編碼。使用二進制編碼會高效序列化,并且序列化后得到的結(jié)果會比較??;而JSON一般用于調(diào)試系統(tǒng)或是基于WEB的應(yīng)用。對Avro數(shù)據(jù)序列化/反序列化時都需要對模式以深度優(yōu)先(Depth-First),從左到右(Left-to-Right)的遍歷順序來執(zhí)行?;绢愋偷男蛄谢菀捉鉀Q,混合類型的序列化會有很多不同規(guī)則。對于基本類型和混合類型的二進制編碼在文檔中規(guī)定,按照模式的解析順序依次排列字節(jié)。對于JSON編碼,聯(lián)合類型(Union Type)就與其它混合類型表現(xiàn)不一致。
Avro為了便于MapReduce的處理定義了一種容器文件格式(Container File Format)。這樣的文件中只能有一種模式,所有需要存入這個文件的對象都需要按照這種模式以二進制編碼的形式寫入。對象在文件中以塊(Block)來組織,并且這些對象都是可以被壓縮的。塊和塊之間會存在同步標(biāo)記符(Synchronization Marker),以便MapReduce方便地切割文件用于處理。下圖是根據(jù)文檔描述畫出的文件結(jié)構(gòu)圖:
上圖已經(jīng)對各塊做肢解操作,但還是有必要再詳細(xì)說明下。一個存儲文件由兩部分組成:頭信息(Header)和數(shù)據(jù)塊(Data Block)。而頭信息又由三部分構(gòu)成:四個字節(jié)的前綴(類似于Magic Number),文件Meta-data信息和隨機生成的16字節(jié)同步標(biāo)記符。這里的Meta-data信息讓人有些疑惑,它除了文件的模式外,還能包含什么。文檔中指出當(dāng)前Avro認(rèn)定的就兩個Meta-data:schema和codec。這里的codec表示對后面的文件數(shù)據(jù)塊(File Data Block)采用何種壓縮方式。Avro的實現(xiàn)都需要支持下面兩種壓縮方式:null(不壓縮)和deflate(使用Deflate算法壓縮數(shù)據(jù)塊)。除了文檔中認(rèn)定的兩種Meta-data,用戶還可以自定義適用于自己的Meta-data。這里用long型來表示有多少個Meta-data數(shù)據(jù)對,也是讓用戶在實際應(yīng)用中可以定義足夠的Meta-data信息。對于每對Meta-data信息,都有一個string型的key(需要以“avro.”為前綴)和二進制編碼后的value。對于文件中頭信息之后的每個數(shù)據(jù)塊,有這樣的結(jié)構(gòu):一個long值記錄當(dāng)前塊有多少個對象,一個long值用于記錄當(dāng)前塊經(jīng)過壓縮后的字節(jié)數(shù),真正的序列化對象和16字節(jié)長度的同步標(biāo)記符。由于對象可以組織成不同的塊,使用時就可以不經(jīng)過反序列化而對某個數(shù)據(jù)塊進行操作。還可以由數(shù)據(jù)塊數(shù),對象數(shù)和同步標(biāo)記符來定位損壞的塊以確保數(shù)據(jù)完整性。
上面是將Avro對象序列化到文件的操作。與之相應(yīng)的,Avro也被作為一種RPC框架來使用??蛻舳讼M?wù)器端交互時,就需要交換雙方通信的協(xié)議,它類似于模式,需要雙方來定義,在Avro中被稱為消息(Message)。通信雙方都必須保持這種協(xié)議,以便于解析從對方發(fā)送過來的數(shù)據(jù),這也就是傳說中的握手階段。
消息從客戶端發(fā)送到服務(wù)器端需要經(jīng)過傳輸層(Transport Layer),它發(fā)送消息并接收服務(wù)器端的響應(yīng)。到達傳輸層的數(shù)據(jù)就是二進制數(shù)據(jù)。通常以HTTP作為傳輸模型,數(shù)據(jù)以POST方式發(fā)送到對方去。在Avro中,它的消息被封裝成為一組緩沖區(qū)(Buffer),類似于下圖的模型:
如上圖,每個緩沖區(qū)以四個字節(jié)開頭,中間是多個字節(jié)的緩沖數(shù)據(jù),最后以一個空緩沖區(qū)結(jié)尾。這種機制的好處在于,發(fā)送端在發(fā)送數(shù)據(jù)時可以很方便地組裝不同數(shù)據(jù)源的數(shù)據(jù),接收方也可以將數(shù)據(jù)存入不同的存儲區(qū)。還有,當(dāng)往緩沖區(qū)中寫數(shù)據(jù)時,大對象可以獨占一個緩沖區(qū),而不是與其它小對象混合存放,便于接收方方便地讀取大對象。
下面聊下Avro的其它方面信息。前文中引述Doug Cutting的話說,Protocol Buffer在傳輸數(shù)據(jù)時,往數(shù)據(jù)中加入注釋(annotation),以應(yīng)對數(shù)據(jù)結(jié)構(gòu)與數(shù)據(jù)不匹配的問題。但直接導(dǎo)致數(shù)據(jù)量變大,解析困難等缺點。那Avro是如何應(yīng)對模式與數(shù)據(jù)的不同呢?為了保證Avro的高效,假定模式至少大部分是匹配的,然后定義一些驗證規(guī)則,如果在規(guī)則滿足的前提下,做數(shù)據(jù)驗證。如果模式不匹配就會報錯。相同模式,交互數(shù)據(jù)時,如果數(shù)據(jù)中缺少某個域(field),用規(guī)范中的默認(rèn)值設(shè)置;如果數(shù)據(jù)中多了些與模式不匹配的數(shù)據(jù)。則忽視這些值。
Avro列出的優(yōu)點中還有一項是:可排序的。就是說,一種語言支持的Avro程序在序列化數(shù)據(jù)后,可由其它語言的Avro程序?qū)ξ捶葱蛄谢臄?shù)據(jù)排序。我不知道這種機制是在什么樣的場景下使用,但看起來還是挺不錯的。
轉(zhuǎn)帖:http://langyu.iteye.com/blog/708568
在hive中實現(xiàn)avro存儲非常簡單。https://cwiki.apache.org/confluence/display/Hive/AvroSerDe 里面有非常詳細(xì)的介紹
高版本的hive,可以直接使用avro格式存儲,而不需要手動指定avro的schema文件,hive自己會根據(jù)table的創(chuàng)建方式自行解析并將schema存儲到文件的頭部。
create table kst(
> name string,age int
> ) stored as avro;
之后,通過手段將數(shù)據(jù)導(dǎo)入到kst表中,1)通過其他表select insert into,2)通過其他程序生成avro格式的數(shù)據(jù),并load到hive表中,或者add partition進去也可以。
第一種方式:
from (select * from stus) base insert into kst select *;
之后,可以查看hive最終生成的數(shù)據(jù)。
可以看到,自動生成了表。
2)創(chuàng)建表的時候,schema直接寫在table中(Use schema.literal and embed the schema in the create statement)
CREATE EXTERNAL TABLE tweets
COMMENT "A table backed by Avro data with the
Avro schema embedded in the CREATE TABLE statement"
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.avro.AvroSerDe'
STORED AS
INPUTFORMAT 'org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat'
LOCATION '/user/wyp/examples/input/'
TBLPROPERTIES (
'avro.schema.literal'='{
"type": "record",
"name": "Tweet",
"namespace": "com.miguno.avro",
"fields": [
{ "name":"username", "type":"string"},
{ "name":"tweet", "type":"string"},
{ "name":"timestamp", "type":"long"}
]
}'
);
3)通過hive腳本(Use avro.schema.literal and pass the schema into the script)
Hive can do simple variable substitution and you can pass the schema embedded in a variable to the script. Note that to do this, the schema must be completely escaped (carriage returns converted to \n, tabs to \t, quotes escaped, etc). An example:
|
To execute this script file, assuming $SCHEMA has been defined to be the escaped schema value:
|
Note that $SCHEMA is interpolated into the quotes to correctly handle spaces within the schema.
最后,即使額外指定sechema自動生成表,那么最終的schema也寫入到最后生成的文件中。
看完了這篇文章,相信你對“Hive中AVRO數(shù)據(jù)存儲格式的示例分析”有了一定的了解,如果想了解更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!