Hadoop集羣datanode磁盤不均衡的解決方案【轉】

1、引言:html

Hadoop的HDFS集羣很是容易出現機器與機器之間磁盤利用率不平衡的狀況,好比集羣中添加新的數據節點,節點與節點之間磁盤大小不同等等。當hdfs出現不平衡情況的時候,將引起不少問題,好比MR程序沒法很好地利用本地計算的優點,機器之間沒法達到更好的網絡帶寬使用率,機器磁盤沒法利用等等。
2、問題:
因業務須要搭建一個新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>

上面這個參數的意思:java

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

再查看datanode日誌,但願能找到可靠的線索:apache

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

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

爲了防止上面的報錯再次出現以及避免hdfs數據不均衡,對hadoop集羣作balance已經不可避免了!
2、解決方案
一、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.app

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

考慮到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提供了一個動態調整的命令:oop

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
 
 
二、上下節點:
其實將高磁盤的節點強制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從新啓動。ui

三、升降數據副本:
升降副本是一個無可奈何的辦法,這樣若是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是須要從新寫數的,這個時候它會優先往磁盤低寫數據,這樣就能將磁盤高的數據遷移至磁盤低的。

四、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要慢不少。

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

五、提升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知道該節點已經沒有剩餘空間,因此就不會往這裏寫數據了。

六、關閉nodemanger進程

在現有計算資源多餘的狀況下,能夠考慮關閉高磁盤節點的nodemanager,避免在該節點起YarnChild,由於若是在該節點上進行計算的話,數據存儲首先會往本地寫一份,這樣更加加劇了本地節點的負擔。

七、刪除舊數據

該方案是在無可奈何的狀況下進行的,由於刪掉的數據可能之後還得補回來,這樣的話又是得要浪費必定的時間。

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

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

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

對此有興趣的同窗歡迎一塊兒交流 。

相關文章
相關標籤/搜索