05.안정 해시 설계
대규모 시스템 설계 기초 5장을 요약한 내용입니다.
Last updated
대규모 시스템 설계 기초 5장을 요약한 내용입니다.
Last updated
수평적 규모 확장성을 달성하기 위해 요청 또는 데이터를 서버에 균등하게 나누는 것이 중요하다.
안정 해시는 이 목표를 달성하기 위해 보편적으로 사용하는 기술이다.
N개의 캐시 서버가 있다면, 서버들에 부하를 균등하게 나누는 보편적인 방법은 하시 함수를 사용하는 것이다.
serverIndex = hash(key) % N
(N은 서버 개수)
총 4대의 서버를 사용한다면 각 키에 대한 해시 값과 서버 인덱스를 계산하면 아래와 같다.
특정 키가 보관된 서버를 알아내기 위해 나머지 연산을 f(key) % 4
적용
hash(key0) % 4 = 1 이면, 클라이언트는 캐시에 보관된 데이터를 가져오기 위해 서버 1에 접속
이 방법은 서버 풀(server pool) 크기가 고정되어 있고, 데이터 분포가 균등할 때는 잘 동작하지만, 서버가 추가되거나 기존 서버가 삭제되면 문제가 생긴다.
나머지 연산을 적용하여 계산한 서버 인덱스 값이 달려져서 대부분의 키가 재분배되고, 캐시 클라이언트가 데이터가 없는 엉뚱한 서버에 접속하게 된다.
결과적으로 대규모 캐시 미스가 발생하게 될 것이다.
안정 해시는 이 문제를 효과적으로 해결하는 기술이다.
안정 해시
해시 테이블 크기가 조정될 때 평균적으로 오직 k/n개의 키만 재배치하는 해시 기술 (k: 키의 개수, n: 슬롯 개수)
(이와 달리 대부분의 전통 해시 테이블은 슬롯의 수가 바뀌면 거의 대부분 키를 재배치)
안정 해시의 동작 원리
해시 함수 f로는 SHA-1을 사용한다고 하고, 그 함수의 출력 값 범위는 x0, x1, x2, x3, ...xn과 같다고 하자.
SHA-1의 해시 공간(hash space) 범위는 0부터 2^160 - 1까지라고 알려져 있다.
따라서 x0은 0, xn은 2^160 - 1이며, 나머지 x1부터 xn-1까지는 그 사이의 값을 갖게 된다.
이 해시 공간의 양 쪽을 구부려 접으면 해시 링(hash ring)이 만들어진다.
이 해시 함수 f를 사용하면 서버 IP나 이름을 링 위의 어떤 위치에 대응시킬 수 있다.
4개의 서버를 이 해시 링 위에 배치한 결과
여기 사용된 해시 함수는 "해시 키 재배치 문제" 언급된 함수와 다르며, 나머지 연산 %은 사용하지 않고 있다.
캐시할 키 key0, key1, key2, key3 또한 해시 링 위의 어느 지점에 배치할 수 있다.
어떤 키가 저장되는 서버는 해당 키의 위치로부터 시계 방향으로 링을 탐색해 나가면서 만나는 첫 번째 서버
key0은 서버 0에 저장되고 key1은 서버 1에, key2는 서버 2, key3은 서버 3에 저장
서버를 추가하더라도 키 가운데 일부만 재배치하면 된다.
서버 4가 추가된 뒤 key0만 서버 4로 재배치되고 다른 키들은 유지
key0의 위치에서 시계 방향으로 순회했을 때 처음으로 만나게 되는 서버가 서버 4
하나의 서버가 제거되면 키 가운데 일부만 재배치
서버 1이 삭제되었을 때 key1만 서버 2로 재배치
나머지 키에는 영향 없음
기본 절차
서버와 키를 균등 분포 해시 함수를 사용해 해시 링에 배치
키의 위치에서 링을 시계 방향으로 탐색하다 만나는 최초의 서버가 키가 저장될 서버
.
문제점
(1) 서버가 추가되거나 삭제되는 상황을 감안하면 파티션의 크기를 균등하게 유지하는 게 불가능
파티션은 인접한 서버 사이의 해시 공간
서버 1이 삭제되어 서버 2의 파티션이 다른 파티션 대비 두 배로 커지는 상황
(2) 키의 균등 분포를 달성하기 어려움
서버 1과 서버 3은 아무 데이터도 갖지 않는 반면, 대부분의 키는 서버 2에 보관
이 문제를 해결하기 위해 제안된 기법이 가상 노드(virtual node) 또는 복제(replica)라 불리는 기법
가상 노드는 실제 노드 또는 서버를 가리키는 노드
하나의 서버는 링 위에 여러 개의 가상 노드를 가질 수 있음
아래 예시를 보면 서버 0과 서버 1은 3개의 가상 노드를 갖는다. (실제 시스템에서는 그보다 훨씬 큰 값을 사용)
각 서버는 하나가 아닌 여러 개 파티션을 관리해야 한다.
키의 위치로부터 시계방향으로 링을 탐색하다 만나는 가상 노드가 해당 키에 저장될 서버가 된다.
k0가 저장되는 서버는 s1_1, 즉 서버 1
가상 노드 개수를 늘리면 키의 분포는 점점 더 균등해진다.
표준 편차(standard deviation)가 작아져서 데이터가 고르게 분포되기 때문
표준 편차: 데이터가 어떻게 퍼져 나갔는지 보이는 척도
100~200개의 가상 노드를 사용했을 경우 표준 편차 값은 평균의 5%에서 10% 사이
가상 노드의 개수를 더 늘리면 표준 편차의 값은 더 떨어지지만 가상 노드 데이터를 저장할 공간은 더 많이 필요할 것이다.
타협적 결정(tradeoff)이 필요하니 시스템 요구사항에 맞도록 가상 노드 개수를 적절히 조정해야 함
서버가 추가/제거되면 데이터 일부는 재배치해야 한다.
어느 범위의 키들이 재배치되어야 할까?
서버 4가 추가되었다고 가정하면 이에 영향 받은 범위는 새로 추가된 s4 노드부터 그 반시계 방향에 있는 첫 번째 서버 s3까지이다.
즉, s3 부터 s4 사이에 있는 키들을 s4로 재배치 해야 한다.
서버 s1이 삭제되면 s1부터 그 반시계 방향에 있는 최초 서버 s0 사이에 있는 키들이 s2로 재배치되어야 한다.
안정 해시의 이점
서버가 추가되거나 삭제될 때 재배치되는 키의 수가 최소화된다.
데이터가 보다 균드앟게 분포되어 수평적 규모 확장성을 달성하기 쉽다.
핫스팟(hotspot)키 문제를 줄인다.
특정한 샤드에 대한 접근이 지나치게 빈번하면 서버 과부하 문제가 생길 수 있지만, 안정 해시는 데이터를 좀 더 균등하게 분배하여 이러한 문제 가능성을 줄인다.
안정 해시를 사용하는 유명한 몇 가지
Amazon DynamoDB의 파티셔닝 관련 컴포넌트
Apache Cassandra 클러스터에서의 데이터 파티셔닝
Discord 채팅 어플리케이션
Akamai CDN
Meglev 네트워크 부하 분산기