데이터노드 불균형과 hdfs balancer

맵리듀스 프레임워크는, 맵 태스크들을 스케줄링할 때 로컬리티를 최대한 지키면서(데이터를 가지고 있는 노드에 할당하면서) 처리를 진행한다.

그렇기 때문에 아무리 알고리즘을 잘 짜놨어도, 애초에 데이터노드에 불균형하게 블록들이 나뉘어 저장되어 있을 경우에는 데이터가 쏠린 노드가 많은 태스크를 처리하게 되는 것이다.

네임노드는 새로운 파일이나 블록의 저장 위치를 결정할 때, 이런 불균형 문제가 일어나지 않게 하기 위해 다양한 요소들을 고려한다.

  • 블록을 쓰려는 노드와 같은 데이터 노드에 레플리카 중 하나를 저장한다.

  • 다른 레플리카들에 대해서는, 전체 랙이 고장날 경우를 대비해 다른 랙에 저장한다.

  • 레플리카들 중 하나는 동일한 랙에 저장함으로써 네트워크 IO의 부담을 줄인다.

  • 클러스터 내의 데이터노드들에 최대한 균일하게 저장되도록 블록을 나눠 위치시킨다.


데이터노드들 사이에 최대한 균일하게 데이터들을 저장하려고 시도하지만, 위의 여러 사항들을 고려하다보니 이게 언제나 뜻대로 되는 것은 아니다.

맵리듀스 처리 결과로 한쪽에 데이터가 쏠리게 될 수도 있고, HBase 같은 경우에는 특정 노드에만 계속 write 해버릴 수도 있기 때문이다.

뿐만 아니라, 클라이언트의 로컬에서 데이터를 직접적으로 hdfs에 올리는 경우에는, 로컬리티를 지키는 방식 때문에 해당 데이터노드에만 모든 블록이 몰릴 수도 있다.

데이터노드가 추가되는 경우 역시 마찬가지로, 기존 hdfs 를 구성하던 데이터노드들에 잘 나뉘어져있던 데이터가, 밸런서 없이는 새로 추가된 노드에 자동으로 옮겨주지 않기 때문에 불균형이 일어난다.

이는 네임노드의 웹UI에서도 시각적으로 확인할 수 있는데, 디폴트로 9870 포트로 제공하는 페이지에 접속하여 데이터노드 정보를 확인해보면 노드들 간에 차지하는 용량이 차이가 나기도 한다.

이를 해결하기 위해서 하둡에서는 밸런서를 제공하며, hdfs balancer처럼 단순하게 실행시킬 수 있다.

그러나 이는 모든 옵션들을 기본값을 사용할 뿐이며, 아래와 같은 여러 옵션들을 지정해줄 수도 있다.

옵션내용
-policy [policy]datanode: 디폴트 정책으로, 각 데이터노드가 밸런싱 되어 있으면 클러스터를 밸런싱 되어있다고 봄
blockpool: 각 데이터노드에 있는 각 블록 풀들이 밸런싱 되어 있으면 클러스터를 밸런싱 되어있다고 봄
-threshold [threshold]디스크 용량에 대한 퍼센트값(디폴트 10퍼센트)으로, 각 노드간 차지하는 용량의 차이에 대한 수치
-exclude [-f hosts-file]
-exclude [comma-separated list of hosts]
밸런싱 과정에서 제외시킬 특정 데이터노드들에 대한 리스트.
-f 로 파일 형식으로 주거나, 쉼표로 구분하여 여러 노드들을 직접 입력할 수 있음
-include [-f hosts-file]
-include[comma-separated list of hosts]
밸런싱 과정에서 포함시킬 특정 데이터노드들에 대한 리스트.
-f 로 파일 형식으로 주거나, 쉼표로 구분하여 여러 노드들을 직접 입력할 수 있음
-source [-f hosts-file]
-include[comma-separated list of hosts]
소스 노드(데이터를 보내는)로 지정한 데이터노드들만 포함시킴.
-f 로 파일 형식으로 주거나, 쉼표로 구분하여 여러 노드들을 직접 입력할 수 있음
-blockpools [comma-separated list of blockpool ids]밸런서는 이 리스트에 포함된 블록 풀들에 대해서만 밸런싱을 수행
-idleiterations [iteration]종료할때까지 밸런싱을 수행할 최대 반복 횟수로, 디폴트 값은 5


예를 들어 옵션을 적용시켜 실행한다면, hdfs balancer -policy blockpool -threshold 3 -exclude h01,h02 -idleiterations 10와 같이 날리면 된다.