深入淺出:Hadoop的start-balancer.sh與hdfs balancer分佈式數據均衡

Hadoop的HDFS集羣非常容易出現機器與機器之間磁盤利用率不平衡的情況,比如集羣中添加新的數據節點。當HDFS出現不平衡狀況的時候,將引發很多問題,比如:
1、MR程序無法很好地利用本地計算的優勢
2、機器之間無法達到更好的網絡帶寬使用率,機器磁盤無法利用等等。可見,保證HDFS中的數據平衡是非常重要的。
在Hadoop中,包含一個Balancer程序,通過運行這個程序,可以使得HDFS集羣達到一個平衡的狀態,使用這個程序的命令如下:

$HADOOP_HOME/bin/start-balancer.sh –t 10%

這個命令中-t參數後面跟的是HDFS達到平衡狀態的磁盤使用率偏差值。如果機器與機器之間磁盤使用率偏差小於10%,那麼我們就認爲HDFS集羣已經達到了平衡的狀態。
Hadoop的開發人員在開發Balancer程序的時候,遵循了以下幾點原則:
1.在執行數據重分佈的過程中,必須保證數據不能出現丟失,不能改變數據的備份數,不能改變每一個rack中所具備的block數量。(這個原則導致了不同rack機櫃之間的數據是不能移動的
2.系統管理員可以通過一條命令啓動數據重分佈程序或者停止數據重分佈程序。
3.Block在移動的過程中,不能暫用過多的資源,如網絡帶寬。
4.數據重分佈程序在執行的過程中,不能影響name node的正常工作。

集羣執行balancer依舊不平衡的原因
基於這些基本點,目前Hadoop數據重分佈程序實現的邏輯流程如下圖所示:

Name Node <------------------------------->Rebalancing Server<-------------------------------->Proxy source data node
/| /|\

|                                                                                                 |
|                                                                                                 |
+----------------------------------->destination data node<---------------------------------------+

Rebalance程序作爲一個獨立的進程與name node進行分開執行。
1 Rebalance Server從Name Node中獲取所有的Data Node情況:每一個Data Node磁盤使用情況。
2 Rebalance Server計算哪些機器需要將數據移動,哪些機器可以接受移動的數據。並且從Name Node中獲取需要移動的數據分佈情況。
3 Rebalance Server計算出來可以將哪一臺機器的block移動到另一臺機器中去。
4,5,6 需要移動block的機器將數據移動的目的機器上去,同時刪除自己機器上的block數據。
7 Rebalance Server獲取到本次數據移動的執行結果,並繼續執行這個過程,一直沒有數據可以移動或者HDFS集羣以及達到了平衡的標準爲止。

Hadoop現有的這種Balancer程序工作的方式在絕大多數情況中都是非常適合的。
現在我們設想這樣一種情況:
1 數據是3份備份。
2 HDFS由2個rack(機櫃)組成。
3 2個rack中的機器磁盤配置不同,第一個rack(機櫃)中每一臺機器的磁盤空間爲1TB,第二個rack(機櫃)中每一臺機器的磁盤空間爲10TB。
4 現在大多數數據的2份備份都存儲在第一個rack(機櫃)中。
在這樣的一種情況下,HDFS級羣中的數據肯定是不平衡的。現在我們運行Balancer程序,但是會發現運行結束以後,整個HDFS集羣中的數據依舊不平衡:rack1中的磁盤剩餘空間遠遠小於rack2。這是因爲Balance程序的開發原則1導致的。
簡單的說,就是在執行Balancer程序的時候,不會將數據中一個rack(機櫃)移動到另一個rack中(機櫃),所以就導致了Balancer程序永遠無法平衡HDFS集羣的情況。
針對於這種情況,可以採取2中方案:
1 繼續使用現有的Balancer程序,但是修改rack中的機器分佈。將磁盤空間小的機器分叉到不同的rack中去。
2 修改Balancer程序,允許改變每一個rack中所具備的block數量,將磁盤空間告急的rack中存放的block數量減少,或者將其移動到其他磁盤空間富餘的rack中去。(不推薦)

1.傳輸帶寬
對hdfs負載設置均衡,因爲默認的數據傳輸帶寬比較低,可以設置爲64M,
即hdfs dfsadmin -setBalancerBandwidth 67108864即可

[root@sht-sgmhadoopnn-01 ~# cd /hadoop/hadoop-2.7.2/bin
[root@sht-sgmhadoopdn-01 bin# ./hdfs dfsadmin -setBalancerBandwidth 67108864
Balancer bandwidth is set to 67108864 for sht-sgmhadoopnn-01/172.16.101.55:8020
Balancer bandwidth is set to 67108864 for sht-sgmhadoopnn-02/172.16.101.56:8020

2.節點存儲使用率偏差
默認balancer的threshold爲10%,即各個節點存儲使用率偏差不超過10%,我們可將其設置爲5%;然後啓動Balancer,sbin/start-balancer.sh -threshold 5,等待集羣自均衡完成即可

[root@sht-sgmhadoopdn-01 bin# cd ../sbin
starting balancer, logging to /hadoop/hadoop-2.7.2/logs/hadoop-root-balancer-sht-sgmhadoopnn-01.telenav.cn.out
[root@sht-sgmhadoopnn-01 sbin# ./start-balancer.sh -threshold 5
starting balancer, logging to /hadoop/hadoop-2.7.2/logs/hadoop-root-balancer-sht-sgmhadoopnn-01.telenav.cn.out

運行這個命令start-balancer.sh -threshold 5和使用hdfs balancer -threshold 5是一樣的

Usage: hdfs balancer

[root@sht-sgmhadoopnn-01 bin# ./hdfs balancer -threshold 5
16/03/05 18:57:33 INFO balancer.Balancer: Using a threshold of 1.0
16/03/05 18:57:33 INFO balancer.Balancer: namenodes = [hdfs://mycluster
16/03/05 18:57:33 INFO balancer.Balancer: parameters = Balancer.Parameters[BalancingPolicy.Node, threshold=1.0, max idle iteration = 5, number of nodes to be excluded = 0, number of nodes to be included = 0
Time Stamp Iteration# Bytes Already Moved Bytes Left To Move Bytes Being Moved
16/03/05 18:57:34 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
16/03/05 18:57:35 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.58:50010
16/03/05 18:57:35 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.60:50010
16/03/05 18:57:35 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.66:50010
16/03/05 18:57:35 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.59:50010
16/03/05 18:57:35 INFO balancer.Balancer: 0 over-utilized: [
16/03/05 18:57:35 INFO balancer.Balancer: 0 underutilized: [
The cluster is balanced. Exiting...
Mar 5, 2016 6:57:35 PM 0 0 B 0 B -1 B
Mar 5, 2016 6:57:35 PM Balancing took 2.66 seconds

1).爲什麼我執行該命令hdfs balancer -threshold 5平衡數據命令沒有反應呢?5表示5%,

羣總存儲使用率: 1.74%
sht-sgmhadoopdn-01: 1.74%
sht-sgmhadoopdn-02: 1.74%
sht-sgmhadoopdn-03: 1.74%
sht-sgmhadoopdn-04: 0%
執行-threshold 5, 表示每一個 datanode 存儲使用率和集羣總存儲使用率的差值都應該小於這個閥值5%;
假如超過5%,會執行數據平衡操作。

B. 2).怎樣判斷執行命令是否會生效,數據平衡操作?

if (羣總存儲使用率 — 每一臺datanode 存儲使用率) > -threshold 5

  #會執行數據平衡

else

  #該命令不生效

end if
C. 3).the threshold range of [1.0, 100.0],所以最小隻能設置 -threshold 1

D. 4).balance命令可以執行早namenode或者datanode節點上

  1. 執行命令hdfs balancer -threshold 2
    點擊(此處)摺疊或打開

[root@sht-sgmhadoopnn-01 hadoop# hdfs balancer -threshold 2
……………..
……………..
16/03/08 16:08:09 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.59:50010
16/03/08 16:08:09 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.58:50010
16/03/08 16:08:09 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.66:50010
16/03/08 16:08:09 INFO net.NetworkTopology: Adding a new node: /default-rack/172.16.101.60:50010
16/03/08 16:08:09 INFO balancer.Balancer: 0 over-utilized: [
16/03/08 16:08:09 INFO balancer.Balancer: 0 underutilized: [
The cluster is balanced. Exiting...
Mar 8, 2016 4:08:09 PM 1 382.22 MB 0 B -1 B
Mar 8, 2016 4:08:09 PM Balancing took 6.7001 minutes

新增數據節點的411.7M,偏差小於2%。

start-balancer.sh和stop-balancer.sh的源碼解析:

[root@sht-sgmhadoopnn-01 sbin]# more start-balancer.sh

!/usr/bin/env bash

bin=dirname "${BASH_SOURCE-$0}"
bin=cd "$bin"; pwd
DEFAULT_LIBEXEC_DIR="$bin"/../libexec
HADOOP_LIBEXEC_DIR=${HADOOP_LIBEXEC_DIR:-$DEFAULT_LIBEXEC_DIR}
. $HADOOP_LIBEXEC_DIR/hdfs-config.sh

Start balancer daemon.

"$HADOOP_PREFIX"/sbin/hadoop-daemon.sh --config $HADOOP_CONF_DIR --script "$bin"/hdfs start balancer $@
解析:start-balancer.sh腳本其實最終還是調用hdfs start balancer $@ 命令,對於 $@ 是指shell腳本運行的傳遞的參數列表,一般參數爲-threshold 5

[root@sht-sgmhadoopnn-01 sbin# more stop-balancer.sh

!/usr/bin/env bash

bin=dirname "${BASH_SOURCE-$0}"
bin=cd "$bin"; pwd
DEFAULT_LIBEXEC_DIR="$bin"/../libexec
HADOOP_LIBEXEC_DIR=${HADOOP_LIBEXEC_DIR:-$DEFAULT_LIBEXEC_DIR}
. $HADOOP_LIBEXEC_DIR/hdfs-config.sh

Stop balancer daemon.

Run this on the machine where the balancer is running

"$HADOOP_PREFIX"/sbin/hadoop-daemon.sh --config $HADOOP_CONF_DIR --script "$bin"/hdfs stop balancer
解析:stop-balancer.sh腳本其實最終還是調用hdfs stop balancer命令
[root@sht-sgmhadoopnn-01 sbin#

注意事項:
由於歷史原因,hadoop集羣中的機器的磁盤空間的大小各不相同,而HDFS在進行寫入操作時,並沒有考慮到這種情況,所以隨着數據量的逐漸增加,磁盤較小的datanode機器上的磁盤空間很快將被寫滿,從而觸發了報警。
此時,不得不手工執行start-balancer.sh來進行balance操作,即使將dfs.balance.bandwidthPerSec 參數設置爲10M/s,整個集羣達到平衡也需要很長的時間,所以寫了個crontab來每天凌晨來執行start-balancer.sh,由於此時集羣不平衡的狀態還沒有那麼嚴重,所以start-balancer.sh很快執行結束了。
另外需要注意的地方是,由於HDFS需要啓動單獨的Rebalance Server來執行Rebalance操作,所以儘量不要在NameNode上執行start-balancer.sh,而是找一臺比較空閒的機器。
理論參考:http://www.aboutyun.com/thread-7354-1-1.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章