Hadoop集群datanode磁盤不均衡的解決方案


一、引言:
Hadoop的HDFS集群非常容易出現機器與機器之間磁盤利用率不平衡的情況,比如集群中添加新的數據節點,節點與節點之間磁盤大小不一樣等等。當hdfs出現不平衡狀況的時候,將引發很多問題,比如MR程序無法很好地利用本地計算的優勢,機器之間無法達到更好的網絡帶寬使用率,機器磁盤無法利用等等。
二、問題:
因業務需要搭建一個新hadoop集群,並將老的hadoop集群中的數據遷移至新的hadoop集群,而且datanode節點不能全部上線,其中還可能會出現節點上線或下線的情況,這個時候就很容易出現機器與機器之間磁盤的均衡的情況,具體如下:
上圖中可以看出max是94.18%,而min是0.37%,其中有600多台是達到94%的,這個時候在跑mapred的時候往往會報錯誤:
 
 
 
 
 
 
 
 
登陸到該機器上查看服務器的磁盤,磁盤都快已經達到100%,如下:
因為我們在hdfs-site.xml中設置了dfs.datanode.du.reserved的值,所以磁盤會有一定預留空間:
<property>
    <name>dfs.datanode.du.reserved</name>
    <value>107374182400</value>
</property>

上面這個參數的意思:

  Reserved space in bytes per volume. Always leave this much space free for non dfs use.

再查看datanode日志,希望能找到可靠的線索:

這種錯誤無法通過namenode來避免,因為它不會再failed的時候去嘗試往別的節點寫數, 最初的辦法是將該節點的datanode關閉掉,就能順利地跑完這個mapreduce。

再者查看namenode的頁面,看到有好多datanode的節點的Remaining快要趨於0B了,這個時候就很容易出現上面的報錯。

為了防止上面的報錯再次出現以及避免hdfs數據不均衡,對hadoop集群做balance已經不可避免了!
二、解決方案
1、balancer
大家首先會想到hadoop自帶的balancer,那就先介紹一下balancer!
Balancer.java中是這么描述balancer的:

The balancer is a tool that balances disk space usage on an HDFS cluster when some datanodes become full or when new empty nodes join the cluster.
The tool is deployed as an application program that can be run by the cluster administrator on a live HDFS cluster while applications adding and deleting files.

下面的圖片是官網中balancer命令得詳解:

考慮到balancer是最近需要經常做的操作,所以我們自己開發了一個查看balancer情況的頁面,結果如下:
上圖可以看到每個集群下balancer執行情況。
balance一天能成功移動的數據量大約在10-20T,這個數據量很難滿足超大集群。
目前我們調用balance會使用如下命令:
start-balancer.sh -threshold 20 -policy blockpool -include -f /tmp/ip.txt
上面的命令通過手工篩選出磁盤高的和磁盤低的放在ip.txt文件中,這樣balance就只通過這文件里的了,另外還需要設置適當的threshold值,因為是多namespace的,所以需要選擇blockpool模式。
另外帶寬也是限制balance的一個因素,在hdfs-site.xml中是有設置的:
<property>
    <name>dfs.datanode.balance.bandwidthPerSec</name> 
    <value>10485760</value> 
</property>

但是這個需要重啟,hadoop提供了一個動態調整的命令:

hdfs dfsadmin -fs hdfs://ns1:8020 -setBalancerBandwidth 104857600
hdfs dfsadmin -fs hdfs://ns2:8020 -setBalancerBandwidth 104857600
hdfs dfsadmin -fs hdfs://ns3:8020 -setBalancerBandwidth 104857600
hdfs dfsadmin -fs hdfs://ns4:8020 -setBalancerBandwidth 104857600
hdfs dfsadmin -fs hdfs://ns5:8020 -setBalancerBandwidth 104857600
 
 
2、上下節點:
其實將高磁盤的節點強制Decommission是最快最有效的方案。
下節點的時候可能會出現有ns不能正常下掉的情況,其實這個時候節點的數據大部分已經移出去了,可能有一些塊卡在那邊沒有移出去。
這個時候只能一個一個節點將已經Decommissioned節點stop掉datanode進程,如果在namenode的頁面上看到有丟失塊的話,就需要將這個塊先get到本地,在put上去。例如:
hdfs dfs -get hdfs://ns1/test/dt=2016-07-24/000816_0.lzo
 
hdfs dfs -put -f 000816_0.lzo hdfs://ns1/test/dt=2016-07-24/000816_0.lzo
 
hdfs dfs -chown dd_edw:dd_edw hdfs://ns1/test/dt=2016-07-24/000816_0.lzo  

前提條件需要將這個節點的datanode重新啟動。

3、升降數據副本:
升降副本是一個迫不得已的辦法,這樣如果datanode有掛掉節點,就會增加丟失塊的幾率。
具體降副本的命令如下:
hdfs dfs -setrep -R -w 2 hdfs://ns1/tmp/test.db

升副本的命令如下:

hdfs dfs -setrep -R -w 3 hdfs://ns1/tmp/test.db

上面的命令是將ns1下的/tmp/test.db副本數降至2個,然后又將它升至3哥副本。具體的hdfs dfs -setrep命令如下圖:

這樣動態的升降副本可以解決。

另外在升降副本的遇到一個BUG:

推測可能是namenode的replications模塊有夯住情況,所以出現該情況執行kill掉進行,跳過該塊再跑!

總結:之所以選擇使用升降副本是因為它不受帶寬的控制,另外在升降副本的時候hadoop是需要重新寫數的,這個時候它會優先往磁盤低寫數據,這樣就能將磁盤高的數據遷移至磁盤低的。

4、distcp

DistCp (distributed copy) is a tool used for large inter/intra-cluster copying. It uses MapReduce to effect its distribution, error handling and recovery, and reporting. It expands a list of files and directories into input to map tasks, each of which will copy a partition of the files specified in the source list. Its MapReduce pedigree has endowed it with some quirks in both its semantics and execution. The purpose of this document is to offer guidance for common tasks and to elucidate its model.

在這里舉一個例子:

通過distcp將/tmp/output12上的數據調用mapreduce遷移至/tmp/zhulh目錄下,原先/tmp/output12上的數據還是有存在的,但是它的塊就發生了變化。

這個時候有人可能會說怎么不使用cp命令呢?

兩者的區別如下:

CP的模式是不走mapreduce的;DISTCP的模式是走mapreduce的,所以它優先寫有nodemanager的機器;

CP是單線程的,類似scp的模式,在執行速度上比DISTCP要慢很多。

想了解更加詳細,請猛點這里

5、提高dfs.datanode.du.reserved值

官網是這么說的:Reserved space in bytes per volume. Always leave this much space free for non dfs use.

在上面的提到dfs.datanode.du.reserved的值是設成100G,因為namenode認為該節點還有剩余的空間,所以給分配到這里,假如這個塊是128K,但是實際剩余空間只有100K,所以就會報上面的錯誤,假如把dfs.datanode.du.reserved成300G,讓namenode知道該節點已經沒有剩余空間,所以就不會往這里寫數據了。

6、關閉nodemanger進程

在現有計算資源多余的情況下,可以考慮關閉高磁盤節點的nodemanager,避免在該節點起YarnChild,因為如果在該節點上進行計算的話,數據存儲首先會往本地寫一份,這樣更加加重了本地節點的負擔。

7、刪除舊數據

該方案是在迫不得已的情況下進行的,因為刪掉的數據可能以后還得補回來,這樣的話又是得要浪費一定的時間。

另外在刪除數據時候就得需要跳過回收站才能算是真正刪除,可以使用的命令如下:

三、方案選擇
考慮到有多達600台機器磁盤使用率達到94%,而且這部分高的機器是在同一個機房的,所以不能采用上下節點的方法,最好的辦法如下:
1、提高dfs.datanode.du.reserved的值;
2、關閉nodemanager進程;
3、升降副本;
4、開啟源碼的balance;
人工的定期觀察,當達到期望的效果的時候就是恢復成原樣;在提高dfs.datanode.du.reserved的值就得需要考慮到datanode需要進行輪詢的重啟,這個時候就考慮到時間間隔,如果時間過短就可能就丟,如果過長就是費的時間比較多。
 這種方法好比:比如在節假日的時候,某個收費口的車輛特別多,那個時候執法人員就會封閉這個收費站的出口,等車輛過的差不多的時候再給開放。這次的方案有這個有點類似,當主機的dfs.datanode.du.reserved值高於目前磁盤使用的情況,namenode就不會分配數據過來了,通過升降副本和balance能快速的將本機的數據轉移走。
四、結束語

本篇文章主要介紹了對hadoop數據出現不均衡情況下可以使用的方案,並以實例來解決問題!

對此有興趣的同學歡迎一起交流 。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM