해싱을 통해 샤딩을 하는 경우 최초 설정된 샤드 갯수가 변동됐을 때 리해싱(샤딩의 규칙을 재정의)을 해야한다.
그 방법은 크게 3가지로 구분할 수 있다.
1. 이동하는 레코드 개수가 최소가 되는 알고리즘 사용한다. => 일관된 해시
2. 이동할 일이 없게 만든다. => 매핑 DB
3. 이동하더라도 이동하는 레코드 크기를 최소로 만든다. =>
일관된 해싱(Consistent hashing)?
원래는 샤드의 변동이 있다면 모든 레코드들에 대해 재배치 연산을 진행해야 하지만 데이터량이 너무 많은 경우 오랜 시간이 걸린다.
일관된 해싱을 사용하면 변동된 샤드에 대해선 재배치 연산을 하면 된다.
샤드가 추가될 때마다 기존 샤드 집합에서 본인이 담당해야 할 데이터를 가져오고 샤드가 줄어들 때마다 그 머신의 데이터는 남아있는 머신에 공유된다.
보통, n개의 캐싱 머신을 로드밸런싱하는 방법은 데이터(O)에 대한 해시값을 모듈러 n 하는 방식인데[= hash(O) (mod n) ] , 이는 캐싱 머신이 늘어나거나 줄어들 때 n이 바뀌며 모든 데이터들이 새로운 곳에 해시되어야 한다. 이것은 매우 치명적일 수 있는데, 왜냐하면 기존의 데이터가 있는 서버가 캐싱 머신으로부터의 요청으로 과부하가 걸릴 수 있기 때문이다. 따라서 Consistent hashing은 서버의 과부하를 막기위해서 필요하다.
일관된 해싱은 데이터를 가능한 한 같은 캐싱 머신에 해싱시킨다. 이는 캐싱머신이 추가될 때, 추가되는 캐싱머신이 다른 모든 캐싱머신들로부터 데이터를 공유한다는 의미이다. 반대로 이 캐싱 머신이 클러스터에서 빠져나갈때, 이 머신의 데이터들은 클러스터에 남아있는 캐싱머신들사이에서 공유된다.
일관된 해싱의 핵심 목적은 각각의 캐시를 다른 해시 값 구간들과 연관시키도록 하는 것인데, 이 구간의 경계는 각각의 캐시 identifier의 해시를 계산하면서 결정된다. 만약 그 캐시가 제거된다면, 그 캐시의 구간은 적정의 구간과 함께 다른 캐시에 의해 취해진다. 모든 남아있는 캐시는 변하지않는다.
만약 버킷이 이용불가능하다면, hash ring에서의 버킷의 포인트는 제거된다. 그리고 그 버킷에 매핑된 모든 데이터에 대한 요청은 그 다음 포인트에 매핑된다. 각각의 버킷이 무수한 램덤하게 분산된 포인트들과 연관되기때문에 (vnode 혹은 vbucket이라 불리는 각 버킷의 virtual버전의 버킷들을 hash ring의 군데군데 만든다. 이로 인해 노드 제거시 부하 불균형을 해결한다.), 각 버킷에 소유되는 리소스들은 무수히 다른 버킷들로 매핑된다. 사라진 버킷에 소유되었던 데이터들은 남아있는 것들사이의 버킷들로 재분산된다. 그러나 다른 버킷에 매핑된 값은 여전히 그 같은 값이고, 이동될 필요가 없다.
매핑(Mapping)?
C언어에서 클래스와 구조체 보다는 그것의 포인터를 다루는 경우가 많다.
데이터베이스도 이와 마찬가지로 데이터를 저장하고 있는 위치를 가지고 있는 데이터베이스를 앞에 두면 일부의 데이터 수정만으로도 데이터의 재배치가 가능해진다.
다만 차후 매핑DB가 병목지점이 될 수 있으므로 여기서도 분산 저장을 해야하며 클라이언트가 임의로 접근하게 한다.
추가
https://www.popit.kr/consistent-hashing/
https://www.joinc.co.kr/w/man/12/hash/consistent
https://www.popit.kr/jump-consistent-hash/
'도서 > 게임 서버 프로그래밍 교과서' 카테고리의 다른 글
데이터 베이스의 수평 확장 (0) | 2019.06.16 |
---|---|
로직 처리의 분산 방식들 (0) | 2019.06.16 |
IOCP (0) | 2019.06.16 |
비트 스트림(bit stream) (0) | 2019.06.09 |
바이트 스와핑 함수 (0) | 2019.06.09 |