hdfs balancer 는 DataNode 사이의 디스크 사용률 편차를 줄인다. 클러스터 평균 사용률을 구한 뒤, 평균에서 임계값(threshold) 이상 벗어난 노드만 대상으로 블록을 옮긴다. 전체 데이터를 재배치하지 않으며, 모든 노드가 임계값 안으로 들어오면 종료한다.
threshold 는 디스크 사용률의 백분율 편차다. CPU 나 네트워크 사용률과는 무관하다. 평균이 60% 이고 -threshold 10 이면 50~70% 안에 있는 노드는 손대지 않고, 72% 나 48% 인 노드가 대상이 된다. 기본값은 10 이다.
대역폭은 DataNode 당 값이며 단위는 초당 바이트다. 운영 중에는 재시작 없이 바꾸는 명령을 쓴다.
hdfs dfsadmin -setBalancerBandwidth 104857600
hdfs getconf -confKey dfs.datanode.balance.bandwidthPerSec
영구 반영은 hdfs-site.xml 에 둔다. 최신 Hadoop 3.x 의 기본값은 100m(약 100MB/s)이며, Hadoop 2.x 계열의 기본값은 1MB/s 로 사실상 거의 움직이지 않는 수준이었다. 오래된 클러스터에서 밸런싱이 며칠씩 걸린다면 이 값부터 확인한다.
<property>
<name>dfs.datanode.balance.bandwidthPerSec</name>
<value>104857600</value>
</property>
업무 시간에는 10~20MB/s, 야간에는 50~100MB/s 정도로 나눠 운용하는 사례가 많다. 값을 크게 잡으면 데이터 이동은 빨라지지만 같은 네트워크와 디스크를 쓰는 작업의 지연이 늘어난다.
hdfs balancer -policy datanode -threshold 5
hdfs balancer -source -f /tmp/hot_nodes.txt -threshold 5
hdfs balancer -exclude -f /tmp/exclude_nodes.txt
hdfs balancer -runDuringUpgrade
hdfs balancer -asService
| 옵션 | 뜻 |
|---|---|
-policy datanode |
노드 단위 사용률 기준(기본). blockpool 은 블록풀 단위 |
-threshold <n> |
평균 대비 허용 편차 백분율. 기본 10 |
-source |
데이터를 내보낼 노드를 한정 |
-include / -exclude |
대상 노드 포함 · 제외 |
-blockpools |
페더레이션 환경에서 특정 블록풀만 |
-idleiterations <n> |
진전 없는 반복이 n 회면 종료 |
-runDuringUpgrade |
롤링 업그레이드 중에도 실행 |
-asService |
데몬처럼 계속 실행 |
-D 로 넘기거나 hdfs-site.xml 에 둔다. 아래 값들은 대부분 이미 기본값이 충분히 큰 항목이라, 손대기 전에 현재 값을 먼저 확인한다.
| 키 | 기본값 | 뜻 |
|---|---|---|
dfs.balancer.movedWinWidth |
5400000 | 최근에 옮긴 블록을 기억하는 시간(ms). 90분 |
dfs.balancer.moverThreads |
1000 | 블록 이동을 수행하는 스레드 수 |
dfs.balancer.dispatcherThreads |
200 | 이동 작업을 분배하는 스레드 수 |
dfs.balancer.max-size-to-move |
10737418240 | 반복 한 번에 옮길 최대 바이트. 블록 하나의 크기 제한이 아니다 |
dfs.datanode.balance.max.concurrent.moves |
100 (Hadoop 3.x) | DataNode 하나가 동시에 처리할 이동 수. Hadoop 2.x 계열은 5 였다 |
hdfs balancer \
-Ddfs.balancer.movedWinWidth=5400000 \
-Ddfs.balancer.moverThreads=1000 \
-Ddfs.balancer.dispatcherThreads=200 \
-Ddfs.datanode.balance.max.concurrent.moves=10 \
-threshold 5
키 이름을 틀리기 쉬우니 주의한다. 대역폭 키는 dfs.balance.bandwidthPerSec 가 아니라 dfs.datanode.balance.bandwidthPerSec 이고, 윈도우 키는 moveWinWidth 가 아니라 movedWinWidth 이며, 실행 옵션은 -theshold 가 아니라 -threshold 다. 잘못 적으면 조용히 무시되고 기본값으로 돈다.
hdfs dfsadmin -report | egrep -i 'Name|DFS Used%|Remaining'
hdfs fsck / -files -blocks -locations | grep -E 'Under replicated|Mis-replicated'
밸런싱은 데이터가 많으면 수 시간에서 수일이 걸린다. 노드를 새로 추가한 직후에는 이동량이 특히 많다.
같은 클러스터라도 Kudu 는 HDFS 와 동작이 다르다. HDFS 는 디스크 사용률 기준으로 블록을 옮기지만, Kudu 리밸런서는 태블릿 개수를 기준으로 균등화한다. 용량 기준이 아니므로 크기가 큰 태블릿이 한쪽에 몰려 있어도 개수가 같으면 손대지 않는다.
또한 Kudu 에는 HDFS 의 dfs.datanode.balance.bandwidthPerSec 같은 대역폭 제한 옵션이 없다. 부하를 줄이려면 동시 이동 수를 제한한다.
sudo -u kudu kudu cluster rebalance master-01,master-02,master-03 \
--max_moves_per_server=2
--max_moves_per_server 의 기본값은 5 다. 태블릿 하나를 옮기는 작업은 전체 복사와 WAL 따라잡기, 이후 compaction 까지 동반하므로 개수가 적어도 태블릿이 크면 부하가 크다.