Protobuf在騰訊數(shù)據(jù)倉庫TDW的使用_ IT技術(shù)精華
http://it.taocms.org/11/5991.htm
馬淑婧:TDW Protobuf存儲格式功能介紹-CSDN.NET
http://www.csdn.net/article/a/2014-06-06/15818975
protobuf是google提供的一個開源序列化框架,類似于XML、JSON這樣的數(shù)據(jù)表示語言,其最大的特點是基于二進制,因此比傳統(tǒng)的XML表示高效短小得多。雖然是二進制數(shù)據(jù)格式,但并沒有因此變得復(fù)雜,開發(fā)人員通過按照一定的語法定義結(jié)構(gòu)化的消息格式,然后送給命令行工具,工具將自動生成相關(guān)的類,可以支持java、c++、python等語言環(huán)境。通過將這些類包含在項目中,可以很輕松的調(diào)用相關(guān)方法來完成業(yè)務(wù)消息的序列化與反序列化工作。
protobuf在google中是一個比較核心的基礎(chǔ)庫,作為分布式運算涉及到大量的不同業(yè)務(wù)消息的傳遞,如何高效簡潔的表示、操作這些業(yè)務(wù)消息在google這樣的大規(guī)模應(yīng)用中是至關(guān)重要的。而protobuf這樣的庫正好是在效率、數(shù)據(jù)大小、易用性之間取得了很好的平衡。
protobuf****格式日志在tdw的支持
1、使用protobuf文件創(chuàng)建表
Tdw支持使用用戶定義的proto文件來創(chuàng)建表,使用我們開發(fā)的編譯器擴展對用的proto文件預(yù)處理后,通過proto文件自動抽取出表的結(jié)構(gòu),支持proto文件引用和message嵌套定義。例如:
message Person {required string name = 1;required int32 id = 2; // Unique ID number for this person.optional string email = 3;enum PhoneType {MOBILE = 0;HOME = 1;}message PhoneNumber {required string number = 1;optional PhoneType type = 2 [default = HOME];}repeated PhoneNumber phone = 4;}
創(chuàng)建的表結(jié)構(gòu)為:
table person{name stringid intemail stringphone array<struct<number:string,type:int>>}
Protobuf中enum 類型轉(zhuǎn)化為tdw的int類型,repeated類型轉(zhuǎn)化為tdw的array,支持protobuf中message定義的嵌套,嵌套message類型轉(zhuǎn)化為tdw的struct類型。
2、使用嵌套message protobuf文件的讀寫適配
提供HDFS與mapreduce層的適配支持protobuf record的input/output format,mapreduce層與hive層的讀寫適配Serde層支持嵌套類型的message讀寫和protobuf默認值的支持。
Protobuf表中的內(nèi)容采用記錄頭+記錄內(nèi)容的方式存儲,一條記錄的頭4個字節(jié)存儲了該記錄的數(shù)據(jù)長度,文件接口層以該長度為依據(jù)去讀取相應(yīng)的記錄內(nèi)容。各個記錄內(nèi)容之間用一個長度為4字節(jié)的長度字段分隔。

3、protobuf格式日志在tdw的使用
創(chuàng)建protobuf存儲格式的表,創(chuàng)建表過程需要用戶手工上傳proto文件,生成jar包,最后執(zhí)行建表語句。可通過以下幾步完成protobuf表的創(chuàng)建:
上傳Proto定義文件。將proto文件上傳到$QE_HOME/protobuf/upload/${UserName}/中
準備Jar文件。用makejar腳本預(yù)處理proto文件,產(chǎn)生并上傳對應(yīng)表的讀寫接口jar包。示例:$QE_HOME/bin/makejar.sh pgurl user passwd dbname tablename username filename protoversion
創(chuàng)建protobuf格式的表。創(chuàng)建protobuf存儲格式的TDW SQL語句是:CREATE TABLE <tableName> [partition_def] STORED AS PB。示例:
創(chuàng)建普通表(不包含分區(qū))create table comp stored as pb
創(chuàng)建帶分區(qū)的表,假設(shè)comp message中包含log_date的字段,以log_date字段建立分區(qū)的SQL為:create table comp partition by list(log_date) (partition default) stored as pb
注意事項
proto文件名一定要是小寫,并且不能包含空格等特殊字符;
proto文件中用到import其他proto文件的,不要寫路徑,只指明文件名即可,例如import “text.proto”;
主proto文件的message名字一定要與表名相同,根據(jù)proto文件生成jar包的時候會進行檢查,不相同會報錯
自定義的類型名和變量名不能相同(支持區(qū)分大小寫,即message A類型的變量名可以為a),否則生成jar包會失敗
不能包含空的message,否則建表的時候會出錯
protobuf格式的表入庫tdw,直接用hadoop命令將pb文件上傳到對應(yīng)表或分區(qū)的目錄下即可,支持gz壓縮。
使用tdw SQL對protobuf表做日志分析,簡單字段可以用通用SQL語法處理,以repeated類型為例描述如何用Lateral View + explode 的SQL處理pb表中的復(fù)雜字段。
舉例:
假設(shè)廣告展示表AdImpression的定義中每個廣告展示的記錄由一個頁面的id和當前頁面上展示的廣告幾個id的list組成,其proto定義為:
message AdImpression{ required string pageid = 1; repeated int adid_list =2; }
當前表中有如下數(shù)據(jù):

對表做lateral view + explode 的SQL如下所示:
SELECT pageid, adid FROM pageAds LATERAL VIEW explode(adid_list) adTable AS adid;
可以產(chǎn)生如下的輸出:

4、Protobuf表在TDW中使用現(xiàn)狀
當前TDW中有150張左右protobuf格式的表,主要存儲廣點通和推薦業(yè)務(wù)相關(guān)數(shù)據(jù),解決了廣點通日志模型中存儲效率低,分析難度大等問題。
TDW中的pb表大部分為小時或天分區(qū)表,日均新增數(shù)據(jù)30T左右,與文本日志相比節(jié)省了大約50%的存儲空間。在達到了簡化業(yè)務(wù)邏輯的同時也達到了節(jié)約存儲成本的效果。
5、protobuf和TDW數(shù)據(jù)類型對應(yīng)關(guān)系表
當前protobuf中數(shù)據(jù)類型對應(yīng)到TDW內(nèi)置類型的關(guān)系如下:

參考鏈接:http://www.csdn.net/article/a/2014-06-06/15818975

