來源 http://www.blogjava.net/paulwong/archive/2012/09/24/388458.htmlhtml
- 網絡帶寬
Hadoop集羣的服務器在規劃時就在統一的交換機下,這是在官方文檔中建議的部署方式。
可是咱們的這臺交換機和其餘交換機的互聯帶寬有限,因此在客戶端遇到了HDFS訪問速度慢的問題。
把操做集羣的客戶端也聯入DataNode的交換機內部,解決了這個問題。
- 系統參數
對ulimit -c的修改也是官方文檔建議的修改,在集羣只有10臺服務器時,並無遇到問題。
隨着機器增長和任務增長,這個值須要改的更大。
- 配置文件管理
這個集羣用的是Cloudera發行的版本,配置文件默認存在/etc/hadoop/conf位置。這是一個只有root才能修改的位置。
爲了修改方便,我把配置文件統一保存在一臺機器上,修改後用腳本分發。保證全部服務器都是統一的配置。
- mapred.tasktracker.map.tasks.maximum
這個參數控制每一個TaskTracker同時運行的Map任務數。
之前的設置是和CPU核數相同的,偶爾遇到任務擠佔DataNode資源的問題。
如今改爲map+reduce+1==num_cpu_cores。
- 嚴格控制root權限
Cloudera的發行版會建立一個hadoop用戶,各類守護進程都應該以這個用戶運行。
曾經有誤操做(/usr/lib/hadoop/bin/hadoop datanode &)致使本地的數據目錄被root寫入新文件,因而正確啓動的hadoop用戶進程沒法讀寫。
因此如今的集羣服務器不提供平常的root權限訪問。
- Java的GC模式
在mapred.child.java.opts和HADOOP_OPTS都增長了-XX:+UseConcMarkSweepGC。
JDK的文檔中推薦現代多核處理器系統,採用這種GC方式,能夠充分利用CPU的併發能力。
這個改動對性能的積極影響很大。
- 選擇正確的JDK
這個集羣有部分服務器的JDK用的是32位版本,不能建立-Xmx4g以上的進程。
統一爲x64版本的JDK。
- mapred.reduce.slowstart.completed.maps
這個參數控制slowstart特性的時機,默認是在5%的map任務完成後,就開始調度reduce進程啓動,開始copy過程。
可是咱們的機器數量很少,有一次大量的任務堆積在JobTracker裏,每一個TaskTracker的map和reduce slots都跑滿了。
因爲map沒有足夠資源迅速完成,reduce也就沒法結束,形成集羣的資源互相死鎖。
把這個參數改爲了0.75,任務堆積的列表從平均10個,變成了3個。
- mapred.fairscheduler.preemption
這個參數設爲了true。以便fairscheduler在用戶最小資源不能知足時,kill其餘人的任務騰出足夠的資源。
集羣運行着各類類型的任務,有些map任務須要運行數小時。這個參數會致使這類任務被頻繁kill,幾乎沒法完成。曾經有個任務在7小時內被kill了137次。
能夠經過調整fairscheduler的pool配置解決,給這種任務單獨配置一個minMap==maxMap的pool。
- mapred.jobtracker.completeuserjobs.maximum
限制每一個用戶在JobTracker的內存中保存任務的個數。
由於這個參數過大,咱們的JobTracker啓動不到24小時就會陷入頻繁的FullGC當中。
目前改成5,JT平穩運行一天處理1500個任務,只佔用800M內存。
這個參數在>0.21.0已經沒有必要設置了,由於0.21版本改造了completeuserjobs的用法,會盡快的寫入磁盤,再也不內存中長期存在了。
- mapred.jobtracker.update.faulty.tracker.interval和mapred.jobtracker.max.blacklist.percent
一個寫錯的任務,會致使一大批TaskTracker進入黑名單,並且要24小時才能恢復。這種情況對中小規模的集羣性能影響是很是大的。只能經過手工重啓TaskTracker來修復。因此咱們就修改了部分JobTracker的代碼,暴露了兩個參數:
mapred.jobtracker.update.faulty.tracker.interval控制黑名單重置時間,默認是24小時不能改變,咱們如今改爲了1小時。
mapred.jobtracker.max.blacklist.percent控制進入黑名單TT的比例,咱們改爲了0.2。
我正在補充這兩個參數的TestCase,準備提交到trunk中。
- 多用hive少用streaming因爲streaming的方便快捷,咱們作了不少基於它的開發。可是因爲streaming的任務在運行時還要有一個java進程讀寫stdin/out,有必定的性能開銷。相似的需求最好改用自定義的Deserializer+hive來完成。