-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
735 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
--- | ||
theme: gaia | ||
_class: lead | ||
paginate: true | ||
marp: true | ||
backgroundColor: #0000 | ||
backgroundImage: url('https://marp.app/assets/hero-background.svg') | ||
|
||
--- | ||
|
||
# 안정해시 설계 | ||
|
||
--- | ||
|
||
# 왜 안정해시 설계를 알아야 할까? | ||
|
||
안정해시설계의 이론은 간단하다. 컴퓨터 구조에도 맞닿는 부분이 있다. | ||
|
||
일단 안정해시설계가 나온 배경부터 이해해보자. | ||
|
||
해시는 요청 또는 데이터를 서버에 균등하게 나누는 것이 중요하다. | ||
|
||
serverIndex = hash(key) % N(서버의 개수) | ||
|
||
여기서 hash() 는 어떤 알고리즘에 의한 함수. | ||
|
||
|
||
--- | ||
|
||
안정해시설계가 나온 이유? | ||
|
||
문제점 | ||
|
||
해시 키 재배치(rehash) 문제 | ||
|
||
모듈러 연산을 통해 부하를 균등하게 나눌 수 있는 서버 4대가 있다. | ||
|
||
111,222,333,444,555,666,777,888,999 의 해시를 갖는 키가 있다고 가정해보자. | ||
|
||
--- | ||
|
||
| 키 | 해시 | 해시 % 4(서버 인덱스) | | ||
| ----- | ---- | ------------------- | | ||
| key 0 | 111 | 1 | | ||
| key 1 | 222 | 2 | | ||
| key 2 | 333 | 3 | | ||
| key 3 | 444 | 0 | | ||
| key 4 | 555 | 1 | | ||
| key 5 | 666 | 2 | | ||
| key 6 | 777 | 3 | | ||
| key 7 | 888 | 0 | | ||
| key 8 | 999 | 1 | | ||
|
||
--- | ||
|
||
| 서버 | 해시키 | | ||
| ----- | ---- | | ||
| Server 1 | key0, key4, key7 | | ||
| Server 2 | key 1, key 5 | | ||
| Server 3 | key 2, key 6 | | ||
| Server 4 | key 3, key 7 | | ||
|
||
균등하게 배포될 수 있다. 그래서 예시에서는 해시의 키가 이미 정렬된 상태였기 때문에 가능했던 것이며, 여기서 만약 Server 1이 죽으면 어떻게 될까? 다시 재배치를 해야될텐데. | ||
|
||
___ | ||
|
||
# 모듈러 계산 | ||
|
||
### **해시 % 4(서버 인덱스)** 에서 | ||
|
||
### **해시 % 3(서버 인덱스)** 으로 변하게 된다. | ||
|
||
그럼 Server 1 에서 가졌던 key0, key4, key7 키뿐만 아니라 모든 해시키가 재배치된다. | ||
|
||
그 결과로 기존에 Server1,2,3,4 를 쓰던 클라이언트는 엉뚱한 서버에서 값을 찾을 테고 그 결과 대뮤고 캐시미스(cache miss)가 발생한다. | ||
|
||
--- | ||
|
||
## 안정 해시 | ||
그래서 나온게 안정 해시 | ||
|
||
안정해시는 해시 테이블이 조정될 때 **평균적으로 오직 k/n개** 의 키만 재배치하는 해시 기술. | ||
|
||
여기서 해시 공간과 해시 링 등장인물이 등장 | ||
|
||
S1,2,3 는 해시 서버 | ||
|
||
![bg right 70%](https://raw.githubusercontent.com/LenKIM/images/master/2024-03-02/image-20240302011454533.png) | ||
|
||
--- | ||
해시 키는 k0,k1,k2,k3 로 표현된다. 이때 각 키는 모듈러 연산으로 나온 결과물을 의미하지 않는다. | ||
|
||
이때 각각의 키는 시계방향으로 링을 탐색하면 마주치는 서버에 저장. | ||
|
||
![bg left 70%](https://raw.githubusercontent.com/LenKIM/images/master/2024-03-02/image-20240302011638788.png) | ||
|
||
|
||
![bg left 80%](https://raw.githubusercontent.com/LenKIM/images/master/2024-03-02/image-20240302011904221.png) | ||
|
||
만약 s0 이 사라진다면? | ||
|
||
또는 s0_1이 추가된다면 | ||
|
||
다시 말하지만 안정해시는 평균적으로 오직 k/n개 키만 재배치하는 해시 기술이다. | ||
|
||
--- | ||
|
||
위 방식의 안정해시 기술은 2가지 문제점 | ||
|
||
**첫번째** | ||
서버가 추가되거나 삭제되는 상황을 감안하면 파티션(partition)의 크기를 균등하게 유지하는 게 불가능하다는 것(파티션은 인접한 서버 사이의 해시 공간) | ||
|
||
어떤 서버는 굉장히 작은 해시 공간을 할당 받고, 어떤 서버는 굉장히 큰 해시 공간을 할당 받는 상황이 가능하다는 것. | ||
|
||
**두번째** | ||
키의 균등 분포(unifrom distribution)를 달성하기가 어렵다는 것. 균등한 키의 분포를 해결하기 위해서 제안된 기법은 가상 노드(virtual node) 또는 복제(replica)라 불리는 기법 | ||
|
||
--- | ||
|
||
어떻게 해결할 수 있을까? 앞에서 언급한 **가상 노드** 를 활용 | ||
|
||
![bg right 100%](https://raw.githubusercontent.com/LenKIM/images/master/2024-03-02/image-20240302013203702.png) | ||
|
||
가상 노드의 개수를 늘리면 키의 분포는 점점 더 균등. | ||
|
||
표준 편차(standard deviation)가 작아져서 데이터가 고르게 분포되기 때문. | ||
|
||
타협적 결정(tradeoff) | ||
|
||
|
||
--- | ||
|
||
**코드 살펴보기** | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
# 5장 안정 해시 설계 | ||
|
||
|
||
|
||
수평적 규모 확장성? | ||
|
||
요청 또는 데이터를 서버에 균등하게 나누는 것이 중요. | ||
|
||
|
||
|
||
## 해시 키 재배치(rehash) 문제 | ||
|
||
N개의 캐시 서버. 이 서버들에게 부하를 균등하게 나누는 보편적 방법은 아래의 해시 함수 사용 | ||
|
||
serverIndex = hash(key) % N(서버의 개수) | ||
|
||
|
||
|
||
모듈러 연산을 통해 분새를 시킨다. 이 방법은 서버 풀(server pool)의 크기가 고정되어 있을 때, 그리고 데이터 분포가 균등할 때는 잘 동작한다. 하지만, 서버가 추가되거나 기존 서버가 삭제되면 문제가 생긴다. 한쪽으로 몰리는 현상이 발생할 수 있다. | ||
|
||
그 결과 캐시 미스(cache miss)가 발생할 수 있다. 안정해시는 이 문제를 효과적으로 해결하는 기술 | ||
|
||
| 키 | 해시 | 해시%4(서버 인덱스) | | ||
| ----- | ---- | ------------------- | | ||
| key 0 | 111 | 1 | | ||
| key 1 | 222 | 2 | | ||
| key 2 | 333 | 3 | | ||
| key 3 | 444 | 0 | | ||
| key 4 | 555 | 1 | | ||
| key 5 | 666 | 2 | | ||
| key 6 | 777 | 3 | | ||
| key 7 | 888 | 0 | | ||
| key 8 | 999 | 1 | | ||
|
||
|
||
|
||
### 안정 해시 | ||
|
||
안정해시란? 해시 테이블 크기가 조정될 때 평균적으로 오직 k/n 개의 키만 재배치하는 해시 기술. 여기서 k는 키의 개수이고, n은 슬롯(slot)의 개수. 이와는 달리 대부분의 전통적 해시 테이블은 슬롯의 수가 바뀌면 거의 대부분 키를 재배치한다. | ||
|
||
|
||
|
||
### 해시 공간과 해시 링 | ||
|
||
어떻게 동작 하는걸까? 해시 함수 f는 SHA-1을 사용하고, 출력 값의 범위는 x0, x1,x2,x3 ..xn과 같다고 하자. SHA-1의 해시 공간(hash space) 범위는 2^160-1까지라고 알려져 있다. | ||
|
||
|
||
|
||
**해시서버** | ||
|
||
<img src="https://raw.githubusercontent.com/LenKIM/images/master/2024-03-02/image-20240302011454533.png" alt="image-20240302011454533" style="zoom:50%;" /> | ||
|
||
4개의 서버를 배치하고, | ||
|
||
**해시 키** 를 해시 링 위의 어느 지점에 배치할 수 있다. | ||
|
||
<img src="https://raw.githubusercontent.com/LenKIM/images/master/2024-03-02/image-20240302011638788.png" alt="image-20240302011638788" style="zoom:50%;" /> | ||
|
||
**서버 조회** | ||
|
||
어떤 키가 저장되는 서버는, 해당 키의 위치로부터 시계 방향으로 링을 탐색해 나가면서 만나는 첫 번재 서버. | ||
|
||
<img src="https://raw.githubusercontent.com/LenKIM/images/master/2024-03-02/image-20240302011904221.png" alt="image-20240302011904221" style="zoom:50%;" /> | ||
|
||
**서버 추가** | ||
|
||
중간에 서버를 추가하더라도 키 가운데 일부만 재배치하면 된다. | ||
|
||
**서버 제거** | ||
|
||
삭제를 하더라도 마찬가지. | ||
|
||
|
||
|
||
**기본 구현법의 두 가지 문제.** | ||
|
||
안정 해시 알고리즘의 절차는 다음과 같다. | ||
|
||
- 서버와 키를 균등 분포(uniform distrubution) 해시 함수를 사용해 해시 링에 배치한다. | ||
- 키의 위치에서 링을 시계 방향으로 탐색하다 만나는 최초의 서버가 키가 저장될 서버다. | ||
|
||
이 접근법에는 두 가지 문제. 서버가 추가되거나 삭제되는 상황을 감안하면 파티션(partition)의 크기를 균등하게 유지하는 게 불가능하다는 것**이 첫번째.** 여기서 파티션은 인접한 서버 사이의 해시 공간. | ||
|
||
어떤 서버는 굉장히 작은 해시 공간을 할당 받고, 어떤 서버는 굉장히 큰 해시 공간을 할당 받는 상황이 가능하다는 것. | ||
|
||
**두 번째 문제**는 키의 균등 분포(unifrom distribution)를 달성하기가 어렵다는 것. 균등한 키의 분포를 해결하기 위해서 제안된 기법은 가상 노드(virtual node) 또는 복제(replica)라 불리는 기법 | ||
|
||
|
||
|
||
**가상 노드** | ||
|
||
실제 노드 또는 서버를 가리키는 노드로서, 하나의 서버는 링 위에 여러 개의 가상 노드를 가질 수 있다. | ||
|
||
<img src="https://raw.githubusercontent.com/LenKIM/images/master/2024-03-02/image-20240302013203702.png" alt="image-20240302013203702" style="zoom:50%;" /> | ||
|
||
가상 노드의 개수를 늘리면 키의 분포는 점점 더 균등. 표준 편차(standard deviation)가 작아져서 데이터가 고르게 분포되기 때문. | ||
|
||
- 표준 편차는 데이터가 어떻게 퍼져 나갔는지 보이는 척도. | ||
|
||
가상 노드의 개수를 더 늘리면 표준 편차의 값은 더 떨어진다. 그러나 가상 노드 데이터를 저장할 공간은 더 많이 필요하게 될 것이다. 타협적 결정(tradeoff)이 필요하다는 뜻. 시스템 요구사항에 맞도록 가상 노드 개수를 적절히 조정 | ||
|
||
|
||
|
||
**재배치할 키 결정** | ||
|
||
서버가 추가되거나 제거되면 데이터 일부는 재배치해야 한다. 어느 범위의 키들이 재배치되어야 할까? | ||
|
||
|
||
|
||
안정 해시가 왜 필요하며 어떻게 동작하는지를 살펴본 건데, 이점은 다음과 같다. | ||
|
||
- 서버가 추가되거나 삭제될 때 재배치되는 키의 수가 최소화된다. | ||
- 데이터가 보다 균등하게 분표하게 되므로 수평적 규모 확장성을 달성하기 쉽다. | ||
- 핫스팟(hotspot) 키문제를 줄인다. 특정 샤드에 대한 접근이 지나치게 빈번하면 서버 과부화 문제 발생. | ||
|
||
어디서 쓰는가? | ||
|
||
- 아마존 DynamoDB의 파티셔닝 관련 컴포넌트 | ||
- 카산드라 클러스터의 데이터 파티셔닝 | ||
- 디스코드 채팅 어플 | ||
|
||
--- |
Oops, something went wrong.