
一、引言:
Hadoop的HDFS集群非常容易出現(xiàn)機(jī)器與機(jī)器之間磁盤利用率不平衡的情況,比如集群中添加新的數(shù)據(jù)節(jié)點(diǎn),節(jié)點(diǎn)與節(jié)點(diǎn)之間磁盤大小不一樣等等。當(dāng)hdfs出現(xiàn)不平衡狀況的時(shí)候,將引發(fā)很多問題,比如MR程序無法很好地利用本地計(jì)算的優(yōu)勢(shì),機(jī)器之間無法達(dá)到更好的網(wǎng)絡(luò)帶寬使用率,機(jī)器磁盤無法利用等等。
二、問題:
因業(yè)務(wù)需要搭建一個(gè)新hadoop集群,并將老的hadoop集群中的數(shù)據(jù)遷移至新的hadoop集群,而且datanode節(jié)點(diǎn)不能全部上線,其中還可能會(huì)出現(xiàn)節(jié)點(diǎn)上線或下線的情況,這個(gè)時(shí)候就很容易出現(xiàn)機(jī)器與機(jī)器之間磁盤的均衡的情況,具體如下:

上圖中可以看出max是94.18%,而min是0.37%,其中有600多臺(tái)是達(dá)到94%的,這個(gè)時(shí)候在跑mapred的時(shí)候往往會(huì)報(bào)錯(cuò)誤:

登陸到該機(jī)器上查看服務(wù)器的磁盤,磁盤都快已經(jīng)達(dá)到100%,如下:

因?yàn)槲覀冊(cè)趆dfs-site.xml中設(shè)置了dfs.datanode.du.reserved的值,所以磁盤會(huì)有一定預(yù)留空間:
dfs.datanode.du.reserved107374182400
上面這個(gè)參數(shù)的意思:
Reserved space in bytes per volume. Always leave this much space free for non dfs use.
再查看datanode日志,希望能找到可靠的線索:

這種錯(cuò)誤無法通過namenode來避免,因?yàn)樗粫?huì)再failed的時(shí)候去嘗試往別的節(jié)點(diǎn)寫數(shù), 最初的辦法是將該節(jié)點(diǎn)的datanode關(guān)閉掉,就能順利地跑完這個(gè)mapreduce。

再者查看namenode的頁面,看到有好多datanode的節(jié)點(diǎn)的Remaining快要趨于0B了,這個(gè)時(shí)候就很容易出現(xiàn)上面的報(bào)錯(cuò)。
為了防止上面的報(bào)錯(cuò)再次出現(xiàn)以及避免hdfs數(shù)據(jù)不均衡,對(duì)hadoop集群做balance已經(jīng)不可避免了!
二、解決方案
1、balancer
大家首先會(huì)想到hadoop自帶的balancer,那就先介紹一下balancer!
Balancer.java中是這么描述balancer的:
The balancer is a tool that balances disk space usage alt="" width="550" height="256" />
考慮到balancer是最近需要經(jīng)常做的操作,所以我們自己開發(fā)了一個(gè)查看balancer情況的頁面,結(jié)果如下:

上圖可以看到每個(gè)集群下balancer執(zhí)行情況。
balance一天能成功移動(dòng)的數(shù)據(jù)量大約在10-20T,這個(gè)數(shù)據(jù)量很難滿足超大集群。
目前我們調(diào)用balance會(huì)使用如下命令:
start-balancer.sh -threshold 20 -policy blockpool -include -f /tmp/ip.txt
上面的命令通過手工篩選出磁盤高的和磁盤低的放在ip.txt文件中,這樣balance就只通過這文件里的了,另外還需要設(shè)置適當(dāng)?shù)膖hreshold值,因?yàn)槭嵌鄋amespace的,所以需要選擇blockpool模式。
另外帶寬也是限制balance的一個(gè)因素,在hdfs-site.xml中是有設(shè)置的:
dfs.datanode.balance.bandwidthPerSec10485760
但是這個(gè)需要重啟,hadoop提供了一個(gè)動(dòng)態(tài)調(diào)整的命令:
hdfs dfsadmin -fs hdfs://ns1:8020 -setBalancerBandwidth 104857600 hdfs dfsadmin -fs hdfs://ns2:8020 -setBalancerBandwidth 104857600
2、上下節(jié)點(diǎn):
其實(shí)將高磁盤的節(jié)點(diǎn)強(qiáng)制Decommission是最快最有效的方案。
下節(jié)點(diǎn)的時(shí)候可能會(huì)出現(xiàn)有ns不能正常下掉的情況,其實(shí)這個(gè)時(shí)候節(jié)點(diǎn)的數(shù)據(jù)大部分已經(jīng)移出去了,可能有一些塊卡在那邊沒有移出去。
這個(gè)時(shí)候只能一個(gè)一個(gè)節(jié)點(diǎn)將已經(jīng)Decommissioned節(jié)點(diǎn)stop掉datanode進(jìn)程,如果在namenode的頁面上看到有丟失塊的話,就需要將這個(gè)塊先get到本地,在put上去。例如: