데이터 중심 어플리케이션 설계 [PART 2]
Designing Data Intensive Applications - O’REILLY

06. Partitioning

📖 Overview

06-1. 키-값 데이터 파티셔닝

06-2. 파티셔닝과 보조 색인

06-3. 파티션 재균형화

06-4. 요청 라우팅

06 정리


6장 파티셔닝

배경

  • 파티셔닝이란?

    • 데이터셋이 매우 크거나, 질의 처리량이 매우 높은 경우 데이터를 의도적으로 작은 단위(‘파티션’)로 쪼개는 작업 (=샤딩)
    • 파티션
      • = 샤드(MongoDB, ES, Solr ..)
      • = 리전 (Hbase)
      • = 태블릿 (Bigtable)
      • = 브이노드 (Cassandra, Riak)
      • = 브이버켓 (Couchbase)
    • 파티션은 보통 각 데이터 단위(레코드, 로우, 문서) 가 하나의 파티션에 속함
      • 즉, 파티션 그 자체로 작은 데이터베이스가 됨
  • 파티셔닝의 목적

    • 확장성, 부하 분산 (디스크, 질의 부하)
    • 파티셔닝 지원 데이터베이스의 용도 2가지 : 트랜잭션 작업부하용, 분석용
    • 용도에 따른 차이는 시스템 튜닝의 차이일뿐, 파티셔닝의 기본 원칙은 동일하게 적용

그래서 6장에서는 💡

  • 파티셔닝 방법
  • 데이터 색인과 파티셔닝 간의 상호 작용
  • 노드 추가/제거 시의 필요 작업 (=> 재균형화)
  • 데이터베이스가 올바른 파티션을 찾아 요청을 전달하고 질의를 실행하는 방법

06-1 파티셔닝과 복제

  • 사용 방법
    • 보통 파티셔닝 + 복제 함께 적용 (단, 방식은 독립적 선택)
    • 각 리더는 하나의 노드에 할당
  • 파티셔닝 목적
    • (데이터와 질의) 부하의 고른 분산
    • 부하 분산이 안된 Bad Case => “쏠렸다 (skew)” (부하가 쏠린 파티션 = ‘핫스팟’)
  • 파티셔닝 방법
    • Skew 및 핫스팟을 회피해야함
    • 가장 심플한 솔루션은 ‘랜덤’ => 나조차도 어디 저장됐는지도 알 수 없음 (찾으려면 모든 노드에 질의해야)

키 범위 기준 파티셔닝

  • 각 파티션의 연속된 범위 (MIN~MAX) 의 키 할당
    • Like 백과사전
  • 파티션 경계 (키 범위 크기)
    • 동일하지 않아도 됨
    • 관리자가 수동 선택 or 데이터베이스가 자동으로 선택하도록
  • 장단점
    • 장점 : 범위 스캔에 유용 (파티션 내 키 정렬 저장, 다중 칼럼 색인)
    • 단점 : 특정 접근 패턴으로인한 핫스팟 발생 가능성 (ex. 실시간으로 기록되는 key = timestamp 센서)
  • 사용 예
    • Bigtable, HBase, RethinkDB, MongoDB(<2.4)

키의 해시값 기준 파티셔닝

  • Skew와 핫스팟 회피를 위해 해시함수 많이 사용
    • 좋은 해시함수는 유사한 데이터가 인입되어도 균일되게 분산
    • 프로그래밍 언어의 내장 해시 함수는 파티셔닝에 적합하지 않을 수도 (ex. Java의 Object.hashCode())
  • 파티션 경계
    • 동일하지 않아도 됨 (무작위에 가깝게 선택도 가능)
    • = ‘일관성 해싱’?
      • 부하를 균등하게 분산시키는 방법 (잘 사용 x)
  • 장단점
    • 장점 : 키를 파티션 사이에 균일하게 분산
    • 단점 : 범위 질의 효율성 ↓ 정렬 순서 유지 x
  • 사용 예
    • Riak, Couchbase, Voldmort, MongoDB (해시기반 샤딩 모드)
    • Cassandra : 해시값 + 범위 기준 파티셔닝 전략 타협안 사용 (=> 복합 기본키)

쏠린 작업부하와 핫스팟 완화

(암호화폐는 유망하지만 투자는 조심혔어야재-)
  • 핫스팟을 완전히 제거할 수는 없다
    • 극단적 상황의 작업부하 (ex. 유명인의 SNS 활동의 영향 => 동일 id이므로 해싱 소용 x)
  • 현대 데이터 시스템은 skew에 대한 자동 보정이 어려움
    • 대부분 어플리케이션 단에서 완화
    • 이로 인한 불필요한 오버헤드는 방지할 것 (세분화)
    • => 트레이드 오프를 따져볼 것

06-2 파티셔닝과 보조 색인

  • 키-값 데이터모델에 의존한 파티셔닝 방식은 명확함
    • 기본키를 통한 레코트 식별
  • 여기에 보조 색인 이 연관되면? => 파티션에 깔끔하게 대응되지 x
    • 보조 색인 : 특정한 값이 발생한 항목을 검색하는 수단
    • 데이터 모델링에 유용 (관계형, 문서 데이터베이스에서도 흔히 사용)
  • 보조 색인이 있는 데이터베이스 색인 방식 2가지
    • 문서 기반 파티셔닝 (local index)
    • 용어 기반 파티셔닝 (global index)

문서 기준 보조 색인 파티셔닝

  • 문서 파티셔닝 색인 (지역 색인, local index)
    • 각 파티션은 자신의 보조 색인을 유지
    • 보조 색인도 그 파티션이 속하는 문서만 담당
    • 즉, 문서 CUD 시 쓰려고하는 파티션만 다루면 된다
  • 장단점
    • 장점 : write => 파티션의 보조색인이 100% 독립적
    • 단점 : read 시 모든 파티션으로 요청 + 취합 과정 필요 (scatter/gather)
      • 꼬리 지연 시간 증폭 발생 가능성
      • 질의가 단일 파티션에서만 실행되도록 권장되지만 어렵다 (특히 한번에 여러 보조 색인 사용시)
  • 사용 예
    • MongoDB, Riak, Cassandra, Elasticsearch, SolrCloud, VoltDB

용어 기준 보조 색인 파티셔닝

  • 용어 기준 파티셔닝 색인 (전역 색인, global index)
    • “용어 기준으로 파티셔닝되다 (term-partitioned)”
    • 용어 = 문서에 등장하는 모든 단어. from 전문 색인 (특별한 종류의 보조 색인)
  • 전역 색인도 파티셔닝은 필요
    • 한 노드에 저장시 병목 발생
    • 방법 : 용어 자체 사용 (범위 스캔 good) or 용어 해시값 사용 (분산 good)
  • 장단점
    • 장점 : read => 모든 파티션에 질의 할 필요 x
    • 단점 : write가 복잡하고 느림 (여러 파티션에 영향)
      • 색인을 항상 최신상태로 유지하려면 => 쓰기에 영향받는 모든 파티션에 대한 ‘분산 트랜잭션’ 필요
      • 실제로는 대부분 비동기로 갱신
  • 사용 예
    • Riak 검색, Oracle Warehouse (지역/전역 선택 가능)

06-3 파티션 재균형화

  • 재균형화 (리밸런싱, Rebalancing)
    • 장비의 추가/제거로 인해 데이터와 요청을 다른노드로 옮기는 과정
  • 재균형화의 최소 요구사항
    1. 리밸런싱 후 부하가 노드간 균등하게 분배될 것
    2. 리밸런싱 중에도 읽기/쓰기 요청을 받아들일 것
    3. 리밸런싱 소요 시간과 네트워크, 디스크 IO 부하를 최소화 할 것 (이동 데이터 최소화)

재균형화 전략

  • 파티션을 노드에 (새로) 할당하는 방법 3가지
  • (나쁜 예 : mod N 연산 => N 변경시 대부분의 데이터가 이동되어야함)

파티션 개수 고정

파티션 크기 ∝ 전체 데이터셋 크기

  • 파티션을 노드 대수보다 많이 만들어서 각 노드당 여러 파티션을 할당
  • 노드 추가/제거 시) 기존 노드에서 파티션 몇개를 뺏어옴
    • 파티션은 노드 사이에서 통째로 이동 (파티션 개수 및 내용 유지)
    • 네트워크를 통해 데이터 이동 (시간 소요) => 리밸런싱 중 요청은 기존 할당된 파티션 사용
  • 장단점
    • 장점 : 파티션 통째로 이동. 바뀌는점은 “어느 노드에 어느 파티션이 할당되었나” 뿐
    • 단점 : 파티션 수는 고정인데 데이터셋 크기 변동이 심할 경우 => 적절한 파티션 수 지정 어려움
      • 대부분 처음 설정된 파티션 수 = 사용 가능한 노드 대수의 최대치
      • 파티션이 너무 작으면 오버헤드↑, 너무 크면 재균형화와 노드 장애 시 복구 비용↑
  • 사용 예
    • Riak, ES, CouchBase, Voldmort

동적 파티셔닝

파티션 크기 ∝ 데이터 셋

  • 파티션 개수가 고정되면 문제가 생기는 경우 (ex. 키 범위 파티셔닝)
  • 동적 파티셔닝
    • 파티션 크기가 설정된 값을 넘어서면 두개로 쪼갬
    • 파티션 크기가 임곗값 아래로 떨어지면 인접한 파티션과 합침 (like B트리)
  • 사전 분할(pre-splitting)
    • 빈 데이터베이스의 초기 파티션 집합 설정
  • 장단점
    • 장점 : 전체 데이터양에 맞게 조정되는 적절한 파티션 수 (오버헤드 ↓)
    • 단점 : 시작 시에는 파티션이 하나 (사전정보 x)
  • 사용 예
    • HBase, RethinkDB (키 범위), MongoDB (>2.4, 키 범위 & 해시)

노드 비례 파티셔닝

파티션 개수 ∝ 노드 대수

  • 노드당 할당되는 파티션 개수를 고정
    • 노드 대수가 동일하면 (= 파티션 개수 고정)
    • 노드 대수가 증가하면 => 파티션 수 ↓ (절반은 두고 절반은 새 노드에 할당)
  • 장단점
    • 장점 : 개별 파티션 크기가 안정적
    • 단점 : 신규 노드 추가로 인한 파티션 분할 시 무작위 분할 => 균등하지 않은 분할 가능성
      • 무작위 분할 => 해시 기반 파티셔닝 사용 (=일관성 해싱)

운영: 자동 재균형화와 수동 재균형화

  • 재균형화는 자동으로해야할까 수동으로해야할까?
    • 완전 자동 재균형화 vs 완전 수동 재균형화
    • 그 중간 어디쯤.. => 시스템이 자동으로 파티션 할당을 제안하고 + 관리자가 확정해야 반영되는
  • 자동 재균형화
    • 편리하지만, 예측이 어렵고 성능 저하 이슈나 연쇄 장애 가능성
  • 수동 재균형화
    • 느리지만 예상치 못한 이슈 방지 가능

06-4 요청 라우팅

“Service Discovery”

  • Service Discovery 접근법 (라우팅 방법) 3가지
    • 노드 : 아무 노드나 읽어서 어느 노드에 있는지 찾아서 요청
    • 라우팅 계층 : 모든 요청을 라우팅 계층으로 보내서 전달 (Partition-aware LB)
    • 클라이언트 : 클라Client가 파티셔닝 방법 및 할당 위치를 알고 직접 해당 노드에 요청
  • 핵심 문제는? => “파티션의 변경 사항을 어떻게 알것인가”
    • 외부의 별도 코디네이션 (ex. Zookeeper) 사용 : 변경사항에 대해 모든걸 관리하고 알려줌
    • 가십 프로토콜 (gossip protocol): 클러스터 상태 변화를 노드 사이에 퍼뜨림. 노드 복잡도 ↑ 외부의존도 ↓

병렬 질의 실행

  • 더 복잡한 종류의 질의 (분석용)
    • => 대규모 병렬 처리 (MPP, Massively Parallel Processing) 관계형 DB
  • MPP 질의 최적화기가 복잡한 질의를 분해하여 서로 다른 노드에서 병렬적 실행 가능하게함
    • 웨어하우스 질의 (join, filter, grouping, aggregation)
  • 데이터 웨어하우스 질의 고속 병렬 실행

06 정리

  • 파티셔닝이란
    • 대용량 데이터셋을 더욱 작은 데이터셋으로 파티셔닝
  • 파티셔닝의 목적
    • 핫스팟이 생기지 않게 + 데이터와 질의부하를 균일하게 분배
  • 주요 파티셔닝 기법 2가지
    • 키 범위 파티셔닝 (보통 동적)
    • 해시 파티셔닝 (보통 고정 파티션수)
  • 파티셔닝 + 보조 색인
    • 문서 파티셔닝 색인 (지역)
    • 용어 파티셔닝 색인 (전역)
  • 질의 라우팅 기법