사례 연구: HDFS(Hadoop 분산 파일 시스템)

완료됨

MapReduce 프로그래밍 모델을 사용하면 두 함수, 즉 map 및 reduce를 기준으로 구성된 계산 작업을 수행할 수 있습니다. 입력이 키-값 쌍으로 MapReduce에 들어간 다음, map 함수를 통해 처리되고 reduce 함수로 전달됩니다. 그런 다음, reduce 작업이 결과를 생성하는데 역시 키-값 쌍의 형태입니다. MapReduce는 많은 맵 인스턴스와 reduce 작업을 대량 계산 클러스터에서 병렬로 실행하기 위해 설계되었습니다. MapReduce 프로그래밍 모델은 이후 모듈에서 자세히 설명합니다.

MapReduce 프로그래밍 모델은 단일 네임스페이스로 클러스터의 모든 노드에서 사용할 수 있는 분산 스토리지 시스템의 가용성을 가정하는데 여기에 DFS(분산 파일 시스템)가 개입됩니다. DFS는 MapReduce 클러스터의 노드와 함께 배치됩니다. DFS는 MapReduce와 나란히 작동하도록 설계되었으며 전체 MapReduce 클러스터에 대한 단일 네임스페이스를 유지합니다.

Apache Hadoop이라는 오픈 소스 버전의 MapReduce는2 빅 데이터 분야에서 매우 인기가 있습니다. HDFS는 오픈 소스 DFS입니다. HDFS는 주로 MapReduce 프로그래밍 모델의 요구에 맞춘 확장 가능한 내결함성 분산 파일 시스템으로 설계되었습니다. 비디오 4.12에서는 HDFS를 소개합니다.

HDFS는 POSIX와 호환되지 않으며 그 자체로 탑재 가능한 파일 시스템이 아니라는 점에 유의해야 합니다. HDFS는 일반적으로 HDFS 클라이언트를 통해 액세스하거나 Hadoop 라이브러리에서 API(애플리케이션 프로그래밍 인터페이스) 호출을 사용하여 액세스합니다. 그러나 (HDFS)용 FUSE(File system in User SpacE) 드라이버의 개발로 UNIX와 같은 운영 체제에서 가상 디바이스로 탑재할 수 있게 되었습니다.

HDFS 아키텍처

앞서 설명한 것처럼 HDFS는 노드의 클러스터에서 실행되도록 설계되었고 다음과 같은 목표로 설계된 DFS입니다.

  • 단일한 클러스터 전체의 공통 네임스페이스
  • 큰 파일을 저장하는 기능(예: 테라바이트 또는 페타바이트)
  • MapReduce 프로그래밍 모델에 대한 지원
  • 한 번 쓰기, 여러 번 읽기 데이터 액세스 패턴을 위한 데이터 액세스 스트리밍
  • 상용 하드웨어를 사용한 고가용성

다음 그림은 HDFS 클러스터를 보여 줍니다.

HDFS 아키텍처

그림 1: HDFS 아키텍처

HDFS는 마스터-종속 디자인을 따릅니다. 마스터 노드를 NameNode라고 합니다. NameNode는 전체 클러스터에 대한 메타데이터 관리를 처리하고 HDFS에 저장된 모든 파일에 대해 단일 네임스페이스를 유지합니다. 종속 노드를 DataNodes라고 합니다. DataNodes는 실제 데이터 블록을 각 노드 내의 로컬 파일 시스템에 저장합니다.

HDFS의 파일은 각각 128MB의 기본 크기를 사용하는 블록(청크라고도 함)으로 분할됩니다. 반면, 일반적으로 로컬 파일 시스템의 블록 크기는 4KB입니다. HDFS는 MapReduce 작업을 처리하는 데 효율적인 방식으로 매우 큰 파일을 저장하도록 설계되었기 때문에 큰 블록 크기를 사용합니다.

MapReduce의 단일 맵 작업은 기본적으로 단일 HDFS 블록에서 독립적으로 작동하도록 구성되므로 여러 개의 맵 작업에서 여러 HDFS 블록을 병렬로 처리할 수 있습니다. 블록 크기가 너무 작은 경우 많은 수의 맵 작업을 클러스터의 노드 간에 분산해야 하며, 이렇게 하면 오버헤드로 인해 성능이 저하될 수 있습니다. 한편 블록이 너무 크면 파일을 병렬로 처리할 수 있는 맵 작업 수가 감소하여 병렬 처리에 영향을 줄 수 있습니다. HDFS를 사용하면 파일별로 블록 크기를 지정하여 사용자가 원하는 병렬 처리 수준을 달성할 수 있도록 블록 크기를 튜닝할 수 있습니다. MapReduce와 HDFS의 상호 작용은 이후 모듈에서 자세히 설명합니다.

또한 HDFS는 개별 노드의 오류를 허용하도록 설계되었기 때문에 데이터 중복성을 제공하기 위해 데이터 블록이 노드에 걸쳐 복제됩니다. 이 프로세스는 다음 섹션에서 자세히 설명합니다.

HDFS의 클러스터 토폴로지

Hadoop 클러스터는 이전 모듈에 설명한 대로 일반적으로 팻 트리 토폴로지를 사용하여 연결된 여러 랙의 서버로 구성된 데이터 센터에 배포됩니다. 이를 위해 HDFS는 성능 및 내결함성에 영향을 주는 블록 배치 결정을 내리는 데 도움이 되는 클러스터 토폴로지 인식을 사용하여 설계되었습니다. 일반적인 Hadoop 클러스터에는 랙 전용 기가비트 스위치 및 코어 스위치나 라우터로의 업링크가 포함된 랙당 30~40대의 서버가 있으며, 다음 그림에 나오는 것처럼 데이터 센터의 많은 랙 간에 대역폭이 공유됩니다.

HDFS 클러스터 토폴로지.

그림 2: HDFS 클러스터 토폴로지

Hadoop은 한 랙의 노드 내에서 집계 대역폭이 여러 랙의 노드에 걸쳐 집계된 대역폭보다 높다고 가정한다는 점에 주목해야 합니다. 이 가정에서 데이터 액세스 및 복제본 배치(다음 섹션에 설명됨)에 대한 Hadoop의 설계가 탄생합니다.

클러스터에 HDFS가 배포되면 시스템 관리자는 이를 각 노드를 클러스터의 특정 랙에 매핑하는 토폴로지 설명으로 구성할 수 있습니다. 네트워크 거리는 으로 측정되며, 1홉은 토폴로지의 한 링크에 해당합니다. Hadoop은 트리 스타일 토폴로지를 가정하며, 두 노드 간의 거리는 가장 가까운 공통 상위 항목까지의 거리 합계입니다.

그림 2의 예에서 노드 1과 자체의 거리는 0홉입니다(두 프로세스가 동일한 노드에서 통신하는 경우). 노드 1과 노드 2 사이의 거리는 2홉이지만 노드 3과 노드 4 사이의 거리는 4홉입니다.

다음 비디오는 HDFS의 파일 읽기 및 쓰기 작업을 소개합니다.

HDFS의 파일 읽기.

그림 3: HDFS의 파일 읽기

그림 3은 HDFS의 파일 읽기 프로세스를 보여 줍니다. HDFS 클라이언트(파일에 액세스해야 하는 엔터티)는 파일을 읽기용으로 열 때 먼저 NameNode에 연결합니다. 그런 다음, NameNode는 파일의 블록 위치 목록을 클라이언트에 제공합니다. 또한 Hadoop은 블록이 노드에 복제되는 것으로 가정하므로 NameNode는 특정 블록의 위치를 제공할 때 실제로 클라이언트에 가장 가까운 블록을 찾습니다. 집약성은 다음의 순서로 결정됩니다(집약성 감소의 순). 즉, 클라이언트와 동일한 노드 내에 있는 블록, 클라이언트와 동일한 랙에 있는 블록, 클라이언트에 대한 랙에서 벗어난 블록 순서입니다.

블록 위치가 결정되면 클라이언트는 각 DataNode에 대한 직접 연결을 열고 DataNode에서 클라이언트 프로세스로 데이터를 스트리밍합니다. 이 프로세스는 HDFS 클라이언트가 데이터 블록에서 읽기 작업을 호출할 때 수행됩니다. 따라서 클라이언트에서 계산을 시작하여 계산과 통신을 인터리빙하기 전에는 블록 전체를 전송할 필요가 없습니다. 클라이언트가 첫 번째 블록을 다 읽으면 나머지 블록에 대해서도 이 프로세스를 반복하며, 모든 블록을 다 읽으면 파일을 닫습니다.

클라이언트는 DataNode에 연결하여 직접 데이터를 검색해야 한다는 점을 유의해야 합니다. 이 연결을 통해 HDFS는 동시 병렬 데이터 읽기를 위해 많은 수의 동시 클라이언트로 확장할 수 있습니다.

HDFS에서 파일 쓰기는 파일 읽기와 다릅니다(그림 4). HDFS에 데이터를 써야 하는 클라이언트는 먼저 NameNode에 연결한 다음에 파일 생성을 알립니다. NameNode는 파일이 이미 있는지 확인하고 클라이언트에 파일을 만들 수 있는 권한이 있는지 인증합니다. 검사를 통과하면 NameNode는 새 파일의 레코드를 만듭니다.

HDFS의 파일 쓰기.

그림 4: HDFS의 파일 쓰기

그런 다음, 클라이언트는 내부 데이터 큐에 파일을 쓰고 클러스터에서 DataNodes의 블록 위치에 대한 NameNode를 요청합니다. 그런 다음, 내부 큐의 블록이 파이프라인 방식으로 개별 DataNodes에 전송됩니다. 첫 번째 DataNode에 블록을 쓰면 블록의 복제본을 쓰기 위해 블록을 다른 DataNodes로 파이프라인합니다. 따라서 블록은 파일 쓰기 중에 복제됩니다. HDFS는 해당 파일에 대한 모든 복제본을 DataNodes에 쓸 때까지 클라이언트에 대한 쓰기를 승인하지 않습니다(그림 4.28의 5단계).

또한 Hadoop은 복제본을 배치하는 동안 랙 집약성이라는 개념을 사용합니다. 데이터 블록은 기본적으로 HDFS에서 3번 복제됩니다. HDFS는 블록을 쓰는 클라이언트와 동일한 노드에 첫 번째 복제본을 배치하려고 시도합니다. 클라이언트 프로세스가 HDFS 클러스터에서 실행되고 있지 않은 경우 노드가 임의로 선택됩니다. 두 번째 복제본을 첫 번째(랙에서 해제)에서 다른 랙에 있는 노드에 씁니다. 그러면 블록의 세 번째 복제본을 두 번째와 동일한 랙에 있는 다른 임의의 노드에 씁니다. 추가 복제본을 클러스터의 임의 노드에 쓰지만 시스템에서 동일한 랙에 너무 많은 복제본을 배치하는 것을 방지합니다. 그림 5는 HDFS에서 3번 복제된 블록에 대한 복제본 배치를 보여 줍니다. HDFS에서 복제본을 배치하는 기본 개념은 노드 및 랙 오류를 허용할 수 있도록 하는 것입니다. 예를 들어 전원 또는 네트워킹 문제로 인해 전체 랙이 오프라인 상태가 되면 요청된 블록을 다른 랙에 배치할 수 있습니다.

HDFS에서 삼중 복제된 블록에 대한 복제본 배치.

그림 5: HDFS에서 3번 복제된 블록에 대한 복제본 배치

동기화: 의미 체계

HDFS의 의미 체계가 약간 바뀌었습니다. HDFS의 초기 버전은 엄격하게 변경할 수 없는 의미 체계를 따랐습니다. 이전 버전의 HDFS에서 파일을 쓴 후에는 쓰기를 위해 다시 열 수 없었습니다. 그래도 파일 삭제는 가능했습니다. 하지만 현재 버전의 HDFS는 제한된 방식으로 추가를 지원합니다. HDFS에 쓴 기존 이진 데이터를 수정할 수 없다는 점에서는 여전히 제한적입니다.

HDFS에서 이러한 디자인을 선택한 이유는 가장 일반적인 일부 MapReduce 워크로드가 한 번 작성, 여러 번 읽기의 데이터 액세스 패턴을 따랐기 때문입니다. MapReduce는 미리 정의된 단계를 포함하는 제한된 계산 모델이며, MapReduce에서 리듀서의 결과로 HDFS에 대한 독립적 파일이 출력으로 작성됩니다. HDFS는 한 번에 여러 클라이언트에 대한 동시적인 고속 읽기 액세스에 초점을 맞춥니다.

일관성 모델

HDFS는 강력하게 일관된 파일 시스템입니다. 각 데이터 블록은 여러 노드에 복제되지만 모든 복제본을 성공적으로 쓴 후에만 쓰기 성공이 선언됩니다. 따라서 파일을 작성하는 즉시 모든 클라이언트에 파일이 표시되고 모든 클라이언트에서 파일의 보기는 동일하게 됩니다. 파일의 수명 동안 한 번만 쓰기용으로 열 수 있으므로 HDFS의 변경할 수 없는 의미 체계를 사용하면 일관성을 비교적 쉽게 구현할 수 있습니다.

HDFS의 내결함성

HDFS의 기본 내결함성 메커니즘은 복제입니다. 앞에서 설명한 것처럼 HDFS에 쓰인 모든 블록은 세 번 복제되지만 필요한 경우 파일 단위로 사용자가 변경할 수 있습니다.

NameNode는 하트비트 메커니즘을 통해 DataNodes를 추적합니다. 각 DataNode는 정기적 하트비트 메시지(몇 초마다)를 NameNode에 보냅니다. DataNode가 정지된 경우 NameNode에 대한 하트비트가 중지됩니다. NameNode는 누락된 하트비트 메시지 수가 특정 임계값에 도달할 경우 DataNode가 사망했음을 감지합니다. 그러면 NameNode는 DataNode를 비활성으로 표시하고 해당 DataNode에 대한 I/O 요청을 더 이상 전달하지 않습니다. 해당 DataNode에 저장된 블록은 다른 DataNodes에 추가 복제본이 있어야 합니다. 또한 NameNode는 파일 시스템에 대한 상태 검사를 수행하여 복제본 미달 블록을 검색하고 클러스터 균형 조정 프로세스를 수행하여 원하는 수의 복제본보다 작은 블록에 대한 복제를 시작합니다.

NameNode는 HDFS에서 SPOF(단일 실패 지점)가 됩니다. NameNode에 장애가 발생하면 전체 파일 시스템이 중단되기 때문입니다. 내부적으로 NameNode는 파일 시스템의 상태를 저장하는 두 개의 디스크에 있는 데이터 구조, 즉 이미지 파일편집 로그를 유지합니다. 이미지 파일은 특정 시점의 파일 시스템 메타데이터에 대한 검사점이지만 편집 로그는 이미지 파일이 마지막으로 만들어진 이후 파일 시스템 메타데이터의 모든 트랜잭션에 대한 로그입니다. 파일 시스템 메타데이터에 대해 들어오는 모든 변경 내용은 편집 로그에 기록됩니다. 정기적으로 편집 로그 및 이미지 파일은 병합되어 새 이미지 파일 스냅샷을 생성하며 편집 로그는 지워집니다. 그러나 NameNode 오류가 발생하는 경우 메타데이터는 사용할 수 없게 되며 파일 메타데이터가 손실되기 때문에 NameNode의 디스크 오류는 치명적일 수 있습니다.

NameNode에서 메타데이터를 백업하기 위해 HDFS에서는 NameNode에서 이미지 파일을 주기적으로 복사하는 보조 NameNode를 만들 수 있습니다. 이러한 복사본은 NameNode의 데이터 손실 시 파일 시스템을 복구하는 데 도움이 되지만 NameNode의 편집 로그에 있던 최종 몇 가지 변경 내용은 손실됩니다. 최신 버전의 Hadoop에서 진행 중인 작업의 목표는 NameNode의 오류 시 자동으로 넘겨받을 수 있는 완전한 여분 보조 NameNode를 만드는 것입니다.

HDFS의 실제 응용

HDFS는 map 및 reduce 작업을 위한 DFS를 제공하여 주로 Hadoop MapReduce 작업을 지원하도록 설계되었지만 빅 데이터 도구를 통해 HDFS를 수없이 활용되고 있습니다.

HDFS는 Pig, Hive, HBase 및 Giraph를 비롯하여 Hadoop 프레임워크를 기반으로 구축되는 여러 Apache 프로젝트에서 사용됩니다 HDFS는 GraphLab과 같은 다른 프로젝트에서도 지원됩니다

HDFS의 주요 장점은 다음과 같습니다.

  • MapReduce 워크로드에 대한 높은 대역폭: 대규모 Hadoop 클러스터(수천 대의 머신)는 HDFS를 사용하여 초당 최대 1테라바이트까지 지속적으로 작성하는 것으로 알려져 있습니다.
  • 높은 안정성: 내결함성은 HDFS의 기본 디자인 목표입니다. HDFS 복제는 특히 디스크 및 서버의 오류 가능성이 크게 증가하는 대규모 클러스터에서 뛰어난 안정성과 가용성을 제공합니다.
  • 바이트당 저렴한 비용: SAN과 같은 전용 공유 디스크 솔루션과 비교할 때 HDFS는 스토리지가 컴퓨팅 서버와 함께 배치되므로 기가바이트당 비용이 줄어듭니다. SAN을 사용하는 경우 하드웨어 오류를 관리하기 위해 디스크 배열 엔클로저 및 고급 엔터프라이즈 디스크와 같은 관리형 인프라에 추가 비용을 지불해야 합니다. HDFS는 상용 하드웨어에서 실행되도록 설계되었으며 오류 허용을 위해 중복성이 소프트웨어 내에서 관리됩니다.
  • 확장성: HDFS를 사용하면 실행 중인 클러스터에 DataNodes를 추가할 수 있으며, 클러스터 노드가 추가될 때 파일 시스템을 종료하지 않고도 데이터 블록의 균형을 수동으로 다시 조정하는 도구를 제공합니다.

HDFS의 주요 단점은 다음과 같습니다.

  • 작은 파일 비효율성: HDFS는 큰 블록 크기(64MB 이상)로 사용하도록 설계되었습니다. 따라서 대용량 파일(수백 메가바이트, 기가바이트 또는 테라바이트)을 블록으로 청크하여 병렬 처리를 위해 MapReduce 작업에 공급할 수 있습니다. 따라서 파일 크기가 작으면(킬로바이트 범위 내) HDFS는 비효율적입니다. 작은 파일 수가 많으면 파일 시스템의 모든 파일에 대한 메타데이터를 유지해야 하므로 NameNode에 추가 스트레스가 발생합니다. 일반적으로 HDFS 사용자는 시퀀스 파일 등의 기술을 사용하여 여러 작은 파일을 더 큰 파일로 결합합니다.
  • POSIX 비규격: HDFS는 POSIX 호환 탑재 가능 파일 시스템으로 설계되지 않았습니다. 애플리케이션은 HDFS 클라이언트를 사용하도록 처음부터 작성하거나 수정해야 합니다. FUSE 드라이버를 사용하여 HDFS를 탑재할 수 있는 해결 방법이 있지만, 파일 시스템 의미 체계는 파일이 닫힌 후에는 파일에 대한 쓰기를 허용하지 않습니다.
  • 한 번 쓰기 모델: 한 번 쓰기 모델은 같은 파일에 대한 동시 쓰기 액세스를 필요로 하는 애플리케이션에는 잠재적인 단점으로 작용합니다. 그러나 최신 버전의 HDFS는 이제 파일 추가를 지원합니다.

간단히 말해서 HDFS는 MapReduce 모델을 따르거나 HDFS를 사용하도록 특별히 작성된 분산 애플리케이션을 위한 스토리지 백 엔드 옵션으로 적합합니다. HDFS는 다수의 작은 파일보다는 적은 수의 큰 파일을 효율적으로 사용할 수 있습니다.


참고자료

  1. Sanjay Ghemawat, Howard Gobioff, and Shun-Tak Leung (2003). The Google File Systems 19th ACM Symposium on Operating Systems Principles
  2. White, Tom (2012). Hadoop: The Definitive Guide O'Reilly Media, Yahoo Press

지식 점검

1.

로컬 파일 시스템에 대한 HDFS의 이점은 무엇인가요?

2.

HDFS는 언제 디스크에 쓰기를 커밋하나요?

3.

HDFS에서 제공하는 일관성 모델의 종류는 무엇인가요?