앞 단계에서 클라이언트가 직접 계산하기로 정했습니다. 그러면 링을 모든 클라이언트가 들고 있어야 하고, 그 링이 서로 같아야 합니다.
링이 다르면 무슨 일이 생기나
같은 키를 두 클라이언트가 찾는데 링이 다르면 서로 다른 서버로 갑니다.
| 성격 | 결과 |
|---|---|
| 캐시 | 미스가 늘고 같은 값이 두 곳에 생긴다. 견딜 수 있다 |
| 영구 저장소 | 같은 키의 최신 값이 어디인지 알 수 없다. 견딜 수 없다 |
이 요구사항이 캐시라서 전파 지연을 견딜 수 있습니다. 잠깐 어긋나면 미스가 조금 늘 뿐입니다. 저장소였다면 어긋난 동안 쓰기를 막거나 두 곳을 모두 확인해야 합니다.
목록을 어떻게 나눠 주나
| 방법 | 성질 |
|---|---|
| 한 곳에 두고 각자 지켜보기 | 단순하고 순서가 분명하다. 그곳이 죽으면 갱신이 멈춘다 |
| 서로 알려 주며 퍼뜨리기 | 중앙이 없다. 퍼지는 데 시간이 걸리고 상태가 잠시 갈린다 |
서버 100대 규모에서는 한 곳에 두는 편이 낫습니다. 목록이 작고 변경이 주당 3~4번 정도라 중앙 저장소 하나로 충분합니다. 그곳이 잠깐 죽어도 각자 마지막 목록으로 계속 동작하므로 조회는 멈추지 않습니다.
세대 번호를 붙인다
목록에 번호를 하나 붙여 올라갈 때마다 키웁니다. 요청에 그 번호를 실어 보내면 서버가 자기가 아는 번호와 다른 것을 알아챌 수 있습니다.
클라이언트가 세대 7 로 요청한다
서버는 세대 8 을 알고 있다
그 클라이언트가 낡은 링을 보고 있다고 알 수 있다
이 신호가 있으면 어긋남을 지표로 볼 수 있고, 오래 낡은 클라이언트를 찾아낼 수 있습니다. 번호가 없으면 어긋남은 미스 증가로만 나타나서 원인을 짚기 어렵습니다.
죽었다는 판단은 한 곳에서 한다
여러 곳이 각자 판단하면 링이 흔들립니다. 어떤 클라이언트는 그 서버를 뺀 링을, 어떤 클라이언트는 넣은 링을 보게 됩니다.
그리고 넣었다 뺐다를 반복하는 것이 가장 나쁩니다. 그 서버가 담당하는 구간의 키가 매번 이동하므로 미스가 계속 발생합니다. 그래서 판단에 여유를 둡니다.
| 장치 | 이유 |
|---|---|
| 여러 번 연속 실패해야 뺀다 | 순간적인 실패로 링을 흔들지 않는다 |
| 뺀 뒤 일정 시간은 다시 넣지 않는다 | 넣었다 뺐다 반복을 막는다 |
| 한 번에 뺄 수 있는 대수를 제한한다 | 판단이 잘못돼 여럿을 뺄 때를 막는다 |
새 서버는 조금씩 넣는다
새 서버를 지점 150개로 한 번에 넣으면 그 몫의 키가 즉시 미스가 됩니다. 지점 수를 조금씩 늘리면 미스가 시간에 걸쳐 흩어집니다.
처음에 15개 지점으로 넣는다
값이 채워지는 것을 보며 150개까지 올린다
원본 부하가 한 번에 튀는 것을 막는 방법이고, 캐시 클러스터에서 실제로 쓰입니다. 적중률 95퍼센트 유지가 요구사항이라면 이 절차가 설계의 일부입니다.