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