1. 程式人生 > 實用技巧 >Hadoop基礎(五十二):企業級調優(二)

Hadoop基礎(五十二):企業級調優(二)

4 資料傾斜

4.1 合理設定 Map 數 1)通常情況下,作業會通過 input 的目錄產生一個或者多個 map 任務。 主要的決定因素有:input 的檔案總個數,input 的檔案大小,叢集設定的檔案塊大小 2)是不是 map 數越多越好? 答案是否定的。如果一個任務有很多小檔案(遠遠小於塊大小 128m),則每個小檔案也會被當做一個塊,用一個 map 任務來完成,而一個 map 任務啟動和初始化的時間遠遠大 於邏輯處理的時間,就會造成很大的資源浪費。而且,同時可執行的 map 數是受限的。 3)是不是保證每個 map 處理接近 128m 的檔案塊,就高枕無憂了? 答案也是不一定。比如有一個 127m 的檔案,正常會用一個 map 去完成,但這個檔案只有一個或者兩個小欄位,卻有幾千萬的記錄,如果 map 處理的邏輯比較複雜,用一個 map 任務去做,肯定也比較耗時。針對上面的問題 2 和 3,我們需要採取兩種方式來解決:即減少 map 數和增加 map數; 4.2 小檔案進行合併
在 map 執行前合併小檔案,減少 map 數:CombineHiveInputFormat 具有對小檔案進行合併的功能(系統預設的格式)。HiveInputFormat 沒有對小檔案合併功能。
set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
4.3 複雜檔案增加 Map 數 當 input 的檔案都很大,任務邏輯複雜,map 執行非常慢的時候,可以考慮增加 Map數,來使得每個 map 處理的資料量減少,從而提高任務的執行效率。 增加 map 的方法為:根據computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M 公式,調整 maxSize 最大值。讓 maxSize 最大值低於 blocksize 就可以增加 map 的個數。 案例實操: 1.執行查詢
hive (default
)> select count(*) from emp; Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 1
2.設定最大切片值為 100 個位元組
hive (default)> set mapreduce.input.fileinputformat.split.maxsize=100;
hive (default)> select count(*) from emp;
Hadoop job information for Stage-1: number of mappers: 6
; number of reducers: 1
4.4 合理設定 Reduce 數 1.調整 reduce 個數方法一 (1)每個 Reduce 處理的資料量預設是 256MB
hive.exec.reducers.bytes.per.reducer=256000000
(2)每個任務最大的 reduce 數,預設為 1009
hive.exec.reducers.max=1009
(3)計算 reducer 數的公式
N=min(引數 2,總輸入資料量/引數 1)
2.調整 reduce 個數方法二 在 hadoop 的 mapred-default.xml 檔案中修改 設定每個 job 的 Reduce 個數
set mapreduce.job.reduces = 15;
3.reduce 個數並不是越多越好 1)過多的啟動和初始化 reduce 也會消耗時間和資源; 2)另外,有多少個 reduce,就會有多少個輸出檔案,如果生成了很多個小檔案,那麼 如果這些小檔案作為下一個任務的輸入,則也會出現小檔案過多的問題; 在設定 reduce 個數的時候也需要考慮這兩個原則:處理大資料量利用合適的 reduce數;使單個 reduce 任務處理資料量大小要合適;

5 並行執行

  Hive 會將一個查詢轉化成一個或者多個階段。這樣的階段可以是 MapReduce 階段、抽樣階段、合併階段、limit 階段。或者 Hive 執行過程中可能需要的其他階段。預設情況下, Hive 一次只會執行一個階段。不過,某個特定的 job 可能包含眾多的階段,而這些階段可能並非完全互相依賴的,也就是說有些階段是可以並行執行的,這樣可能使得整個 job 的執行 時間縮短。不過,如果有更多的階段可以並行執行,那麼 job 可能就越快完成。   通過設定引數 hive.exec.parallel 值為 true,就可以開啟併發執行。不過,在共享叢集中, 需要注意下,如果 job 中並行階段增多,那麼叢集利用率就會增加。
set hive.exec.parallel=true; //開啟任務並行執行
set hive.exec.parallel.thread.number=16; //同一個 sql 允許最大並行度,預設為 8。

6 嚴格模式

Hive 提供了一個嚴格模式,可以防止使用者執行那些可能意想不到的不好的影響的查詢。通過設定屬性 hive.mapred.mode 值為預設是非嚴格模式 nonstrict 。開啟嚴格模式需要 修改 hive.mapred.mode 值為 strict,開啟嚴格模式可以禁止 3 種類型的查詢。
<property>
 <name>hive.mapred.mode</name>
 <value>strict</value>
 <description>
 The mode in which the Hive operations are being performed. 
 In strict mode, some risky queries are not allowed to run. They include:
 Cartesian Product.
 No partition being picked up for a query.
 Comparing bigints and strings.
 Comparing bigints and doubles.
 Orderby without limit.
</description>
</property>
1) 對於分割槽表,除非 where 語句中含有分割槽欄位過濾條件來限制範圍,否則不允許執行。換句話說,就是使用者不允許掃描所有分割槽。進行這個限制的原因是,通常分割槽表都擁有 非常大的資料集,而且資料增加迅速。沒有進行分割槽限制的查詢可能會消耗令人不可接受的巨大資源來處理這個表。 2) 對於使用了 order by 語句的查詢,要求必須使用 limit 語句。因為 order by 為了執行排序過程會將所有的結果資料分發到同一個 Reducer 中進行處理,強制要求使用者增加這個 LIMIT 語句可以防止 Reducer 額外執行很長一段時間。 3) 限制笛卡爾積的查詢。對關係型資料庫非常瞭解的使用者可能期望在執行 JOIN 查詢的時候不使用 ON 語句而是使用 where 語句,這樣關係資料庫的執行優化器就可以高效地將 WHERE 語句轉化成那個 ON 語句。不幸的是,Hive 並不會執行這種優化,因此,如果表足夠大,那麼這個查詢就會出現不可控的情況。

7 JVM 重用

  JVM 重用是 Hadoop 調優引數的內容,其對 Hive 的效能具有非常大的影響,特別是對於很難避免小檔案的場景或 task 特別多的場景,這類場景大多數執行時間都很短。   Hadoop 的預設配置通常是使用派生 JVM 來執行 map 和 Reduce 任務的。這時 JVM 的啟動過程可能會造成相當大的開銷,尤其是執行的 job 包含有成百上千 task 任務的情況。 JVM重用可以使得JVM例項在同一個 job 中重新使用N次。N的值可以在Hadoop的 mapredsite.xml 檔案中進行配置。通常在 10-20 之間,具體多少需要根據具體業務場景測試得出。
<property>
 <name>mapreduce.job.jvm.numtasks</name>
 <value>10</value>
 <description>How many tasks to run per jvm. If set to -1, there is
no limit. 
 </description>
</property>
這個功能的缺點是,開啟 JVM 重用將一直佔用使用到的 task 插槽,以便進行重用,直到任務完成後才能釋放。如果某個“不平衡的”job 中有某幾個 reduce task 執行的時間要比其 他 Reduce task 消耗的時間多的多的話,那麼保留的插槽就會一直空閒著卻無法被其他的 job使用,直到所有的 task 都結束了才會釋放。

8 推測執行

在分散式叢集環境下,因為程式 Bug(包括 Hadoop 本身的 bug),負載不均衡或者資源分佈不均等原因,會造成同一個作業的多個任務之間執行速度不一致,有些任務的執行速 度可能明顯慢於其他任務(比如一個作業的某個任務進度只有 50%,而其他所有任務已經執行完畢),則這些任務會拖慢作業的整體執行進度。為了避免這種情況發生,Hadoop 採用 了推測執行(Speculative Execution)機制,它根據一定的法則推測出“拖後腿”的任務,併為這樣的任務啟動一個備份任務,讓該任務與原始任務同時處理同一份資料,並最終選用最先 成功執行完成任務的計算結果作為最終結果。 設定開啟推測執行引數:Hadoop 的 mapred-site.xml 檔案中進行配置,預設是 true
<property>
 <name>mapreduce.map.speculative</name>
 <value>true</value>
 <description>If true, then multiple instances of some map tasks 
 may be executed in parallel.</description>
</property>
<property>
 <name>mapreduce.reduce.speculative</name>
 <value>true</value>
 <description>If true, then multiple instances of some reduce tasks 
 may be executed in parallel.</description>
</property>
不過 hive 本身也提供了配置項來控制 reduce-side 的推測執行:預設是 true
<property>
 <name>hive.mapred.reduce.tasks.speculative.execution</name>
<value>true</value>
 <description>Whether speculative execution for reducers should be turned on. 
</description>
 </property>
關於調優這些推測執行變數,還很難給一個具體的建議。如果使用者對於執行時的偏差非常敏感的話,那麼可以將這些功能關閉掉。如果使用者因為輸入資料量很大而需要執行長時間 的 map 或者 Reduce task 的話,那麼啟動推測執行造成的浪費是非常巨大大。

9 壓縮行計劃

10 執行計劃(Explain)

1.基本語法 EXPLAIN [EXTENDED | DEPENDENCY | AUTHORIZATION] query 2.案例實操 (1)檢視下面這條語句的執行計劃
hive (default)> explain select * from emp;
hive (default)> explain select deptno, avg(sal) avg_sal from emp group by deptno;
(2)檢視詳細執行計劃
hive (default)> explain extended select * from emp;
hive (default)> explain extended select deptno, avg(sal) avg_sal from emp group 
by deptno;