現在的位置: 首頁 > 編程語言 > 正文

hadoop 性能調優 重要參數設置技巧 hadoop 性能調優 重要參數設置技巧

2019年04月30日 編程語言 ⁄ 共 4038字 ⁄ 字型大小 評論關閉

hadoop 性能調優 重要參數設置技巧

分類: hadoop 43人閱讀 評論(0) 收藏 舉報

這裡主要針對Mapreduce的性能調優。

這一兩個月在做mapreduce的性能調優,有些心得,還是要記下來的,以郷後人~

這裡主要涉及的參數包括:

HDFS:

dfs.block.size

Mapredure:

io.sort.mb

io.sort.spill.percent

mapred.local.dir

mapred.map.tasks & mapred.tasktracker.map.tasks.maximum

mapred.reduce.tasks & mapred.tasktracker.reduce.tasks.maximum

mapred.reduce.max.attempts

mapred.reduce.parallel.copies

mapreduce.reduce.shuffle.maxfetchfailures

mapred.child.java.opts

mapred.reduce.tasks.speculative.execution

mapred.compress.map.output & mapred.map.output.compression.codec

mapred.reduce.slowstart.completed.maps

這裡一共列出了十六個參數,這十六個參數基本上能滿足一般情況下,不針對特定場景應用的性能調優了,下面我將以Terasort為例,詳述這些參數的作用已經如何配比調優。

       hadoop的HDFS作為mapreduce的基礎分散式文件系統,對mapred的運行效果也有直接的影響。首先影響到我們的性能的參數就是block.size,在網路環境很好的集群中,建議將這個參數提升,大小可以到128或256或更大(默認64M)。

        但是HDFS的影響也僅限於此,而且其配置項多數都是目錄配置以及容錯,還有備份數等等,這些對於我們性能調優意義不大。可以舉一個例子,那就是備份數。這個參數主要是用於設置block在集群中的備份數,這些備份將按照某種規則分配在集群的各個機器上,默認是3備份。但是由於mapred的map需要輸入數據,一般默認情況是一個map一個block,那麼當你在集群起job,一個job拉起來N多的map在一個機器執行時,如果這個map的輸入數據是本地的,那麼顯然map的執行將會更快,因為不需要等待網路傳輸。拿四個節點為例,如果你設置三備份,那麼你不管存什麼數據,任何一台機器上可以存數的你的數據的量都是3/4,。但是如果你設置為四備份,那麼任意一個節點上都能完整的找到你的數據,那麼不管你怎麼起job,你的map都將是本地化的。但是帶來的壞處就是磁碟開銷過大,一般大型的集群也承受不了5備份以上的數據量,所以,基本無意義。

         下面來談談重頭戲,那就是mapred中的這些NB的參數。前置知識我相信大家都已經了解了(如果你還不了解mapred的運行機制,看這個也無意義...),首先數據要進行map,然後merge,然後reduce進程進行copy,最後進行reduce,其中的merge和copy總稱可以為shuffle。在你起一個job前,hadoop需要知道你要啟動多少個map,多少個renduce進程,如果你進行默認參數啟動,那麼默認只有一個map線程。(reduce也許也是一個..)這個速度是很慢的。設置map啟動個數的參數是mapred.map.tasks,reduce則是mapred.reduce.tasks。這兩個參數可以說是對整個集群的性能起主導型作用的參數,調試也基本上圍繞這兩個參數。那大家要問就兩個參數有什麼好來回修改的呢?其實,這兩個參數的設置配比也直接影響到其他的參數的設置。首當其衝的就是mapred.tasktracker.map.tasks.maximum
以及 mapred.tasktracker.reduce.tasks.maximum。因為這兩個參數設置了一台伺服器上最多能同時運行的map和reduce數。現在我們來假設一個集群有一個namenode以及8個datanode,這是一個很客觀的集群。我們假設上面的數據都是三備份,那麼本地數據率為3/8。假設你設置的map.tasks=128,reuce.tasks=64,那麼你的對應的兩個maximum就應該分別為16以及8或是更高。因為這樣才能保證你的所有map和reduce的任務都是分別同時啟動的,如果你的設置reduce的maximum為7,那麼你將得到非常糟糕的結果,因為這樣8台機器同時可以運行的reduce數量為56了,比你設置的64差8個進程,這八個進程將會處於pending狀態,直到某些正在運行的reduce完成它才能補上運行,勢必大幅度的增加了運行時間。當然,這也不是越大越好,因為map有很長的一段時間是和reduce進程共存的,共存的時間取決於你設置的mapred.reduce.slowstart.completed.maps,如果你設置為0.6.那麼reduce將在map完成60%後進入運行態。所以說,如果你設置的map和reduce參數都很大,勢必造成map和reduce爭搶資源,造成有些進程飢餓,超時出錯,最大的可能就是socket.timeout的出錯,網路過於繁忙。所以說,這些需要根據集群的性能,適當調試添加和減少,以達到最好的效果。那麼,map和reduce之間是怎樣的配比比較好呢?apache官網給了我們一些建議,比如設置reduce與map,他們之間有一個具體的公式。但是實際情況總是不能用公式來套用的(否則就不需要系統工程師了...)。一般情況下,當你設置好map和reduce進程數後,你可以通過hadoop的mapred的頁面入口(http://namenode:50030/jobdetai.jps)查看map和reduce進度,如果你發現reduce在33%時,map正好提早一點點到100%,那麼這將是最佳的配比,因為reduce是在33%的時候完成了copy階段,也就是說,map需要再reduce到達33%之前完成所有的map任務,準備好數據。千萬不能讓reduce在等待,但是可以讓map先完成。

          OK!這個重點的搞完之後我們在看看兩個息息相關的參數,io.sort.mb和mapred.child.java.opts。因為每一個map或是reduce進程都是一個task,都會對應啟動一個JVM,所以其實java.opts也與你啟動的map和reduce數以及別的一些jvm敏感的參數有關。既然task運行在JVM裡面,那麼,我這裡所要提到的sort.mb 也是分配在JVM中的,這個值是用來設置到底我一個map sort的可用buffer大小是多少,如果map在內存中sort的結果達到一個特定的值,就會被spill進入硬碟。具體這個值是等於mb*io.sort.spill.percent.。按照通常的設置方式,為了讓jvm發揮最佳性能,一般設置JVM的最大可用內存量為mb設置的內存量的兩倍。那麼mb的內存量又根據什麼設置呢?它主要是與你的一個map的結果數據量有關。如果一個map的結果數據量為600M,那麼如果你設置的mb*io.sort.spill.percent.=200M,那麼將進行3次spill進入硬碟,然後map完成後再將數據從硬碟上取出進行copy。所以,這個mb設置如果是600M的話,那麼就不需要進行這次硬碟訪問了,節省了很多時間。但是最大的問題是內存耗費很大。如果mb是600M,那麼jvm.opts將需要設置為1G以上,那麼,按照上例,你同時啟動16個map和8個reduce
的話,那麼你的內存至少應該有24G。所以,這裡的設置也要慎重,因為畢竟你的伺服器還要跑很多其他的服務。

         下面就講一下別的一些有影響的參數,按照一般的設置方法就可以。首先是針對磁碟和磁碟IO的,mapred.local.dir,這個參數最好設置的跟你的磁碟數相同,你的磁碟應該每一個磁碟都單獨設置為RAID0,然後將所有磁碟配置成多路徑在這個配置項下,那麼HDFS在決定數據存儲時會順序循環存儲,保證所有磁碟數據量的一致性,也提升了整體磁碟的IO速度。那麼針對於網路,主要是有reduce和map同時運行時需要慎重考慮。mapred.reduce.parallel.copies與mapreduce.reduce.shuffle.maxfetchfailures這些參數都是對網路有一些影響的。第一個是reduce可以進行的最大並行拷貝線程數,這些線程會同時從不同的datanode上取map結果,而第二個出錯重試次數過多對於很多我們的應用都是降低性能的一個問題。因為一般一個job重試了1次沒有成功那基本以後無論怎麼重試都是不會成功的,重試了不成功不要緊,關鍵是這個重試還大量的消耗系統的資源,讓其他的線程可能也因為starvation
而進入重試狀態,惡性循環了。如果說你的網路確實很成瓶頸,千兆網都達不到,那麼建議打開mapred.compress.map.output壓縮選項,並配置 mapred.map.output.compression.codec壓縮編碼格式,一般都會使用snappy,因為這種格式對於壓縮和解壓縮都相對較快。還有就是如果你的集群是異構的,有些機器性能好,有些差,那麼建議打開mapred.reduce.tasks.speculative.execution推測性執行,有利於優化進程分配,提升集群性能。

          在下才疏學淺,如有不詳或不對的地方,還請指正,歡迎~~~

抱歉!評論已關閉.