6.2 診斷性能瓶頸
有的時候作業的執行時間會長得驚人。想靠猜也是很難猜對問題在哪。這一章中將介紹如何界定問題,找到根源。涉及的工具中有的是Hadoop自帶的,有的是本書提供的。
系統監控和Hadoop任務 在Hadoop的0.20.x版本中,並沒有提供MapReduce任務的CPU和內存的性能指標的抽取方法。不過在0.22版本中,CPU和內存性能指標將會被寫道作業的歷史信息文件中。並且可以通過Hadoop的用戶界面來查看這些。 |
6.2.1 理解MapReduce作業性能的影響因子
從大的方面來講,對作業性能有負面效應的影響因子可以分為如下幾個大類:
- Hadoop配置。默認設置在大部分服務器集群平台上的性能是非常低下的。但如果自定義的配置沒配好,情況也不會有多好。配置所導致的常見性能問題有內存頻繁交換,CPU過載等等。
- Map任務。特別大的文件和特別小的文件都會影響Map任務的性能。性能低下的代碼也會有影響。
- Reduce任務。數據傾斜(data skew),reduce的數量,未經優化的代碼都會影響reduce的性能。
- 硬件。集群會被部分糟糕的節點和網絡原因影響。特別是那種不夠大的集群。
這一章將會介紹作業性能低下的常見場景及解決方案。這些場景和方案將會分別在上述4大類別中介紹。
圖6.3種有一個決策樹,用以根據性能問題的特別界定原因和解決方案。
6.2.2 Map的性能問題
圖6.4是map任務中的各個基本單元,並標識出了可能影響性能的區域。
技術28 調查輸入數據中的特別大的部分
如果處理的數據突然增長到特別大,超出預期,那作業就會變得很慢。例如,有一天網站的訪問量突然飆升,產生了異乎尋常的大的日志文件。就會導致MapReduce作業變慢。
問題
如果在map或reduce有特別大的輸入數據,能夠被快速地發現或診斷出來。
方案
使用JobTracker UI將運行較慢的作業的當前輸入輸出數據的大小和歷史信息相比較。
討論
在JobTracker UI中選擇運行很慢的作業。在作業概述信息中可以看到作業的性能統計信息。如圖6.5所示。
把這些信息和作業的歷史信息相比較,就可以找到運行緩慢的原因了。
小結
要理解將會被作業處理的數據的特性。有的數據會有產生特別大的數據的時候,有的沒有。
技術29 診斷map端的數據傾斜(data skew)
數據傾斜是不可避免的。在map端,一般有兩個原因造成數據傾斜:
- 大量的不可分塊的超大文件
- 大量的小文件
問題
需要診斷是不是由於數據傾斜導致了作業運行緩慢
方案
使用JobTracker UI來比較同一個作業所有map任務的輸入數據的大小。
討論
由於數據傾斜會導致部分任務的運行時間要比其它的要長。只要把這些有拖延症的遲遲不完成的任務和其他已完成的任務的輸入數據的大小比較一下,就很容易可以把數據傾斜的問題找出來。
圖6.6介紹了使用JobTracker UI來診斷數據傾斜的步驟。
小結
如果已經確定了數據傾斜,下一步就是考慮如何減輕數據傾斜對作業的影響。技術50和51介紹如何診斷數據傾斜的成因。(這兩個技術在6.4.3。)
技術30 診斷map任務的低吞吐量問題
這個技術中將介紹如何診斷map任務是否存在低吞吐量問題,以及問題的成因。
問題
需要診斷是否是任務的低吞吐量導致了作業運行緩慢。
方案
用JobTracker UI或作業的歷史信息源數據中的性能指標來計算map任務的吞吐量。
討論
有以下方法可以得到某個任務的map任務的吞吐量:
- 使用JobTracker來得到任務的執行時間。再如圖6.7所示計算map任務的吞吐量。
- 用TaskThroughput類(源: http://goo.gl/QQvvQ)基於作業歷史信息文件得到所有map任務的吞吐量統計信息。如圖6.8所示。
小結
得到計算結果后,需要根據實際情況來判斷吞吐量是高還是低。如果數據來自於本地節點,那么可以以本地磁盤的讀取吞吐量為對照。如果數據來自於HDFS以外,就需要以數據的讀取速率,hadoop節點和數據源之間的讀取延遲等作為對照。
有以下幾點可以導致map任務的吞吐量變低:
- 源文件的大小遠小於HDFS的塊的大小。這意味着任務的開啟和停止要耗費更多的時間,就沒有足夠的時間來讀取並處理輸入數據。
- 源文件無法分塊。這導致需要通過網絡IO從其他節點讀取文件塊。
- 一個節點的本地磁盤或磁盤控制器運行在降級模式中,讀取寫入性能都很差。這會影響某個節點,而不是全部節點。
- 源文件不來自於HDFS。則可能是Hadoop節點和數據源之間的延遲導致了性能低下。
- Map任務從其他數據節點讀取數據。可以從JobTracker的map任務細節信息和任務運行嘗試中找到輸入塊的位置。如果輸入塊的位置不是任務執行的節點,那就不是本地數據了。
上述各點將分別有對應技術來診斷低吞吐量的具體成因。
技術31 小文件
在作業中,數以千計的小文件將會導致數以千計的JAVA任務來處理他們。這顯然是效率低下的。
問題
需要診斷是否是小文件導致了作業運行緩慢。
方案
使用JobTracker UI或作業歷史源數據來檢查輸入塊的大小。
討論
通過目測JobTracker中的作業的map任務列表中的輸入文件,就可以得到map任務的輸入數據的大小。圖6.9介紹了一個有小文件作為輸入源的歸屬同一個作業的map任務列表。
此外,還可以從作業統計信息摘要工具(https://github.com/alexholmes/hadoop-book/blob/master/src/main/java/com/manning/hip/ch6/MetricSummary.java)得到map輸入大小的字節數的最小值,最大值,平均值和中位數。如圖6.10所示。
小結
如果作業的輸入文件遠遠小於HDFS的塊的大小,集群就很有可能沒有足夠的時間來處理數據。第5張中介紹了很多提高處理小文件的效率的方法。
技術32 不可分塊的文件
如果作業的輸入文件無法分塊(例如:某些壓縮格式,二進制文件等等),那么數據就沒辦法得到序列化優化處理了,並且無法在HDFS本地處理。這個技術將介紹如何診斷作業的不可分快的文件的問題。
問題
需要診斷是不是不可分塊的文件導致了作業運行緩慢。
方案
使用JobTracker UI或作業歷史源數據來診斷輸入塊是否過大。
討論
通過目測JobTracker中作業的map任務列表的輸入文件,可以找到其中是否有不可分塊的超大文件。如圖6.11所示。
此外,還可以用作業統計信息摘要工具(https://github.com/alexholmes/hadoop-book/blob/master/src/main/java/com/manning/hip/ch6/MetricSummary.java)得到map輸入大小的字節數的最小值,最大值,平均值和中位數。如圖6.12所示。
用JobTracker來查看map任務的列表,並計算每個map人物的輸入字節數的平均值。
小結
如果作業輸入文件遠遠大於HDFS的塊的大小,那么集群將要分配大量的槽(slot)來處理這些大文件。由於這些輸入文件無法分塊,還會有大量的槽(slot)無法利用。
如果發生了這種情況,那么首先要想的就是,這是不是和預期的一樣。因為不基於塊的二進制文件就是要這樣處理。但如果是壓縮文件,如LZOP和BZIP2之外的壓縮格式,就可以考慮一下是不是要更換壓縮格式。第5張的表5.2列出了Hadoop中支持的所有壓縮格式以及它們對分塊的支持。
盡管LZOP格式可以分塊,但仍然有兩種情況無法分塊:
- LZOP文件沒有索引,無法分塊。如果是這種情況,可以參考第5張來創建索引文件。
- 不用LZOP的InputFormat來處理LZOP文件。不是LZOP的InputFormat不知道如何對LZOP文件進行分塊。如果要對LZOP進行分塊,應該用名字開頭為lzo的InputFormat,如LzoTextInputFormat。第5章中有詳細介紹。
這介紹了map任務性能影響因素的所有情況。下一步,將介紹reduce任務的性能的影響因素。