[시스템 디자인] 5장. 안정 해시 설계

혀어어언·2025년 9월 16일
0

5장. 안정 해시 설계

수평적 규모 확장성을 달성하기 위해서는 요청 또는 데이터를 서버에 균등하게 나누는 것이 중요하다
안정해시는 이를 달성하기 위해 보편적으로 사용하는 기술이다

1. 수평적 규모 확장이란?

  • 단일 서버 성능을 올리는 수직적 확장(Scale-up)과 달리, 서버를 여러 대로 나누어 부하를 분산하는 것
  • 균등하고 일관성 있는 데이터의 분산이 중요

2. 설계 관점에서의 서버 풀

2-1. 고정 서버 풀

  • 서버 수가 늘거나 줄지 않는 전제
  • 단순 해시(hash(key) % N)로도 충분
  • 균등 분포만 잘 맞추면 문제 없음

2-2. 변동 서버 풀

  • 현실 세계에서는 서버가 고정되지 않음:
    • 오토스케일링: 트래픽 스파이크 대응 위해 서버 증설/축소
    • 장애 대응: 서버가 죽으면 다른 서버로 재분배 필요
  • 이때 단순 모듈러 해시는 풀 사이즈가 바뀌면 전체 키 매핑이 바뀌는 문제 발생 → 재배치 비용이 매우 큼

3. 데이터 분산 방식

3-1. 단순 해시(Uniform / Modulo Hashing)

  • hash(key) % N (N = 서버 개수)로 분산
  • 키를 해시함수로 충분히 무작위로 섞은 후, 탐색이나 검색 없이 즉시 도달하는 인덱싱 모델
      long x = XxHash64.hash(keyBytes, seed); // 1. 해시 알고리즘 실행(섞기)
      int  i = Math.floorMod(x, N);           // 2. 범위 축소(인덱스 뽑기)
      Server s = servers[i];                  //    해당 인덱스의 서버 선택
  • 장점: 단순, 빠름, 균등 분배 가능
  • Naive 해시(hash(key) % N) 방식의 가장 큰 약점:
    • 서버 수 N이 바뀌면 전체 키 매핑이 바뀜.
    • 대규모 키 재배치발생 → 캐시 미스, 데이터 불일치 문제
  • 예: 서버 4대에서 5대로 확장 → 80% 이상의 키가 다른 서버로 이동

3-2. 안정 해시(Consistent Hashing)


4. 실무에서 고려할 점

4-1. 해시 함수 선택

  • 단순한 mod N 대신 어떤 해시 함수를 쓰느냐에 따라 분포 균등도가 달라짐
  • MD5, SHA-1 같은 암호학적 해시 vs MurmurHash, xxHash 같은 비암호학적 고속 해시
  • 분산 시스템에서는 충돌 최소화 + 속도 둘 다 중요

4-2. 가상 노드(Virtual Node, vnode)

  • 안정 해시만 쓰면 서버 개수가 적을 때 분포 불균형 발생
  • 각 서버를 여러 개의 가상 노드로 링에 배치하면 데이터 분포가 더 균등해짐

4-3. 서버 가중치(Weighted Consistent Hashing)

  • 모든 서버가 같은 스펙은 아님 → CPU, 메모리, 디스크, 네트워크 성능 차이 존재
  • 서버별 처리 능력에 따라 가중치 부여
  • 가상 노드 개수 ∝ 서버 성능 으로 균형 잡음

4-4. 데이터 이동 비용 (Resharding Overhead)

  • 서버 추가/삭제 시에도 일부 키는 이동해야 함
  • 데이터 이동 과정에서 캐시 미스 폭증, 백엔드(DB) 부하 급증 가능
  • 이를 줄이기 위해:
    • 백그라운드 점진적 마이그레이션
    • 더블 라이트(Double-write) 전략
    • 버전 기반 라우팅

4-5. 안정 해시와 CAP 정리

  • 분산 환경에서 노드 장애 → 데이터 재배치 → 일관성(Consistency) 문제 발생
  • Dynamo, Cassandra는 Eventual Consistency + 안정 해시 모델을 채택
  • RDBMS 스타일의 Strong Consistency를 원하면 안정 해시 적용 범위에 제약 생김

1) Eventual Consistency란?

  • 분산 시스템에서 모든 복제본(replica)이 즉시는 아니지만, 충분한 시간이 지나면 결국 동일한 상태로 수렴하는 일관성 모델
  • CAP 이론에서 Availability(가용성)Partition Tolerance(분할 내성)을 우선할 때 주로 채택
  • 강한 일관성(Strong Consistency)과 달리, 읽는 순간마다 최신 데이터를 보장하지 않는다
2) 동작 원리
  • 쓰기 요청이 들어오면 모든 노드에 동시에 적용되지 않고, 먼저 도착한 일부 노드에서 처리됨
  • 나머지 노드들은 비동기적 복제 / 동기화 프로세스를 통해 나중에 같은 데이터로 맞춰짐
  • 결국 어느 시점에는 모든 복제본이 같은 값을 가지게 됨
3) C.A.P
  • Consistency (일관성)
    → 모든 노드가 같은 시점에 동일한 데이터를 보여준다
  • Availability (가용성)
    → 모든 요청에 대해 항상 응답을 돌려줄 수 있다 (성공/실패 여부 무관)
  • Partition Tolerance (분할 내성)
    → 네트워크가 분리(Partition)돼도 시스템은 계속 동작할 수 있다

4-6. 안정 해시 대안 기법

1) Rendezvous Hashing (HRW, Highest Random Weight)

  • Consistent Hashing보다 간단하면서도 비슷한 재배치 성질
  • 구글 GFS, Ceph, 일부 CDN에서 사용
    • 장점: 균등 분포, 구현 단순, Consistent Hashing보다 데이터 이동량이 더 적을 수 있음

2) Jump Consistent Hashing

  • 구글이 제안, O(1) 시간 복잡도, 균등 분포 뛰어남
  • Kafka, FoundationDB 같은 대규모 분산 시스템에서 채택

5. 운영 단계에서 해시와 안정 해시의 문제들

5-1. 데이터 분포 균등성 (Uniformity)

  • 해시는 이상적으로 키를 균등하게 분배해야 함
  • 하지만 실제 운영에서는 Hotspot Key / Celebrity Problem이 발생:
    • 예: 특정 사용자 ID(연예인 계정), 특정 해시 범위에만 트래픽 집중
  • 안정 해시를 쓰더라도, 키 분포 자체가 편향되면 샤드 불균형은 피할 수 없음

해결 전략

  • Sharding Key 설계: 고카디널리티(high cardinality) 키 선택
  • Hash Salting: 키에 무작위성을 추가해 편향 완화
  • Virtual Nodes (가상 노드): 한 물리 노드가 여러 해시 구간 담당 → 균등화

5-2. 노드 추가/삭제 시 데이터 재배치 비용

  • 단순 해싱(Mod N) 방식:
    • 서버 수가 바뀌면, 전체 키의 대부분이 다른 서버로 이동 → 재배치 비용 큼
  • 안정 해시:
    • 노드 추가/삭제 시, 해당 구간 일부 키만 이동 → 비용 최소화
  • 그러나 재배치 자체는 여전히 비용:
    • TB 단위 데이터를 옮기는 데 수시간~수일
    • 그동안 읽기/쓰기 지연 발생

해결 전략

  • Rebalancing Window: 트래픽이 낮은 시간대에 점진적 재분배
  • Double Write: 재분배 기간 동안 두 노드에 동시에 기록해 일관성 유지
  • Lazy Migration: 요청 시점에 필요한 키만 새로운 노드로 점진적으로 옮김

5-3. 데이터 일관성 (Consistency)

  • 분산 해시 환경에서는, 노드 이동/장애 시 데이터 복제가 중요
  • 안정 해시의 기본 구조는 N개의 인접 노드에 복제(replica) → Dynamo, Cassandra.
  • 문제:
    • 네트워크 분할(Partition) → 일부 노드만 최신 데이터 보유
    • 복제본 간 충돌(conflict) 발생

해결 전략

  • Quorum 기반 읽기/쓰기: W+R > N 보장 (예: 3개의 복제 중 2개 이상 성공해야 ack)
  • Conflict Resolution: Last Write Wins, Vector Clock, CRDT 등
  • Eventual Consistency 허용 여부 결정: 애플리케이션 성격 따라 선택

5-4. 장애 복구와 트래픽 우회

  • 노드가 죽으면, 해당 구간 키 요청이 모두 장애로 이어짐

  • 안정 해시는 바로 인접 노드로 우회 가능하지만, 실제 운영은 더 복잡:

    • 캐시/DB 미스율 폭발
    • 특정 노드로 트래픽 집중(2차 장애)

    해결 전략

  • Replica 활용: 읽기는 다른 복제본에서 즉시 처리

  • Auto-Rebalancing 제어: 장애 시 자동 리밸런싱을 막고, 임시 우회 후 복구 단계에서 이동

  • Rate Limiting + Circuit Breaker: Failover 중 과부하 방지


5-5. 관측성과 모니터링

  • 운영 시 가장 큰 문제 중 하나는 샤드 불균형을 조기에 탐지하지 못하는 것
  • 해시 분포 문제는 지표로 드러남:
    • 샤드별 QPS, Latency, Storage Usage, Cache Hit Rate
  • 안정 해시라고 해서 자동으로 "균등"이 보장되는 건 아님 → 반드시 모니터링 필요

핵심 지표

  • 키 분포 균등도(Entropy)
  • 샤드별 Hotspot 비율
  • 재배치 중 지연 시간 증가율

5-6. 운영 환경에서의 설계 Trade-off

1) 서버 풀(Server Pool)의 고정 vs 변동

  • 고정 풀: 서버 수가 잘 변하지 않으면, 단순 해싱(Mod N)도 가능 → 운영 단순
  • 변동 풀: 클라우드 오토스케일링, 다중 데이터센터 환경이라면 → 안정 해시 필수

2) 데이터 분포

  • 분포가 완전히 랜덤이라면 이상적 → 하지만 실제 키는 특정 패턴(사용자 ID, 지역, 시간대)에 따라 편향
  • 해시 함수 선택, 키 설계가 중요

3) 안정 해시와 변형 기법

  • Virtual Nodes: 균등화 보완
  • Jump Hashing: O(1) 매핑, 대규모 클러스터 효율적
  • Rendezvous Hashing: 데이터 이동량 최소화

0개의 댓글