Hadoop Cluster?

  노드(node)는 하나의 컴퓨터를 말합니다. 이처럼 30~40개의 노드가 모여 하나의 rack을 구성합니다. rack은 물리적으로 같은 network의 switch에 모두 연결이 되어 있습니다. 그렇기 때문에 두 노드의 badnwidth는 다른 rack에 있는 노드보다 크게 됩니다. 즉, 데이터의 이동을 할 수 있는 폭이 크기 때문에 데이터의 속도가 빠른것을 알 수 있습니다. rack이 모여서 하나의 Hadoop Cluster를 구축하게 됩니다. 이처럼 network의 다른 switch에 연결되어 있는 rack으로 인해 어떤 성능 저하가 나타는지 추후에 알아보도록 하겠습니다.

Hadoop의 주요한 컴포넌트는 HDFS와 MapReduce가 있습니다. 

HDFS(Hadoop Distributed File System)

  HDFS는 각 노드의 파일시스템의 위에서 동작을 하게 됩니다. 분산시스템에서 문제로 다루어지고 있는 fault tolerant를 해결하기 위해 HDFS에서는 데이터를 복제(replication)을 하게 됩니다. Hadoop은 데이터가 큰 파일을 처리하도록 디자인 되었기 때문에, 데이터의 파일이 크면 클수록 다음 읽어야하는 데이터의 위치를 찾는 시간이 줄어들게 됩니다. 그렇기 때문에 큰 파일을 읽어서 처리하는게 효율적입니다. 데이터의의 서브셋을 분석할때도 데이터의 위치를 찾는 연산의 코스트가 크기때문에 피하는게 좋습니다. Hadoop은 streaming, sequential 데이터를 접근하는게 임의의 접근보다 더 효율적으로 디자인이 되어 있습니다. 잘 생각해보면 데이터의 위치를 찾는 연산의 코스트가 크다고 했는데, sequenctial 데이터나, streaming 데이터는 데이터를 시작하는 위치만 찾으면 되기 때문에 찾는 작업의 코스트가 크지 않습니다. 

  HDFS에서는 데이터를 블록(block)의 사이즈로 저장을 하고 있습니다. 기본으로는 64MB가 하나의 블록 사이즈인데, 거의 대부분은 128MB의 이상의 블록사이즈로 데이터를 저장을 하고 있습니다. 그냥 데이터를 통째로 저장하면 되는데, 왜 블록으로 나누어서 저장을 하게 될까요? 그 이유는 첫번째로 데이터가 얼마나 디스크에 맞는지, 저장이 가능한지 계산하기가 쉽습니다. 두번째로 HDFS에서는 fault tolerant를 방지하기 위해서 데이터를 복제합니다. 그렇다면 데이터를 부분적으로 복제해 여러 분산된 노드에 저장이 가능합니다. 세번째로 블록은 데이터 공간을 낭비하지 않습니다. 그 예로 450MB의 데이터를 128MB의 블록으로 나누어 져장할때, 4개의 블록이 생기게 됩니다. 하지만 마지막 4번째 블록은 128MB의 공간을 전부 소비하지 않고, 데이터 사이즈에 맞도록 소비하게 됩니다. 

  아래 예제는 블록이 각 여러 노드에 복제된 것을 나타낸 그림입니다. 블록1은 노드1, 노드2에 저장이 되어있고, 블록2는 노드1과 노드3에 저장이 되어 있습니다. 그리고 블록3은 노드2와 노드3에 저장이 되어 있습니다. 이처럼 데이터 복제는 한개의 노드가 fail이 나도 데이터 손실없이 데이터를 처리 할 수 있습니다. 예를 들어 만약 노드1이 충돌이 발생하면 노드2는 여저니 블록1을 갖고 있기 때문에 데이터를 계속 처리가 가능합니다.

  HDFS는 NameNode와 DataNodes를 가지고 있습니다. NameNode는 실제 데이터를 저장하고 있는 노드가 아닌, 어느 노드에 어떤 데이터가 저장되어 있는지에 대한 filesystem의 metadata를 가지고 있습니다. filesystem의 모든 metadata를 메모리에 저장을 하고 있어야 하기 때문에 NameNode는 가능한 큰 메모리를 갖고 있는게 좋습니다. HDFS는 많은 DataNodes를 가지고 있습니다. DataNodes는 데이터의 블록을 저장하고 있습니다. 

  만약 데이터를 찾는 클라이언트의 요청이 오면, NameNode로 부터 데이터의 위치를 찾습니다. 해당 DataNode의 데이터 위치를 확인한 클라이언트는 직접적으로 DataNode의 데이터에 접근을 해서 연산을 하게 됩니다. 그렇기 때문에 각각 DataNode에서 생성되거나 바뀐 데이터의 정보가 발생하는데, 변경된 정보는 NameNode로 주기적으로 리포트를 보냅니다.

  만약에 NameNode가 fail이 났을 경우를 생각해서 JournalNodes가 있습니다. JournalNodes는 최소 3개, 홀수개로 존재하게 됩니다. NameNode는 무조건 한개가 active인데, JournalNodes는 함께 동작하면서 NameNode가 죽게 되면 다른 NameNode를 active시키는 역할을 합니다. 

  Hadoop은 topology network를 갖고 있기 때문에 데이터를 보내고, 처리하는 과정을 최적화를 해야합니다. 최적활를 하는 방법은 간단합니다. 데이터가 있는 곳에서 처리를 하거나, 데이터를 이동해서 처리를 해야한다면 bandwidth가 최대가 되는 노드 사이에서 데이터를 이동하는게 효율적입니다. 예를들어서 블록 B1을 처리를 해야할때 rack1의 노드 n1에서 처리하는게 가장 좋습니다. 하지만 만약 같은 노드에 데이터가 없다면, 같은 rack에 있는 노드에서 처리하는게 좋습니다. 가장 최악은 다른 rack2에 있는 노드에서 처리하는게 최악입니다. 

  HDFS에 데이터를 생성하는 방법은, NameNode에 "create"라는 request를 보내게 됩니다. 그럼 NameNode에서는 해당 파일이 있는지, 이 클라이언트가 권한이 있는지 확인을 하고, DataNode에 데이터를 생성합니다. 만약 클라이언트가 DataNode에서 동작을 하고 있으면 해당 노드에 데이터를 생성합니다. 만약 그게 아니라면 랜덤하게 DataNode를 선택하고 데이터를 생성합니다. HDFS는 기본적으로 2개의 복제(replication)를 하게 됩니다. DataNodes사이에 pipeline을 생성을 하고, 복제 데이터를 생성합니다. 파일을 다 생성하게 되면 DataNodes에서는 데이터가 다 생성되었다는 메시지를 순차적으로 전송을 합니다. 모든 노드에 데이터가 복제가 되면 NameNode는 acknowlegement를 받게 됩니다.

MapReduce

MapReduce 프로그램은 map tasks와 reduce tasks로 나누어져서 각 노드에서 parallel하게 동작하는 것을 말합니다.

 

Yarn

  Hadoop위에서 동작하는 여러 어플리케이션이 등장하기 시작하면서 고려를 해야하는게 생겼습니다. 바로 리소스와 스케줄입니다. 각 어플리케이션은 각자의 리소스매니저와 스케줄러를 사용했습니다. 그렇게 되면 다른 어플리케이션에서 공유되는 자원을 사용할때 문제가 발생하게 됩니다. 그래서 등장한게 Yarn입니다. Yarn은 Hadoop Cluster의 리소스를 관리해주는 관리자입니다. 각자의 어플리케이션에서 관리하던 리소스와 스케줄러를 통합해서 관리하게 됩니다. 

  Yarn은 각 노드에서 동작하고 있는 NodeManager를 통해서 각 노드에 사용가능한 자원에 대해서 인지를 하고 있습니다. 동작순서는 어플리케이션이 실행이 되면 Application Master가 시작되고, ResourceManager로 부터 어떤 리소스를 사용할 수 있는지에 대해서 알게 됩니다. 그렇게 되면 Application Manager는 각 노드에 있는 Containers에게 자원을 할당합니다. 자원이 할당되면 각 tasks는 Containers에서 작업을 수행하게 됩니다. 



[참고] Big Data University - Hadoop Fundamental I 


+ Recent posts