Hive優(yōu)化
一、why?為什么要優(yōu)化?
????基于hive設(shè)計的數(shù)據(jù)模型是為了給數(shù)據(jù)產(chǎn)品服務(wù),一個好的數(shù)據(jù)模型要符合以下幾點:
1.跑批速度快。???2.查詢效率高,能夠及時響應(yīng)查詢需求。????3.可拓展性強(qiáng),能夠靈活應(yīng)對業(yè)務(wù)需求變更,減少煙囪式開發(fā),便于后期維護(hù)。4.盡可能少的占用存儲資源和計算資源。???所以調(diào)優(yōu)的目的就是為了盡可能符合上面幾條標(biāo)準(zhǔn)。

二、how?如何優(yōu)化?
????基于上面的幾大標(biāo)準(zhǔn),我個人的優(yōu)化思路是:資源優(yōu)化-》參數(shù)調(diào)優(yōu)-》SQL邏輯優(yōu)化-》數(shù)據(jù)模型優(yōu)化。也就是先看能不能先協(xié)調(diào)資源解決問題,其次再看常用的參數(shù)調(diào)優(yōu)是否能解決問題,再看SQL邏輯是不是有值得優(yōu)化的地方,如何最后問題還是解決不了,再考慮模型設(shè)計上是否能進(jìn)行優(yōu)化。
????那基于上面的優(yōu)化思路,我下面圍繞存儲和計算兩個角度談?wù)剬ive常見問題的優(yōu)化方案。
1.存儲角度
主要體現(xiàn)在我們建表時候的優(yōu)化,建表時根據(jù)業(yè)務(wù)需求是否需要構(gòu)建分區(qū)表和分桶表,以及文件的存儲格式和壓縮格式的選擇。
存儲格式:行式存儲(textFile格式等)、列式存儲(orc,parquet格式等)。
壓縮格式:snappy、lzo、bzip2、gip等等。
存儲格式選用哪種得分情況,比如數(shù)據(jù)貼源層,源數(shù)據(jù)大多數(shù)行式存儲的數(shù)據(jù),那表就只能設(shè)計為行式存儲了。如果是中間層,那為了提交檢索效率,大多數(shù)就用的是列式存儲了,orc相比于parquet,orc和hive的兼容性更好,且存儲壓縮率和數(shù)據(jù)導(dǎo)入和數(shù)據(jù)查詢的速度要高于parquet,所以在hive中orc用的較多,而spark對parquet的支持要更好,在spark中parquet用的較多。壓縮格式的話我們主要的考慮因素有壓縮比,壓縮解壓縮速度以及壓縮后文件是否可切片,可以場景選擇。下面是各種壓縮算法的一些性能比較:

2.計算角度
????在數(shù)據(jù)計算時,我們常碰見的問題有以下幾種:
1)數(shù)據(jù)傾斜問題
????數(shù)據(jù)傾斜的體現(xiàn)是在任務(wù)跑批的時候,其它task已經(jīng)跑完,有部分task任務(wù)卡住。
造成這個問題的原因是部分task處理的數(shù)據(jù)量明顯比其他task多,所以處理時間明顯就慢。
數(shù)據(jù)傾斜問題分兩大類:
①單表造成的數(shù)據(jù)傾斜
????當(dāng)對單表進(jìn)行g(shù)roup by分組聚合時,容易造成數(shù)據(jù)傾斜,對于sum以及count這種操作,
如果是單個key造成的數(shù)據(jù)傾斜,可以先進(jìn)行參數(shù)調(diào)優(yōu),開啟map端的預(yù)聚合以及數(shù)據(jù)傾斜負(fù)載均衡參數(shù)。
如果是多個key同時造成的數(shù)據(jù)傾斜,那就可能是reduce數(shù)量太少了,可以增加reduce的數(shù)量
方法1:直接設(shè)置hive每個?job的reduce的數(shù)量
方法2:
②多表join造成數(shù)據(jù)傾斜
小表join大表,MapJoin開啟后,會把小表分發(fā)到各個map進(jìn)程中,大表直接跟內(nèi)存中的小表數(shù)據(jù)進(jìn)行join,避免了reduce過程從而避免了數(shù)據(jù)傾斜的問題
還可以開啟join數(shù)據(jù)傾斜的優(yōu)化參數(shù),對于數(shù)據(jù)傾斜的key對單獨開啟任務(wù)進(jìn)行處理,兩個任務(wù)并行處理,單獨處理的數(shù)據(jù)量少了,也能處理數(shù)據(jù)傾斜問題。
處理數(shù)據(jù)傾斜問題其實就是利用分治的思維,先分后合,先把傾斜的數(shù)據(jù)單獨進(jìn)行拆分處理,其它數(shù)據(jù)單獨處理,最后再將兩部分的處理結(jié)果合并。
2)大表join問題
????大表join大表的問題實質(zhì)上是數(shù)據(jù)量太大,在數(shù)據(jù)檢索的時候IO操作太多檢索慢造成的。所以重點在于如何減少IO,提高檢索效率。一是對數(shù)據(jù)進(jìn)行分類,減少檢索范圍,二是對數(shù)據(jù)進(jìn)行排序,提高檢索效率。所以處理方式有以下幾種:
①開啟SMBjoin,通過分桶,然后桶內(nèi)排序解決
對于兩個join的表按照join鍵進(jìn)行分桶排序,兩個表分桶個數(shù)相等或者成倍數(shù)關(guān)系,這樣在join的時候就只在對應(yīng)的桶內(nèi)找數(shù)據(jù)即可,而且桶內(nèi)的數(shù)據(jù)拍好了序,既降低了檢索范圍也提高了檢索效率。
② 分區(qū)處理
????通過分區(qū)處理的優(yōu)勢在于可以人為控制數(shù)據(jù)落在哪個分區(qū)之下??梢愿鶕?jù)join的字段進(jìn)行分區(qū)(可以hash,也可以按照字段其中的某幾位進(jìn)行分區(qū),需要對數(shù)據(jù)進(jìn)行提前分析避免分區(qū)太多),然后分區(qū)和分區(qū)間join,最后再將多個分區(qū)間的結(jié)果進(jìn)行合并。
③ 臨時表
? ? 將待join的大表,通過對關(guān)聯(lián)字段hash的方式打散分為多份,比如關(guān)聯(lián)字段hash后對5取模就將大表數(shù)據(jù)分為了5份放到臨時表中,最后再將個臨時表處理的結(jié)果進(jìn)行合并。
無論何種方式,都是利用分治思維解決問題。
3)小文件問題
? ? 一是如何對小文件處理,二是如何避免產(chǎn)生小文件。
????對于小文件,計算時每個小文件都會產(chǎn)生一個maptask,可以設(shè)置InputFormat
提前對輸入文件進(jìn)行合并,較少maptask的數(shù)量。同時可以開啟jvm重用功能,減少jvm頻繁開啟關(guān)閉帶來的資源浪費(fèi)。
????對于小文件的生成,一般存在于下面兩種操作中:
????①insert into table xxx value
這種操作,每執(zhí)行一次就會產(chǎn)生一個小文件,所以盡量避免這種操作。
????②動態(tài)分區(qū)過程中產(chǎn)生的小文件
動態(tài)分區(qū)的時候,reduce處理的數(shù)據(jù)分布不均勻?qū)е乱l(fā)的小文件問題,所以處理的時候可以通過distribute by? rand()這種方式將數(shù)據(jù)盡量均勻地分散到各個reduce中,并且適當(dāng)調(diào)整reduce的數(shù)據(jù)解決小文件問題。
????上面是針對于一些常見問題的優(yōu)化,也有一些其它的job任務(wù)整體優(yōu)化方案,如fetch抓取
可以避免有些情況不走mr任務(wù)直接查詢文件,在測試時數(shù)據(jù)量比較小開啟本地模式單機(jī)處理,降低執(zhí)行時間。? ??
????歡迎大家補(bǔ)充,謝謝!
?????
