Post

[분산 시스템] Day 3: 파티셔닝 - 데이터를 쪼개 나눠 담기

[분산 시스템] Day 3: 파티셔닝 - 데이터를 쪼개 나눠 담기

이 글은 AI(Claude)의 도움을 받아 작성하고, 작성자가 검토·편집했습니다.

서론: 복제만으로는 부족할 때

복제(Day 2)는 같은 데이터의 사본을 늘린다. 하지만 데이터 자체가 한 노드의 디스크·메모리를 넘으면 사본을 늘려도 소용없다. 파티셔닝(샤딩)은 데이터를 여러 조각으로 쪼개 서로 다른 노드에 나눠 담는다. 쓰기 부하와 저장 용량을 수평 확장하는 유일한 길이다. 보통 복제와 함께 쓴다(각 파티션을 또 복제).

1. 파티셔닝의 목표와 함정

1
2
3
목표: 데이터와 부하를 노드들에 "고르게" 분산
함정: 한 파티션에 부하가 쏠리는 핫스팟(hot spot)
      → 한 노드만 과부하, 나머지는 놀고, 확장 효과 사라짐

파티셔닝 설계의 성패는 “얼마나 고르게 나누는가”와 “노드를 추가할 때 얼마나 적게 옮기는가”에 달렸다.

2. 키 범위 파티셔닝

키를 정렬해 연속 범위로 나눈다.

1
2
3
4
5
6
파티션 A: 키 a~h
파티션 B: 키 i~p
파티션 C: 키 q~z

✅ 범위 스캔 효율적 (정렬돼 있음). HBase, Bigtable 방식.
❌ 핫스팟 위험: 타임스탬프를 키로 쓰면 항상 최신 파티션에만 쓰기 몰림

시계열 데이터를 시간 키로 범위 분할하면 “오늘” 파티션에만 모든 쓰기가 집중된다. 키 앞에 다른 차원(센서 ID 등)을 붙여 분산한다.

3. 해시 파티셔닝

키를 해시해 범위로 나눈다. 핫스팟에 강하다.

1
2
3
4
5
partition = hash(key) % N

✅ 균등 분산: 해시가 키를 흩뜨려 핫스팟 완화
❌ 범위 스캔 불가 (인접 키가 다른 파티션으로 흩어짐)
❌ 치명적 결함: N이 바뀌면(노드 추가) 거의 모든 키의 위치가 바뀜

hash(key) % N은 노드를 하나만 추가해도 % N% (N+1)로 바뀌어 대부분의 키가 재배치된다. 대규모 데이터 이동이 발생한다. 이 문제를 일관성 해싱이 푼다.

4. 일관성 해싱

노드와 키를 같은 해시 링(0 ~ 2^32) 위에 올리고, 키는 시계 방향으로 만나는 첫 노드에 속한다.

1
2
3
4
5
6
7
8
9
10
        Node A (해시 위치 100)
       /                      \
  key(50)→A              Node B (위치 4000)
      |                       |
  Node D (위치 60000)    key(2000)→B
       \                      /
        Node C (위치 30000)

노드 B 추가 시: B 앞 구간의 키만 이동, 나머지는 그대로
→ 평균 K/N개의 키만 재배치 (전체가 아니라)

노드 추가/삭제 시 인접한 일부 키만 옮기면 된다. 가상 노드(virtual node)를 도입해 각 물리 노드를 링 위 여러 지점에 배치하면 분산이 더 고르고, 노드 장애 시 부하가 한 노드로 쏠리지 않는다. Cassandra, DynamoDB가 이 방식을 쓴다.

5. 핫스팟과 보조 인덱스

해시 파티셔닝도 특정 키 하나에 트래픽이 폭증하면(유명인 계정 등) 못 막는다.

1
2
3
완화: 핫 키에 랜덤 접미사를 붙여 여러 파티션으로 분산
  user_123_00, user_123_01, ... user_123_09
  → 읽을 땐 10개 파티션을 모두 조회해 합침 (쓰기 분산 ↔ 읽기 비용 트레이드오프)

또한 파티셔닝은 보통 기본 키(primary key) 기준이라, 다른 속성으로 조회하는 보조 인덱스가 문제다.

1
2
3
4
5
6
7
로컬 인덱스(document-partitioned):
  각 파티션이 자기 데이터의 인덱스만 보유
  쓰기 빠름, 읽기는 모든 파티션 조회 필요(scatter-gather)

글로벌 인덱스(term-partitioned):
  인덱스 자체를 별도로 파티셔닝
  읽기 빠름(해당 인덱스 파티션만), 쓰기는 여러 파티션 갱신 필요

6. 리밸런싱과 요청 라우팅

노드를 추가할 때 데이터를 어떻게 옮기고, 클라이언트는 어느 노드로 가야 하는지 알아야 한다.

1
2
3
4
5
6
7
8
9
10
리밸런싱 원칙:
  - hash % N 회피 (전체 재배치 유발)
  - 고정 개수 파티션을 미리 많이 만들어 노드 간 이동만 (Elasticsearch 방식)
  - 자동 리밸런싱은 편하지만, 부하 급증 시 폭주 위험 → 운영자 승인 권장

요청 라우팅 (어느 노드?):
  1. 아무 노드나 받아 내부 전달
  2. 라우팅 계층(프록시)이 결정
  3. 클라이언트가 직접 파티션 매핑을 앎
  → 보통 ZooKeeper/etcd 같은 코디네이터가 매핑을 관리

7. Day 3 체크리스트

  1. 파티셔닝이 저장 용량·쓰기 부하의 수평 확장 수단임을 이해했다.
  2. 키 범위(스캔 유리, 핫스팟 위험)와 해시(균등, 스캔 불가) 방식을 비교했다.
  3. hash % N의 재배치 문제를 일관성 해싱과 가상 노드가 푸는 원리를 안다.
  4. 핫 키 분산과 로컬/글로벌 보조 인덱스의 트레이드오프를 파악했다.
  5. 리밸런싱 전략과 코디네이터 기반 요청 라우팅을 이해했다.

다음 편 예고

복제와 파티셔닝을 갖추면 시스템은 분산되지만, “어디까지 일관성을 보장하는가”라는 질문이 남는다. Day 4에서는 CAP 정리와 일관성 모델(강한 일관성부터 최종 일관성까지)을 정리한다.

This post is licensed under CC BY 4.0 by the author.