Hadoop運維記錄
記錄一些Hive的優化點,和能夠提升的效率差異。
Hive是目前應用最多最廣的SQL on Hadoop工具,近期很多專業的大數據公司推出了很多新的,基于列式或者內存熱數據的SQL工具,像Impala,Tez,Spark等等,但是Hive仍然是目前使用率最高和普及面最廣的SQL on Hadoop的工具。在以前淘寶羅李的報告中,淘寶90%的業務跑在Hive上面。暴風影音的比例更高一些,大概95%以上都是跑在Hive上面。盡管很多人對Hive有看法,效率低,查詢慢,bug多。但是并不可否認hive是一個開創性的工具,提供了更多的想象空間。而且,在生產集群上的數據查詢程序的開發效率,Hive要遠遠高于自己寫MR。
在默認情況下,Hive的配置參數比較保守,所以效率會比較差一點,修改配置會讓查詢效率有比較大的提升,記錄幾個對查詢效率影響比較重要的參數。
首先拿到一個hive要修改的就是他的元數據存儲,默認情況下,Hive是用Derby內存數據庫存儲元數據,不明白,都是嵌入式數據庫,Hive為啥不用SQLite呢,之前寫過修改元數據存儲的文章,不在贅述。修改元數據存儲的傳送門在這里。
Hive參數優化:
比較重要是頭幾個和后幾個,尤其是最后兩個,性能提升效果是最明顯的。但是會同時開啟更多的MR任務,這就需要一個平衡了。
嵌套SQL并行執行優化:
set hive.exec.parallel=true;
set hive.exec.parallel.thread.number=16;
效率可提升至少100%
某job需要11個stage:
非并行35分鐘
并行8個job執行10分鐘
并行16個job執行6分鐘
Hive查詢的優化:
一、數據量大的表和數據量小的表做關聯的時候,把數據量小的表放到join前面去select。
原因是在 Join 操作的 Reduce 階段,位于 Join 操作符左邊的表的內容會被加載進內存,將條目少的表放在左邊,可以有效減少發生內存溢出錯誤的幾率。
二、Join優化
Join查找操作中如果存在多個join,且所有參與join的表中其參與join的key都相同,則會將所有的join合并到一個mapred程序中。
例:
SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1) 在一個mapre程序中執行join
SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2) 在兩個mapred程序中執行join
Map join的關鍵在于join操作中的某個表的數據量很小
例:
SELECT /*+ MAPJOIN(b) */ a.key, a.value FROM a join b on a.key = b.key
三、用sum() group by的方式來替換count(distinct)。
四、排序優化
Order by 實現全局排序,一個reduce實現,效率低
Sort by 實現部分有序,單個reduce輸出的結果是有序的,效率高,通常和DISTRIBUTE BY關鍵字一起使用(DISTRIBUTE BY關鍵字 可以指定map 到 reduce端的分發key)
CLUSTER BY col1 等價于DISTRIBUTE BY col1 SORT BY col1.
五、合并小文件
文件數目過多,會給 HDFS 帶來壓力,并且會影響處理效率,可以通過合并 Map 和 Reduce 的結果文件來盡量消除這樣的影響
hive.merge.mapfiles = true是否和并 Map 輸出文件,默認為 True
hive.merge.mapredfiles = false是否合并 Reduce 輸出文件,默認為 False
hive.merge.size.per.task = 256*1000*1000合并文件的大小。
這里的參數沒有寫到上面的表格里是因為這是可以根據任務不同臨時設置的,而不一定非要是全局設置。有時候全局設置了反而對大文件的操作有性能影響。
六、使用分區,RCFile,lzo,ORCFile等
Hive中的每個分區都對應hdfs上的一個目錄,分區列也不是表中的一個實際的字段,而是一個或者多個偽列,在表的數據文件中實際上并不保存分區列的信息與數據。Partition關鍵字中排在前面的為主分區(只有一個),后面的為副分區
靜態分區:靜態分區在加載數據和使用時都需要在sql語句中指定
例:(stat_date='20120625',province='hunan')
動態分區:使用動態分區需要設置hive.exec.dynamic.partition參數值為true,默認值為false,在默認情況下,hive會假設主分區時靜態分區,副分區使用動態分區;如果想都使用動態分區,需要設置set hive.exec.dynamic.partition.mode=nostrick,默認為strick
例:(stat_date='20120625',province)
七、使用外部表而盡量少用內部表,這主要從數據的安全性上考量。
本文出自 “實踐檢驗真理” 博客,http://slaytanic.blog.51cto.com/2057708/1295222。