한양과학기술고등학교

에듀테크 프로젝트 대시보드

일관된 해싱 (Consistent Hashing)

일관된 해싱 (Consistent Hashing)

여러 대의 서버에 데이터를 나눠 저장할 때 가장 단순한 방법은 server = hash(key) % N 이다. 하지만 서버가 한 대 늘거나 줄면 N 이 바뀌면서 거의 모든 키가 다른 서버로 이동한다(캐시 전체 무효화). 일관된 해싱은 키와 서버를 같은 해시 링 위에 올려놓고, 각 키를 "시계 방향으로 만나는 첫 서버"에 맡긴다. 서버가 바뀌어도 영향받는 키는 평균 1/N 뿐이다.

해시 링 시뮬레이터

1
서버(노드) 키(데이터) 방금 이동한 키
서버를 추가하면 링 위에 배치됩니다.

모듈러 해싱 vs 일관된 해싱 — 재배치 비용

현재 키 0개 · 서버 0대 상태에서 서버를 한 대 더 추가하면 몇 개의 키가 다른 서버로 옮겨가야 하는지 비교한다.

hash(key) % N

–
서버 수가 바뀌면 대부분 재배치

일관된 해싱

–
새 서버 구간의 키만 이동

왜 차이가 날까? 모듈러 방식은 나눗셈의 나머지가 N 에 의존하므로 N 이 바뀌면 거의 모든 매핑이 깨진다. 일관된 해싱에서 새 서버는 링의 한 구간만 넘겨받으므로, 그 구간에 있던 키만 이동한다.

핵심 로직 (의사코드)

# 링은 정렬된 (해시값 → 서버) 목록. 가상 노드로 각 서버를 여러 번 배치한다.
def build_ring(servers, vnodes=100):
    ring = []
    for s in servers:
        for i in range(vnodes):
            ring.append( (hash(f"{s}#{i}"), s) )
    return sorted(ring)

def lookup(ring, key):
    h = hash(key)
    for (pos, server) in ring:        # 실제로는 이진 탐색 O(log M)
        if pos >= h:
            return server
    return ring[0][1]                 # 링을 한 바퀴 돌아 처음으로
  • 가상 노드(vnode): 서버 한 대를 링에 수십~수백 번 흩뿌려 배치 → 구간 크기가 고르게 되어 부하 불균형을 줄인다.
  • 탐색 비용: 링을 정렬해두면 이진 탐색으로 O(log M) (M = 총 vnode 수).
  • 실제 사용처: Redis Cluster, Cassandra, DynamoDB, 카프카 파티셔너, CDN 캐시 분산, memcached 클라이언트(ketama).