在 HDFS 上到底應該怎麼儲存才好呢?請看以下實驗。
本實驗主要介紹Hive處理Avro方法,與使用序列化儲存的好處,當然Avro的最重要功能Schema Evolution與Self-Describe目前還未想到好的例子說明,留到以後再提吧。
實驗數據是 HDFS 的日誌檔案,原始檔案存放於 Namenode 的宿主機檔案系統中,/var/log/hadoop/hdfs/hdfs-audit.log
並以日做分隔。我們以八月的記錄來做實驗
現在我們將其上傳至 HDFS 中以利分析
drwxr-xr-x - robinlin hdfs 0 2015-10-25 18:38 /apps/hive/warehouse/hdfs_audit_as_avro
drwxr-xr-x - robinlin hdfs 0 2015-10-25 19:02 /apps/hive/warehouse/hdfs_audit_as_parquet
drwxr-xr-x - robinlin hdfs 0 2015-10-25 15:20 /apps/hive/warehouse/hdfs_audit_as_text
其中 hdfs_audit_as_text 以原始檔案形式儲存,大小為 3550323691,大約為 3.5G
執行 Hive Query 將其匯入至HiveTable
create table hdfs_audit_text (
date string,
time string,
level string,
class string,
allowed string,
userName string,
auth string,
ip string,
cmd string,
src string,
dst string,
permission string,
protocol string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*)\t([^ ]*) ([^ ]*)\t([^ ]*)\t([^ ]*)\t([^ ]*)\t([^ ]*)\t([^ ]*)\t([^ ]*)",
"output.format.string" = "%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s %10$s %11$s %12$s %13$s"
)
STORED AS TEXTFILE;
load data inpath '/user/robinlin/hdfs/2015-8-import' into table hdfsaudittable;
並執行查詢
</pre><pre name="code" class="sql">select username, count (username) counting from hdfs_audit_as_text group by username;
結果
總共耗時大約十分鐘,CPU時間大約50分鐘
實體記憶體大約24G, 虛擬記憶體大約520G
接下來以Avro格式來做儲存,Avro是專門為分散式運算所設計的序列化格式框架,與一般序列化框架不同點是,Avro格式可以被任意分割與壓縮,大大增近了對分散式運算的支持度
而Avro在HDFS檔案系統中占的空間也較少,
用以下指令將原本hdfs_audit_as_text資料轉成Avro儲存格式,
CREATE TABLE hdfs_audit_as_avro (
date string,
time string,
level string,
class string,
allowed string,
userName string,
auth string,
ip string,
cmd string,
src string,
dst string,
permission string,
protocol string
)
STORED AS AVRO;
INSERT OVERWRITE TABLE hdfs_audit_as_avro SELECT * FROM hdfs_audit_as_text;
轉成Avro儲存,總共大小大約為1G左右。
執行以下查詢
select username, count (username) counting from hdfs_audit_as_avro group by username;
結果
總共耗時 1分半鐘 ,CPU時間大約為23分鐘
實體記憶體用量大約26G,虛擬記憶體大約530G左右
時間上有很大的進步,應該是跟檔案大小影響網路傳輸有關係。若是不用Hive做測試,而是直接做MR,那差距會更明顯,因為HDFS上並不適合存放" 小"的檔案,這樣會造成太多的Map Task而阻礙排呈,Hive應該有解決這個問題。
記憶體上並無改進,原因 應該是因為在處理MR時,讀入Map Task中就反序列化處理了,此時以原文的方式處理,而且Avro的特點是自帶Schema在檔案標頭,因此在記憶體的消耗量上會比原來要來的大一些些。
事實上還可以再改進記憶體消耗,那就是處理更少的資料,估計用Parquet,在這個情況下會有更好的效果。