distcp 병렬 복사
파일 글로빙을 통해 복수 파일 집합에 적용도 가능하지만 효율적인 병렬 처리를 원한다면 직접 프로그램을 작성하는 것이 좋다. 하둡은 병렬로 다량의 데이터를 하둡 파일시스템으로(부터) 복사하기 위한 distcp라는 유용한 프로그램을 제공한다.
distcp는 hadoop fs -cp를 대체하는 용도로도 쓰일 수 있다. 예를 들어 아래처럼 하나의 파일을 다른 파일로 복사할 수 있다.
% hadoop distcp file1 file2
디렉터리도 복사할 수 있다.
% hadoop distcp dir1 dir2
만약 dir2가 존재하지 않는다면 새롭게 생성될 것이고 dir1 디렉터리 안의 파일들이 복사될 것이다. 복수의 원본 경로 지정 또한 가능하다. 그 경우 모든 원본 경로의 냉요이 타깃 경로로 복사될 것이다.
만약 dir 디렉터리가 이미 존재한다면 dir1은 dir2 하위에 복사될 것이고 디렉터리 구조는 dir2/dir1 형태가 될 것이다. 이러한 방식을 원치 않는다면 -overwrite 옵션을 통해 동일한 타깃 디렉터리에 덮어쓰기 형태로 내용을 복사하는 것도 가능하다. 그리고 -update 옵션을 통해 변경이 이루어진 파일들만 복사할 수도 있다.
% hadoop distcp -update dir1 dir2
distcp 는 맵리듀스 잡으로 구현되어 있고 클러스터 전반에 걸쳐 병렬로 수행되는 맵 태스크를 이용하여 복사 작업을 한다. 여기에 리듀서는 없다. 각 파일은 단일 맵으로 복사되고 대체로 동일 할당으로 파일을 버킷팅함으로써 distcp는 거의 같은 양의 데이터를 각 맵에 제공하려 한다. 기본값으로 최대 20개의 맵이 사용되며, distcp의 -m 옵션을 통해 변경할 수 있다.
가장 일반적인 distcp 사용예로 두 HDFS 클러스터 간의 데이터 이동을 들 수 있다. 예를 들어 아래와 같은 명령을 통해 첫 번째 클러스터의 /foo 디렉터리를 두 번째 클러스터에 동일하게 백업하는 것이 가능하다.
% hadoop distcp -update -delete -p hdfs://namenode1/foo hdfs://namenode2/foo
-delete 옵션은 원본 경로에는 존재하지 않고 타깃 경로에만 존재하는 파일들을 지우도록 하는 옵션이다. 그리고 -p는 파일의 권한, 블록 사이즈 등의 파일 속성 정보를 복제 시 보전하려는 경우에 사용된다.
만약 두 클러스터가 서로 호환되지 않는 HDFS 버전으로 운영 중인 경우에는 두 클러스터 간의 distcp 에 있어 webhdfs 프로토콜을 이용할 수 있다.
% hadoop distcp webhdfs://namenode1:50070/foo webhdfs://namenode2:50070/foo
webhdfs 프로토콜을 이용하는 대신 HttpFs 프록시 방식으로 distcp의 소스 혹은 타깃을 변경할 수도 있다. 이는 방화벽을 설정하거나 대역폭을 설정할 수 있는 장점이 있다.
HDFS 클러스터 균형 유지
데이터를 HDFS로 복사할 때는 클러스터의 균형을 고려하는 것은 주요하다. HDFS는 클러스터 전반에 걸쳐 파일 블록이 고르게 분산되었을 때 가장 잘 동작한다. 따라서 distcp가 이러한 클러스터의 균형 유지를 방해하지 않도록 보장해야 한다. 예를 들어 -m 옵션 값으로 1을 지정하면 단일 맵이 복사를 수행하는데, 이는 느리고 클러스터 자원을 효율적으로 사용하지 못하는 문제를 떠나 복사 과정은 각 블록의 첫 번째 복제본이 단일 맵을 실행하는 노드에 저장되어야 한다(디스크가 꽉 찰 때까지)는 것을 의미한다. 두 번째와 세 번째 복제본은 클러스터를 넘나들며 분산되겠지만 첫 번째 복사본이 있는 노드는 불균형이 될 것이다. 이 문제는 클러스터에 노드보다 더 많은 맵을 할당함으로써 피할 수 있다. 이러한 이유로 distcp를 기본적으로 노드당 20개의 맵과 함께 수행하는 것이 가장 좋은 출발점이다.
클러스터가 불균형에서 벗어나는 것이 항상 가능하지는 않다. 아마도 다른 잡을 위해 일부 노드를 사용하려고 맵의 수를 제한하고 싶을지도 모른다. 이 경우 클러스터 전반에 걸쳐 블록 분산을 지속적으로 향상시키기 위한 balancer 도구를 사용할 수 있다.