사전 Hadoop
구현체

Hadoop

gabury1고친 사람 github-actions[bot]

Hadoop 은 서버 한 대로는 감당이 안 되는 큰 데이터를 서버 여러 대에 나눠 담고 계산해 주는 소프트웨어 묶음입니다. 값싼 서버 수백 대를 한 덩어리처럼 쓰게 해 줍니다. 계산은 데이터를 옮기지 않고 데이터가 놓인 서버에서 돌립니다. 그 대신 한 번에 몇 분에서 몇 시간씩 걸리는 큰 일괄 작업에 맞춰져 있습니다.

쉽고 빠른 이해

Hadoop 은 서버 수백 대를 묶어 큰 데이터를 담고 계산합니다. 몇 년 치 접속 로그를 모아 두고 밤마다 집계하는 일이 전형입니다.

이게 없으면 데이터가 서버 한 대의 디스크와 메모리에 묶입니다. 더 큰 서버를 사는 데는 끝이 있습니다.

  1. 데이터를 조각으로 잘라 여러 서버에 복사해 둡니다
  2. 계산 요청이 오면 조각이 있는 서버마다 계산을 따로 돌립니다
  3. 서버마다 낸 중간 결과를 모아 최종 결과를 만듭니다

서버 몇 대가 고장 나도 다른 서버의 복사본으로 이어 갑니다.

치르는 값도 있습니다. 짧은 조회 하나에도 계산을 여러 서버에 나눠 보내는 준비부터 거칩니다. 굴릴 서버와 프로그램이 많아 운영이 무겁습니다.

상세

Hadoop 이라는 이름은 좁은 뜻과 넓은 뜻으로 쓰입니다. 아래에서는 그 둘부터 가릅니다.

좁은 뜻과 넓은 뜻

Hadoop 은 Apache Software Foundation 이 관리하는 오픈 소스 프로젝트입니다. 좁게는 이 프로젝트가 직접 내놓는 네 부품을 가리킵니다. 파일을 여러 서버에 나눠 담는 HDFS(Hadoop Distributed File System)가 첫째입니다. 서버들의 계산 자원을 나눠 주는 YARN(Yet Another Resource Negotiator)이 둘째입니다. 계산을 나눠 돌리는 MapReduce 와, 셋이 함께 쓰는 공용 코드 Hadoop Common 이 나머지 둘입니다. 자세한 일은 아래 「네 부품」 소절에서 봅니다.

넓게는 이 네 부품 위에서 도는 도구 전체를 함께 부릅니다. SQL(Structured Query Language)로 데이터를 조회하게 해 주는 Apache Hive, 키로 행 하나를 읽고 쓰는 HBase, 데이터를 읽어 계산을 돌리는 계산 엔진 Apache Spark 같은 도구입니다. 이 둘레를 흔히 하둡 생태계라고 부릅니다. "하둡 클러스터를 쓴다" 고 할 때는 대개 넓은 뜻입니다.

한 대에 안 들어가는 데이터

서버 한 대의 디스크와 메모리에는 끝이 있습니다. 데이터가 수백 테라바이트가 되면 한 대에 담지 못합니다. 담더라도 디스크 하나로 처음부터 끝까지 읽는 데 몇 시간이 걸립니다.

길은 둘입니다. 서버 한 대를 더 크고 비싼 것으로 바꾸는 것이 스케일 업입니다. 서버 대수를 늘려 일을 나눠 맡기는 것이 스케일 아웃입니다. 스케일 업은 살 수 있는 가장 큰 서버에서 멈춥니다.

Hadoop 은 스케일 아웃을 골랐습니다. 특별한 장비 대신 흔한 서버를 많이 묶습니다. 한 가지 일을 함께 하도록 묶은 이런 서버 무리가 클러스터입니다.

서버가 수백 대면 디스크든 전원이든 어딘가는 늘 고장 나 있습니다. 그래서 Hadoop 은 고장을 드문 사고가 아니라 평소 상태로 보고 설계했습니다. 데이터는 여러 벌 복사해 둡니다. 멈춘 계산은 다른 서버에서 다시 돌립니다.

Hadoop 은 구글이 논문으로 공개한 두 설계를 본떠 만들었습니다. 분산 파일 시스템 GFS(Google File System)와 계산 방식 MapReduce 입니다. Hadoop 의 부품 MapReduce 는 이 계산 방식을 오픈 소스로 다시 만든 것이라 이름이 같습니다.

네 부품

Hadoop 본체는 네 부품으로 이루어집니다. 아래 표가 부품마다 맡는 일입니다. 블록은 파일을 일정한 크기로 자른 조각 하나입니다.

부품 맡는 일
HDFS 파일을 블록으로 잘라 여러 서버에 복사해 담는다
YARN 클러스터 전체의 메모리와 계산 자원을 작업마다 나눠 준다
MapReduce 큰 계산을 블록마다 따로 돌린 뒤 결과를 모은다
Hadoop Common 세 부품이 함께 쓰는 설정·통신·파일 접근 코드

세 부품 사이에는 방향이 있습니다. 계산 엔진인 MapReduce 가 나머지 둘을 부릅니다. YARN 에서 계산 자원을 빌립니다. HDFS 에서는 데이터를 읽습니다.

저장과 계산 자원 관리를 부품으로 떼어 둔 덕분에 MapReduce 말고 다른 계산 엔진도 같은 클러스터에 붙습니다. Spark 가 그런 엔진입니다. 아래 그림에서 위쪽의 두 엔진은 아래쪽의 같은 두 부품을 부릅니다.

flowchart TD
    subgraph E["계산 엔진"]
        MR["MapReduce · 본체 부품"]
        SP["Spark · 둘레 도구"]
    end
    subgraph B["본체의 바탕 부품"]
        YARN["YARN"]
        HDFS["HDFS"]
        CM["Hadoop Common · 공용 코드"]
    end
    E -->|계산 자원을 빌린다| YARN
    E -->|데이터를 읽는다| HDFS

Hadoop 은 Java 로 짜였습니다. 그래서 MapReduce 작업도 처음에는 Java 코드로 쓰는 것이 기본이었습니다.

계산을 데이터 쪽으로 보낸다

보통 프로그램은 데이터를 자기 쪽으로 가져와 계산합니다. 데이터가 수백 테라바이트면 이 방식이 막힙니다. 데이터를 네트워크로 옮기는 데 계산보다 오래 걸립니다.

Hadoop 은 방향을 뒤집습니다. 계산 코드는 데이터에 비하면 아주 작습니다. 그래서 코드를 데이터가 놓인 서버로 보내 거기서 돌립니다. 이 원칙이 데이터 지역성입니다.

로그 파일 하나가 서버 백 대에 블록으로 나뉘어 있다고 해 봅니다. 서버 백 대가 저마다 자기 디스크의 블록을 읽어 계산합니다. 원본 데이터는 디스크 밖으로 나오지 않습니다. 네트워크를 타는 것은 블록마다 나온 중간 결과입니다.

아래 그림은 그중 서버 세 대만 그렸습니다. 화살표가 서버 밖으로 나가는 곳은 중간 결과가 떠나는 곳 하나뿐입니다.

flowchart TD
    subgraph W1["워커 서버 1"]
        B1["블록 1"] --> C1["계산"]
    end
    subgraph W2["워커 서버 2"]
        B2["블록 2"] --> C2["계산"]
    end
    subgraph W3["워커 서버 3"]
        B3["블록 3"] --> C3["계산"]
    end
    C1 -->|중간 결과| F["중간 결과를 모아 최종 결과를 만든다"]
    C2 -->|중간 결과| F
    C3 -->|중간 결과| F

마스터와 워커

Hadoop 클러스터의 서버는 두 무리로 나뉩니다. 소수의 마스터 서버가 전체를 관리합니다. 나머지 다수의 워커 서버가 데이터를 담고 계산을 돌립니다.

HDFS 와 YARN 은 이 얼개를 저마다 갖습니다. 마스터 쪽에 관리 프로그램 하나를 둡니다. 워커마다 일꾼 프로그램을 하나씩 띄웁니다. 서버에 늘 떠서 요청을 기다리는 이런 프로그램이 데몬입니다.

마스터 쪽 워커마다
HDFS 네임노드(NameNode) — 어느 블록이 어느 서버에 있는지 쥔다 데이터노드(DataNode) — 블록을 자기 디스크에 담고, 담은 블록을 네임노드에 알린다
YARN 리소스매니저(ResourceManager) — 클러스터 전체 자원을 작업에 나눠 준다 노드매니저(NodeManager) — 자기 서버의 남은 자원을 알리고 계산을 띄운다

워커 서버 한 대에는 데이터노드와 노드매니저가 함께 뜹니다. 같은 서버가 블록을 담고 계산도 돌립니다. 앞 소절의 데이터 지역성은 이 배치가 있어야 성립합니다.

flowchart TD
    subgraph M["마스터 서버"]
        NN["네임노드"]
        RM["리소스매니저"]
    end
    subgraph W1["워커 서버 1"]
        DN1["데이터노드"]
        NM1["노드매니저"]
    end
    subgraph W2["워커 서버 2"]
        DN2["데이터노드"]
        NM2["노드매니저"]
    end
    subgraph W3["워커 서버 3"]
        DN3["데이터노드"]
        NM3["노드매니저"]
    end
    DN1 -.->|담은 블록| NN
    DN2 -.->|담은 블록| NN
    DN3 -.->|담은 블록| NN
    NM1 -.->|남은 자원| RM
    NM2 -.->|남은 자원| RM
    NM3 -.->|남은 자원| RM

화살표는 워커에서 마스터로 향합니다. 워커가 자기 사정을 알려 오고, 마스터는 그것을 모아 클러스터 전체를 봅니다.

클러스터를 키울 때는 워커 서버를 더 붙입니다. 붙인 서버마다 디스크와 계산 자원이 함께 늘어납니다.

네임노드와 리소스매니저는 멈추면 클러스터 전체가 서는 부품입니다. 이런 부품을 단일 장애점이라고 합니다. 그래서 운영 클러스터는 두 관리 프로그램을 저마다 서버 두 대에 띄웁니다. 지금 일을 맡은 쪽이 활성 관리 서버입니다. 뒤에서 기다리는 쪽은 대기 관리 서버입니다. 활성 관리 서버가 죽으면 대기 관리 서버가 넘겨받습니다.

Hadoop 이 내려놓은 것

Hadoop 은 큰 데이터를 한꺼번에 훑는 일에 맞춰 여러 가지를 포기했습니다. 아래 표가 그 목록입니다.

내려놓은 것 얻은 것
조회 한 건에 곧바로 답하기 전체를 훑는 큰 작업의 처리량
파일 중간 고쳐 쓰기 복사본끼리 내용이 갈리지 않는다
작은 파일 수백만 개 파일 목록을 마스터 한 대의 메모리에 쥐는 단순한 설계
서버 몇 대로 가볍게 굴리기 서버를 붙이는 만큼 늘어나는 저장과 계산

첫 줄은 작업을 띄우는 방식에서 옵니다. 작업마다 먼저 자원을 빌립니다. 그다음 여러 서버에 계산을 나눠 보내고, 끝나면 결과를 모읍니다. 이 준비에 드는 시간은 조회가 짧아도 줄지 않습니다.

둘째 줄은 HDFS 의 쓰기 방식에서 옵니다. HDFS 의 파일은 한 번 쓰고 나면 끝에 덧붙이기만 합니다. 중간을 고쳐 쓰는 길이 없습니다. 여러 서버에 흩어진 복사본을 같은 순간에 똑같이 고쳐야 하는 일이 없으니, 복사본끼리 내용이 갈릴 틈도 없습니다.

셋째 줄은 네임노드에서 옵니다. 네임노드는 어느 파일이 어떤 블록으로 이루어졌는지, 블록마다 어느 서버에 있는지를 전부 메모리에 쥡니다. 한곳에 다 있으니 찾기가 빠릅니다. 설계도 단순합니다. 대신 파일 하나, 블록 하나마다 네임노드 메모리를 조금씩 씁니다. 파일이 작아도 한 개는 한 개라서, 작은 파일이 수백만 개면 디스크보다 네임노드 메모리가 먼저 찹니다. 담을 수 있는 파일 수가 곧 네임노드 메모리 크기로 정해집니다.

MapReduce 는 계산 단계마다 중간 결과를 디스크에 적습니다. 같은 데이터를 여러 번 되풀이해 훑는 계산에서는 이 쓰기와 읽기가 무거워집니다. 중간 결과를 메모리에 두고 계산하는 Spark 가 이 틈을 채웠습니다.

넷째 줄은 운영의 무게입니다. 서버마다 데몬이 여럿 뜹니다. 부품마다 설정 파일도 따로 있습니다. 서버가 수백 대면 이 설정을 모두 맞춰 두는 일부터 품이 듭니다.

Hadoop 을 고르는 경우

한 번 쌓고 여러 번 훑는 큰 데이터에 맞습니다. 몇 년 치 로그를 모아 밤마다 집계하는 배치 처리가 그런 일입니다. 여러 시스템의 데이터를 모아 한곳에 쌓는 데이터 레이크의 저장소로도 쓰였습니다.

사용자가 누를 때마다 결과를 돌려줘야 하는 서비스에는 안 맞습니다. 주문 한 건을 읽고 고치는 일은 관계형 데이터베이스가 맡습니다. 데이터가 서버 한 대에 들어가는 크기일 때도 안 맞습니다. 클러스터를 굴리는 수고가 얻는 것보다 큽니다.

클라우드에서는 저장을 오브젝트 스토리지에 맡기는 구성이 많아졌습니다. 오브젝트 스토리지는 파일을 디렉터리 대신 키 하나로 찾는 저장소입니다. Amazon S3(Simple Storage Service)가 그런 저장소입니다. 이 구성에서는 HDFS 대신 오브젝트 스토리지를 읽습니다. 계산 클러스터는 필요할 때만 띄웠다가 내립니다.

이렇게 하면 저장과 계산을 따로 늘리고 줄일 수 있습니다. 대신 데이터 지역성을 잃습니다. 계산하는 서버가 매번 네트워크 너머에서 데이터를 가져옵니다.

맞물림

Hadoop 의 부품과 둘레 도구는 서로 부르도록 만들어졌습니다. 아래 네 소절은 누가 누구를 부르는지와 그렇게 붙어서 치르는 값을 봅니다.

계산 작업이 네임노드와 리소스매니저를 부르는 순서

계산 작업은 뜨기 전에 네임노드와 리소스매니저를 차례로 거칩니다. 먼저 네임노드에 입력 파일의 블록이 어느 서버에 있는지 묻습니다. 그다음 리소스매니저에 그 서버들의 자원을 청합니다. 자원을 받으면 그 서버의 노드매니저가 계산을 띄웁니다.

sequenceDiagram
    participant 계산 작업
    participant 네임노드
    participant 리소스매니저
    participant 노드매니저
    계산 작업->>네임노드: 입력 파일의 블록은 어느 서버에 있나
    네임노드-->>계산 작업: 블록마다 서버 목록
    계산 작업->>리소스매니저: 그 서버들의 자원을 달라
    리소스매니저-->>계산 작업: 워커 서버 2 의 자원을 내준다
    계산 작업->>노드매니저: 워커 서버 2 에서 계산을 띄워 달라
    Note over 노드매니저: 자기 디스크의 블록을 읽어 계산한다

원하는 서버가 바쁘면 리소스매니저는 다른 서버의 자원을 내줍니다. 그때 계산은 블록을 네트워크로 가져와 읽습니다. 데이터 지역성은 보장이 아니라 되도록 지키는 선호입니다.

이 순서가 통하려면 블록을 담은 서버에 계산 자원도 있어야 합니다. 그래서 저장과 계산이 한 서버에 묶입니다. 이것이 이 배치가 치르는 값입니다. 디스크만 모자라도 계산 자원까지 딸린 워커 서버를 통째 사야 합니다.

MapReduce 와 Spark 가 YARN 에서 빌리는 자원

초기 Hadoop 에서는 MapReduce 가 계산과 자원 관리를 함께 맡았습니다. YARN 이 자원 관리를 떼어 낸 뒤로 여러 계산 엔진이 한 클러스터를 나눠 씁니다.

계산 엔진은 작업마다 필요한 메모리와 계산 자원을 YARN 에 청합니다. 그리고 받은 만큼만 씁니다. MapReduce 도 Spark 도 이 방식으로 같은 워커 서버에서 같은 HDFS 데이터를 읽습니다.

여러 팀과 엔진이 한 클러스터를 나눠 쓰면 자원을 누구에게 먼저 줄지 정해야 합니다. 이 규칙을 정하는 부품이 스케줄러입니다. 규칙을 안 잡아 두면 큰 작업 하나가 자원을 다 쥐고 다른 팀의 작업이 기다립니다.

Hive 가 SQL 을 바꿔 띄우는 작업

사용자가 SQL 을 보내면 Hive 가 그것을 계산 작업으로 바꿔 YARN 에 띄웁니다. 그 작업이 읽는 데이터는 HDFS 에 있습니다. Hive 의 테이블 하나는 HDFS 의 디렉터리 하나입니다. 그 안의 파일에 담긴 줄이 테이블의 행입니다.

덕분에 Java 코드를 짜지 않고 SQL 로 큰 데이터를 집계합니다. 대신 조회 한 번에도 계산 작업이 하나 뜹니다. 몇 줄짜리 조회도 작업을 띄우고 거두는 시간을 기다립니다.

ZooKeeper 가 고르는 활성 관리 서버

ZooKeeper 는 여러 서버가 한 가지 값에 합의하도록 돕는 조정 서비스입니다. HDFS 와 YARN 은 두 관리 서버 중 어느 쪽이 활성 관리 서버인지를 ZooKeeper 에 맡겨 정합니다. 활성 관리 서버는 ZooKeeper 에 자기 이름을 적은 표식을 쥐고 있습니다.

활성 관리 서버가 죽으면 그 표식이 풀립니다. 그러면 대기 관리 서버가 표식을 잡고 일을 넘겨받습니다. 이렇게 한 대가 멈춰도 서비스가 이어지게 하는 구성이 고가용성입니다.

대가는 굴릴 서버 무리가 하나 더 느는 것입니다. ZooKeeper 자체도 여러 대로 띄워야 멈추지 않습니다. 옛 활성 관리 서버가 죽지 않고 잠시 멈췄다 돌아오면 두 대가 저마다 활성 관리 서버라고 믿는 스플릿 브레인도 막아야 합니다.

관련 항목

Hadoop 을 이루는 구성 요소

HDFS · YARN · MapReduce · Hadoop Common · 네임노드 · 데이터노드 · 리소스매니저 · 노드매니저

Hadoop 위에서 도는 생태계 도구

Apache Hive · HBase · Apache Spark · ZooKeeper · Apache Pig · Apache Sqoop · Apache Oozie · Apache Tez · Apache Flume

Hadoop 이 속하는 상위 분류

분산 시스템 · 분산 파일 시스템 · 빅데이터 · 오픈 소스 · Apache Software Foundation · 클러스터

Hadoop 이 기대는 설계 원리

데이터 지역성 · 수평 확장 · 수직 확장 · 복제 · 고가용성 · 스케줄링 · GFS

Hadoop 이 맞춘 작업 방식

배치 처리 · 처리량 · ETL · 데이터 웨어하우스 · 데이터 레이크

Hadoop 을 대신하는 저장·계산 구성

오브젝트 스토리지 · Amazon S3 · Amazon EMR · Google Cloud Dataproc · Databricks · 스노우플레이크

Hadoop 운영에서 자주 나는 문제

작은 파일 문제 · 단일 장애점 · 스플릿 브레인 · 데이터 스큐

다른 이름: 하둡 · Apache Hadoop