데이터분석 전문가(ADP)

데이터분석 전문가(ADP) 시험 노트개념 정리22 MIN

분산 파일 시스템과 NoSQL, 맵리듀스

ADP 2과목의 둘째 자리입니다. 구글 파일 시스템과 HDFS의 블록 복제, 공유 디스크와 무공유 클러스터, CAP 이론과 NoSQL 저장 모델 넷, 맵리듀스의 셔플 단계, 하둡 에코시스템과 병렬 질의 처리를 계산과 표로 정리합니다.

앞 노트가 데이터를 어떻게 모아 오는가였다면 이 노트는 모아 온 것을 어디에 어떻게 쌓고 처리하는가입니다. 한 대의 서버로 감당되지 않는 크기가 되면 장비를 여러 대로 늘리는데, 그 순간 저장·조회·계산이 전부 다른 문제가 됩니다. 2과목에서 문항이 가장 많이 나오는 자리이고, 지문이 이름만 늘어놓는 것처럼 보여도 실제로는 「어느 층에 서 있는 이름인가」를 묻습니다.

분산 파일 시스템

구글 파일 시스템

분산 파일 시스템은 여러 대의 서버에 나눠 저장된 파일을 한 덩어리처럼 보이게 하는 소프트웨어입니다. 그 원형이 구글 파일 시스템(GFS)이고, 값싼 서버를 잔뜩 붙여 쓰는 것을 전제로 설계됐습니다. 장비가 고장 나는 것을 예외가 아니라 일상으로 보고 복제로 막는 것이 그 설계의 핵심입니다.

구성은 셋입니다. 파일이 어느 서버의 어디에 있는지를 아는 마스터, 실제 데이터 조각을 들고 있는 청크서버, 그리고 둘에게 말을 거는 클라이언트입니다. 클라이언트는 위치를 마스터에게 묻고 데이터 자체는 청크서버와 직접 주고받습니다. 마스터를 데이터가 지나가는 길목에서 빼 놓았기 때문에 한 대로도 버팁니다.

HDFS

HDFS는 구글 파일 시스템을 본떠 만든 하둡의 분산 파일 시스템입니다. 이름만 바뀐 것이 아니라 역할 이름도 그대로 대응합니다.

GFS HDFS 하는 일
마스터 네임노드 파일 이름과 블록 위치를 메모리에 들고 있다
청크서버 데이터노드 블록을 디스크에 저장하고 읽어 준다
청크 블록 파일을 자른 조각

네임노드가 파일 목록 전체를 메모리에 두기 때문에 작은 파일이 아주 많은 것이 HDFS의 약점입니다. 1GB짜리 파일 하나와 1MB짜리 파일 1,024개는 저장 용량은 같지만 네임노드가 기억해야 할 항목 수가 천 배 차이 납니다.

블록과 복제

파일은 고정 크기 블록으로 잘려 저장됩니다. 기본값은 하둡 초기에 64MB였고 지금은 128MB입니다. 일반 파일 시스템의 블록이 수 KB인 것과 견주면 터무니없이 큰데, 이유는 조각 수를 줄여 네임노드의 부담과 위치 조회 횟수를 낮추기 위해서입니다.

각 블록은 서로 다른 데이터노드에 세 벌로 복제됩니다. 한 대가 죽어도 남은 두 벌로 읽을 수 있고, 네임노드가 부족해진 복제본을 다른 노드에 다시 만듭니다. 대신 실제 디스크 사용량은 원본의 세 배가 됩니다. 계산 문제가 이 자리에서 나옵니다.

한 가지 더, HDFS는 한 번 쓰고 여러 번 읽는 것을 전제로 합니다. 파일 중간을 고치는 연산이 없고 끝에 덧붙이는 것만 됩니다. 복제본을 여럿 두고 중간 수정을 허용하면 어느 벌이 최신인지 맞추는 비용이 감당되지 않기 때문입니다.

데이터베이스 클러스터

공유 디스크와 무공유

여러 서버를 묶어 하나의 데이터베이스처럼 쓰는 것이 데이터베이스 클러스터입니다. 저장 장치를 어떻게 두느냐로 크게 둘로 갈립니다.

견줄 것 공유 디스크 무공유
저장 장치 모든 노드가 같은 디스크를 본다 노드마다 제 디스크를 갖는다
노드 추가 디스크 경합이 늘어 한계가 있다 노드를 늘린 만큼 성능이 는다
데이터 분배 필요 없다 미리 나눠 둬야 한다
한 노드 고장 나머지가 그대로 읽는다 그 노드가 맡은 데이터를 못 읽는다
예 오라클 RAC IBM DB2 ICE, MySQL 클러스터

앞에서 본 분산 파일 시스템은 전부 무공유 쪽입니다. 값싼 서버에 제 디스크를 달아 옆으로 늘리는 방식이고, 고장 문제는 복제로 메웁니다.

파티셔닝

무공유 구조는 데이터를 미리 나눠 둬야 합니다. 이 나눔을 파티셔닝이라 하고, 나누는 기준에 따라 성질이 달라집니다.

  • 범위 분할은 값의 구간으로 나눕니다. 날짜별로 나누면 기간 조회가 한 노드에서 끝나지만, 최근 데이터에만 부하가 몰립니다.
  • 해시 분할은 키를 해시 함수에 넣어 나눕니다. 고르게 퍼지는 대신 범위 조회가 모든 노드를 건드립니다.
  • 목록 분할은 「서울은 1번, 부산은 2번」처럼 값을 직접 지정합니다.

어느 쪽이든 한 노드에 데이터가 쏠리는 것을 경계합니다. 이렇게 한쪽으로 쏠린 상태를 데이터 스큐라 하고, 나중에 볼 맵리듀스에서도 같은 이름으로 같은 문제가 나옵니다.

NoSQL과 CAP 이론

CAP 이론

CAP 이론은 분산 시스템이 다음 셋을 동시에 만족할 수 없다는 명제입니다.

성질 뜻
일관성(Consistency) 어느 노드에 물어도 같은 값이 나온다
가용성(Availability) 요청하면 언제든 응답을 받는다
분단 내성(Partition tolerance) 노드 사이 통신이 끊겨도 시스템이 동작한다

여러 대에 나눠 둔 이상 네트워크가 끊기는 일은 피할 수 없으므로 분단 내성은 사실상 포기할 수 없는 항목입니다. 그래서 실제 선택은 끊겼을 때 일관성을 지킬 것인가, 응답을 계속할 것인가 둘 중 하나가 됩니다. 앞을 고르면 CP, 뒤를 고르면 AP입니다.

관계형 데이터베이스가 지키는 ACID와 대비되는 말이 BASE입니다. 지금 당장은 노드마다 값이 다를 수 있지만 시간이 지나면 같아진다는 결과적 일관성이 그 핵심이고, AP를 고른 저장소가 서 있는 자리입니다.

저장 모델 넷

NoSQL은 관계형 모델과 SQL을 벗어난 저장소를 묶어 부르는 말입니다. 담는 모양으로 넷을 가릅니다.

모델 담는 모양 어울리는 곳 예
키-값 키 하나에 값 하나 세션, 캐시, 장바구니 Redis, DynamoDB
문서 키에 JSON 같은 구조체 스키마가 자주 바뀌는 데이터 MongoDB, CouchDB
컬럼 행 키 아래 컬럼 묶음 대용량 로그, 시계열 HBase, Cassandra
그래프 정점과 간선 관계망, 추천 Neo4j

키-값과 문서의 차이가 자주 나옵니다. 키-값은 값 안을 들여다보지 않아 키로만 찾을 수 있고, 문서는 값 안의 필드로도 조회하고 색인을 걸 수 있습니다. 구글 빅테이블이 컬럼 모델의 원형이고 아마존 다이나모가 키-값의 원형이라는 짝도 함께 묻습니다.

맵리듀스

맵과 리듀스

맵리듀스는 데이터가 있는 노드로 계산을 보내 나눠 처리하는 프로그래밍 모델입니다. 데이터를 옮기는 대신 코드를 옮기기 때문에 네트워크로 흐르는 양이 줄어듭니다.

이름 그대로 두 함수로 씁니다. 맵은 입력 조각 하나를 읽어 키-값 쌍을 뱉고, 리듀스는 같은 키로 모인 값들을 받아 하나로 줄입니다. 맵 태스크의 개수는 입력 블록 수가 정하고, 리듀스 태스크의 개수는 사람이 지정합니다.

셔플과 정렬

두 함수 사이에 사람이 쓰지 않는 단계가 끼어 있고 여기가 시험의 핵심입니다. 맵이 뱉은 쌍을 키별로 모아 같은 리듀서로 보내는 것이 셔플이고, 리듀서에 도착한 쌍을 키 순서로 줄 세우는 것이 정렬입니다. 전체 순서는 이렇습니다.

  1. 입력 분할 — 파일을 스플릿으로 나눈다
  2. 맵 — 스플릿마다 키-값 쌍을 만든다
  3. 컴바인 — 맵 노드에서 미리 부분 집계한다(선택)
  4. 파티션 — 키를 어느 리듀서로 보낼지 정한다
  5. 셔플과 정렬 — 네트워크로 옮기고 키 순으로 세운다
  6. 리듀스 — 키마다 값들을 줄여 최종 결과를 쓴다

셔플은 유일하게 노드 사이를 대량으로 오가는 단계라 대개 여기가 병목입니다. 컴바이너를 두는 이유가 그것입니다 — 맵 쪽에서 미리 합쳐 놓으면 네트워크로 나가는 쌍의 수가 줄어듭니다. 다만 덧셈이나 최댓값처럼 부분끼리 합쳐도 답이 같은 연산에만 쓸 수 있습니다. 평균에 컴바이너를 그대로 붙이면 「평균의 평균」이 나와 값이 틀어집니다.

단어 세기

가장 기본이 되는 예제입니다.

def map(key, line):
    for word in line.split():
        emit(word, 1)

def reduce(word, counts):
    emit(word, sum(counts))

맵은 단어마다 (단어, 1)을 뱉고, 셔플이 같은 단어를 한 리듀서로 모으며, 리듀스가 그 1들을 더합니다. 여기서 한 단어가 전체의 대부분을 차지하면 그 키를 맡은 리듀서 하나만 오래 도는데, 이것이 앞에서 본 데이터 스큐가 맵리듀스에 나타나는 모습입니다.

하둡 에코시스템

계층별 구성 요소

하둡은 저장(HDFS)과 처리(맵리듀스) 둘이 뼈대이고 그 위아래로 도구들이 붙어 있습니다. 이름을 외우기보다 어느 층에 있는지로 묶어 두면 지문에서 성격이 다른 하나를 고르기 쉽습니다.

층 도구 하는 일
수집 Flume, Chukwa, Sqoop 로그와 관계형 데이터를 끌어온다
저장 HDFS, HBase 파일과 컬럼 데이터를 쌓는다
자원 관리 YARN 클러스터의 CPU와 메모리를 나눠 준다
처리 MapReduce, Spark 나눠 계산한다
질의 Hive, Pig, Impala, Tajo 사람이 쓰는 문법으로 묻는다
관리 ZooKeeper, Oozie 노드를 조율하고 작업 순서를 엮는다
분석 Mahout 분산 환경에서 기계학습을 돌린다

병렬 질의 처리

맵리듀스를 직접 쓰려면 자바 코드를 써야 하는데, 집계 한 번 하려고 프로그램을 짜는 것은 부담입니다. 병렬 질의 처리는 익숙한 문법으로 적은 질의를 분산 처리 작업으로 바꿔 돌려 주는 계층입니다.

  • Hive는 SQL을 닮은 HiveQL을 씁니다. 페이스북에서 만들었고, 적은 질의를 맵리듀스나 다른 실행 엔진의 작업으로 번역합니다.
  • Pig는 Pig Latin이라는 절차형 언어를 씁니다. 야후가 만들었고, 단계를 차례로 적어 내려가는 방식이라 데이터 흐름을 그대로 옮기기 좋습니다.
  • Tajo는 국내에서 시작된 프로젝트로, 맵리듀스를 거치지 않고 자체 엔진으로 SQL을 실행합니다.

Hive와 Pig의 갈림이 자주 나옵니다. 선언형 SQL이냐 절차형 흐름이냐가 답을 가르는 지점이고, 구글 쪽 대응물은 Sawzall입니다. 이 계층 전체가 「사람은 질의로 쓰고 기계는 분산으로 돈다」는 한 문장으로 요약됩니다.

연습 문제

  1. HDFS에 1GB 파일을 저장한다. 블록 크기가 128MB이고 복제 계수가 3일 때 클러스터 전체에 놓이는 블록 복제본의 개수와 실제 디스크 사용량은? (1GB = 1,024MB)
    ① 8개, 1GB
    ② 8개, 3GB
    ③ 24개, 3GB
    ④ 24개, 1GB
    ③. 블록 수는 1024÷128=81024 \div 128 = 8 개이고, 각 블록이 세 벌씩 놓이므로 8×3=248 \times 3 = 24 개의 복제본이 생깁니다. 디스크는 원본의 세 배인 3GB를 씁니다. 네임노드가 기억하는 블록 항목은 8개 그대로이고 복제본 위치가 항목마다 셋씩 딸립니다.
  2. 블록 크기가 128MB인 HDFS에 저장된 12GB 입력을 맵리듀스로 처리한다. 생성되는 맵 태스크의 수는? (1GB = 1,024MB)
    ① 12개
    ② 48개
    ③ 96개
    ④ 288개
    ③. 맵 태스크는 입력 스플릿마다 하나씩 뜨고 스플릿은 기본적으로 블록과 같습니다. 12×1024=12,28812 \times 1024 = 12{,}288 MB를 128MB로 나누면 96개입니다. 복제본은 같은 데이터의 사본이므로 태스크 수에 곱하지 않습니다. 리듀스 태스크 수는 이 계산과 무관하게 사람이 지정합니다.
  3. CAP 이론에 대한 설명으로 옳은 것은?
    ① 세 성질을 모두 만족하는 설계가 이론적으로 가능하다
    ② 분단 내성을 포기하는 것이 분산 환경에서 가장 현실적인 선택이다
    ③ 통신이 끊겼을 때 응답을 계속하기로 하면 일관성을 양보하게 된다
    ④ 결과적 일관성은 가용성을 포기한 설계에서 나온 개념이다
    ③. 여러 노드에 나눈 이상 네트워크 단절은 피할 수 없어 분단 내성은 사실상 고정이고, 남은 선택은 일관성과 가용성 둘 중 하나입니다. 응답을 계속하는 쪽을 고르면 노드마다 값이 다른 상태를 잠시 허용하게 되고 그것이 결과적 일관성입니다. 따라서 ④는 가용성을 택한 설계의 개념이라 틀립니다.
  4. 저장 모델과 예가 바르게 짝지어지지 않은 것은?
    ① 키-값 — Redis
    ② 문서 — MongoDB
    ③ 컬럼 — HBase
    ④ 그래프 — Cassandra
    ④. Cassandra는 컬럼 모델입니다. 그래프 모델의 대표는 Neo4j입니다. 키-값과 문서의 차이는 값 안을 들여다보는지 여부인데, 키-값은 키로만 찾고 문서는 값 안의 필드로도 조회할 수 있습니다.
  5. 맵리듀스에서 컴바이너를 붙였을 때 결과가 달라지는 연산은?
    ① 키별 합계
    ② 키별 최댓값
    ③ 키별 평균
    ④ 키별 개수
    ③. 컴바이너는 맵 노드에서 부분 집계를 미리 해 셔플로 나가는 쌍의 수를 줄이는 장치이므로, 부분끼리 합쳐도 같은 답이 나오는 연산에만 쓸 수 있습니다. 평균은 (2+4)/2=3(2+4)/2 = 3 과 (6)/1=6(6)/1 = 6 을 다시 평균 내면 4.5가 되어 실제 평균 4와 어긋납니다. 합계·최댓값·개수는 부분 결과를 다시 합쳐도 같습니다.
  6. 서술형 연습입니다. 매일 4TB씩 쌓이는 웹 서버 로그를 저장하고 일 단위로 집계하려 합니다. 공유 디스크 클러스터 대신 무공유 구조의 분산 파일 시스템을 고르는 근거를 대고, 그 선택이 안게 되는 문제 둘과 각각을 무엇으로 메울지 5줄 이내로 쓰시오.
    채점 기준은 셋입니다. (1) 근거를 구조의 성질로 댔는가 — 공유 디스크는 노드를 늘려도 같은 저장 장치를 함께 보므로 경합이 커져 확장에 한계가 있는 반면, 무공유는 노드마다 제 디스크를 가져 장비를 붙인 만큼 용량과 처리량이 함께 늘고 값싼 서버를 쓸 수 있다는 점을 짚어야 합니다. 로그는 한 번 쓰고 여러 번 읽는 데이터라 중간 수정이 없는 HDFS의 전제와도 맞습니다. (2) 문제 둘을 정확히 들었는가 — 노드가 죽으면 그 노드가 맡은 데이터를 읽을 수 없다는 것, 그리고 데이터를 미리 나눠 둬야 하며 나눔이 한쪽으로 쏠리면 특정 노드만 오래 돈다는 것입니다. 작은 파일이 많을 때 네임노드 메모리가 부담이 된다는 점을 들어도 됩니다. (3) 메우는 방법을 구체적으로 적었는가 — 고장은 블록을 세 벌로 복제해 남은 벌로 읽고 부족해진 복제본을 다시 만드는 것으로, 쏠림은 해시 분할을 쓰거나 집계 키를 잘게 쪼개 리듀서에 고르게 퍼지게 하는 것으로, 작은 파일 문제는 일 단위로 묶어 큰 파일로 적재하는 것으로 메웁니다. 근거만 적고 문제와 대응을 빠뜨리면 배점의 3분의 1만 붙습니다.
데이터분석 전문가(ADP) 시험 노트 전체 보기