반응형

HDFS에서 데이터가 어떻게 쓰여지는지에 대한 프로세스에 대해서 정리하도록 하겠습니다.


해당 내용은 '하둡 완벽 가이드(4판)'을 정리한 내용입니다.


[ HDFS 파일 쓰기 상세 ]

1. 클라이언트는 DistributedFileSystem의 create()를 호출하여 파일을 생성합니다.

2. DistributedFileSystem은 파일시스템의 네임스페이스에 새로운 파일을 생성하기 위해 네임노드에 RPC 요청을 보냅니다. 이때 블록에 대한 정보는 보내지 않습니다. 네임노드는 요청한 파일과 동일한 파일이 이미 존재하는지, 클라이언트가 파일을 생성할 권한을 가지고 있는지 등 다양한 검사를 수행합니다. 검사를 통과하면 네임노드는 새로운 파일의 레코드를 만들고, 그렇지 않으면 파일 생성은 실패하고 클라이언트의 IOException이 발생합니다. DistributedFileSystem은 데이터를 쓸 수 있도록 클라이언트에 FSDataOutputStream을 반환하고 읽을 때와 마찬가지로 FSDataOutputStream은 데이터노드와 네임노드의 통신을 처리하는 DFSOutputStream으로 래핑됩니다.

3. 클라이언트가 데이터를 쓸 때 DFSOutputStream은 데이터를 패킷으로 분리하고, 데이터 큐라 불리는 내부 큐로 패킷을 보냅니다.  DataStreamer는 데이터 큐에 있는 패킷을 처리하고 먼저 네임노드에 복제본을 저장할 데이터노드의 목록을 요청합니다. 데이터노드 목록에 포함된 노드는 파이프라인을 형성하는데, 복제 수준이 3이면 세 개의 노드가 파이프라인에 속하게 됩니다.

4. Datastreamer는 파이프라인의 첫 번째 데이터노드로 패킷을 전송하고 첫 번째 데이터 노드는 각 패킷을 저장하고 파이프라인의 세 번째(마지막) 데이터노드로 전달합니다.

5. DFSOutputStream은 데이터노드의 승인 여부를 기다리는 ack큐라 불리는 내부 패킷 큐를 유지하고 ack큐에 있는 패킷은 파이프라인의 모든 데이터노드로부터 ack 응답을 받아야 제거됩니다. 

6. 데이터 쓰기를 완료할 때 클라이언트는 스트림에 close() 메서드를 호출합니다. 이 메서드는 데이터노드 파이프라인에 남아 있는 모든 패킷을 플러시(flush)하고 승인이 나기를 기다립니다.

7. 모든 패킷이 완전히 전송되면 네임노드에 '파일 완료' 신호를 보냅니다. 네임노드는 DataStreamer를 통해 블록 할당 요청을 받았기 때문에 파일의 블록이 어떻게 구성되어 있는지 이미 알고 있으며, 최소한의 블록 복제가 완료되기를 기다렸다가 최종적으로 성공 신호를 반환합니다. 


[ 데이터를 쓰는 도중 데이터노드 장애 발생시 ]

1. 파이프라인이 닫히고 ack큐에 있는 모든 패킷은 데이터 큐 앞쪽에 다시 추가됩니다.

2. 이렇게 하면 다운스트림(downstream)노드가 실패해도 패킷이 하나도 유실되지 않고 정상 데이터노드는 네임노드로 부터 새로운 ID를 다시 받습니다.

3. 장애가 발생한 데이터노드가 나중에 다시 복구되면 불완전한 블록은 삭제됩니다. 

4. 장애 데이터노드는 파이프라인에서 제거되고, 정상인 나머지 두 데이터노드로 새로운 파이프라인을 구성하고 블록의 남은 데이터는 파이프라인의 정상 데이터노드로 전송됩니다.

5. 네임노드는 해당 블록이 불완전 복제(under-replicated)라는 것을 인식하고 있으므로 나중에 다른 노드에 복제본이 생성되도록 조치하고 후속 블록을 정상적으로 처리합니다. 


감사합니다. 포스팅을 마치도록 하겠습니다:)


반응형

+ Recent posts