大資料(二十四):資料傾斜優化、並行執行、嚴格模式、JVM重用、執行計劃
一、資料傾斜優化
1.合理設定Map數量
1.通常情況下,作業會通過input的目錄產生一個或者多個map任務
主要的決定因素有:input的檔案總個數,input的檔案大小,叢集設定的檔案塊大小。
2.Map並非越多越好
如果一個任務有很多小檔案,則每個小檔案也會被當做一個塊,用一個map任務來完成,而一個map任務啟動和初始化的時間遠遠大於邏輯處理的時間,就會造成最大的資源浪費。而且,同時可執行的map數是受限制的。
3.保證每個map處理接近128m的檔案快,就沒有問題嗎?
有個一個127m的檔案,預設情況下會用一個map去完成,但這個檔案只有一個或者兩個小欄位,卻有著幾千萬行記錄,如果map處理的邏輯比較複雜,用一個map任務去做,肯定也比較耗時。
2.小檔案進行合併
在map執行前合併小檔案,減少map數:CombineHiveInputFormat具有對小檔案進行合併的功能(系統預設的格式)。HiveInputFormat沒有對小檔案合併功能。
set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
3.複雜檔案增加Map數
當input的檔案都很大,任務邏輯複雜,map執行非常慢的時候,可以考慮增加Map數,來使得每個map處理的資料量減少,從而提高任務的執行效率。
增加map的方法為:根據computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=128M公式,調整maxSize最大值。讓maxSize最大值低於blocksize就可以增加map的個數。
set mapreduce.input.fileinputformat.split.maxsize = 100;
4.合理設定Reduce數
1.調整reduce個數方法(1)
(1)每個Reduce處理的資料量預設是256MB
set hive.exec.reducers.bytes.per.reducer = 256000000
(2)每個任務最大的reduce數,預設為1009
set hive.exec.reducers.max = 1009
(3)計算reducer數的公式
N=min(引數2,總輸入資料量/引數1)
2.調整reduce個數方法(2)
在hadoop的mapred-default.xml檔案中修改,設定每個job的Reduce個數
set mapreduce.job.reduces = 15;
3.reduce個數並不是越多越好
(1)過多的啟動和初始化reduce也會消耗時間和資源;
(2)另外,有多少個reduce,就會有多少個輸出檔案,如果產生了很多個小檔案,那麼如果這些小檔案作為下一個任務的輸入,則也會出現小檔案過多的問題;
在設定reduce個數的時候也需要考慮這兩個原則:處理大資料利用適合的reduce數;使單個reduce任務處理資料大小要合適;
二、並行執行
Hive會將一個查詢轉化成一個或者多個階段。這樣的階段可以是MapReduce階段、抽樣階段、合併階段、limit階段。或者Hive執行過程中可能需要的其他階段。預設情況下,Hive一次只會執行一個階段。不過某個特定的job可以包含眾多的階段,而這些階段可能並非完全相互依賴的,也就是說有些階段是可以並行執行的,這樣可能使得整個job的執行時間縮短。不過,如果有更多的階段可以並行執行,那麼job可能就越快完成。
通過設定引數hive.exec.parallel值為true,就可以開啟併發執行。不過,在共享叢集中,需要注意下,如果job中並行階段增多,那麼叢集利用率就會增加。
#開啟任務並行執行
set hive.exec.parallel = true;
#同一個sql允許最大並行度,預設為8
set hive.exec.parallel.thread.number = 16;
三、嚴格模式
hive提供了一個嚴格模式,可以方式使用者執行那些可能意識不到的不好的影響的查詢。
通過設定屬性hive.mapred.mode預設值是非嚴格模式(nonstrict)。開啟嚴格模式需要修改hive.mapred.mode值為strict,開啟嚴格模式可以禁止3種類型的查詢。
<property>
<name>hive.mapred.mode</name>
<value>strict</value>
</property>
1.對於分割槽表,除非where語句中含有分割槽欄位過濾條件來限制使用範圍,否則不允許執行。就是使用者不允許掃描所有的分割槽。進行這個限制的原因是,通常分割槽表都擁有非常龐大的資料集,而且資料迅速增加。沒有進行分割槽限制的查詢可能會消耗令人不可接受的巨大資源來處理這個表。
2.對於使用了order by語句的查詢,要求必須使用limit語句。因為order by為了執行排序過程會將所有的結果資料分發到同一個Reduce中進行處理,強制要求使用者增加這個limit語句可以防止Reduce額外執行很長一段時間。
3.限制笛卡爾積的查詢。對關係資料庫非常瞭解的時候可能在執行Join查詢的時候不使用on語句而是用where語句,這樣關係資料庫的執行優化器就可以高效的將Where語句轉換成on語句,但是Hive並不會執行這種優化,因此,如果該表很大,這個查詢就會出現不可控的情況。
四、JVM重用
JVM重用是Hadoop調優引數的內容,其對hive的效能具有非常大的影響,特別是對於很難避免的小檔案的場景或task特別多的場景,這類場景大多數執行時間都很短。
Hadoop的預設配置通常是使用派生JVM來執行map和Reduce任務的。這時JVM的啟動過程可能會造成相當大的開銷,尤其是執行的job包含成百上千task任務的情況。JVM重用可以使得JVM例項在同一個job中重新使用N次。N的值可以在Hadoop的mapred-site.xml檔案中進行配置。通常在10-20之間,具體多少需要根據具體業務場景測試得出。
<property>
<name>mapreduce.job.jvm.numtasks</name>
<value>10</vaule>
</property>
這個功能的缺點是,開啟jvm重啟將會一直佔用使用到的task插槽,以便使用重啟,知道任務完成後才會釋放。如果某個“不平衡的”job中有幾個reduce task時間要比其他的reduce task消耗的時間多很多的話,那麼保留的插槽將會一直空閒著缺無法被其他的job使用,直到所有的task都結束了才會釋放。
五、檢視語句執行計劃
通過檢視語句的執行計劃單獨對語句進行優化
基本語法:EXPLAIN [EXTENDED|DEPENDENCY|AUTHORIZATION] qurey