Foundry
안정 해시 설계
심화
핵심

뜨거운 키와 조회 쏠림

가상 노드가 고르게 하지 못하는 것

가상 노드는 담당 키 개수를 고르게 만듭니다. 그런데 부하는 키 개수가 아니라 조회 횟수로 옵니다.

개수는 고른데 부하는 쏠린다

담당 키 개수는 고른데 조회 횟수는 한 서버에 몰릴 수 있다 담당 키 개수는 고르다 25 25 24 26 가상 노드가 한 일 그런데 조회 횟수는 10 10 70 10 뜨거운 키 하나 쪼개지지 않는다 가상 노드를 늘려도 한 키는 한 서버가 맡는다

인기 상품 하나, 대문 배너, 공통 설정 같은 키는 다른 키보다 수백 배 자주 읽힙니다. 그 키 하나가 전체 조회의 10퍼센트를 차지하면 담당 서버 한 대가 초당 5만을 받습니다.

가상 노드를 늘려도 해결되지 않습니다. 한 키는 쪼개지지 않으므로 지점이 몇 개든 그 키는 한 지점에 걸리고 한 서버가 맡습니다.

값싼 순서로 본다

방법하는 일대가
클라이언트 로컬 캐시뜨거운 키를 각자 짧게 들고 있는다잠깐 낡은 값을 볼 수 있다
키를 여러 개로 나누기같은 값을 다른 이름 몇 개로 흩는다갱신할 곳이 그만큼 늘어난다
전용 서버로 빼기그 키만 다른 곳에서 처리예외 목록을 사람이 관리한다

로컬 캐시가 가장 값쌉니다. 뜨거운 키는 정의상 자주 읽히므로 아주 짧은 시간만 들고 있어도 대부분의 조회가 로컬에서 끝납니다. 1초만 들고 있어도 초당 5만 조회가 초당 몇 번의 원격 조회로 줄어듭니다.

대가는 그 1초 동안 낡은 값을 볼 수 있다는 것입니다. 얼마나 오래된 값까지 괜찮은지가 이 선택의 기준입니다.

키를 나누는 방법

값이 자주 바뀌어 로컬 캐시가 어려우면 이름을 나눕니다.

인기상품:123 대신
인기상품:123#0 부터 인기상품:123#9 까지 열 개
읽을 때 무작위로 하나를 고른다

열 개가 서로 다른 위치에 흩어지므로 부하가 여러 서버로 나뉩니다. 대가는 값을 바꿀 때 열 곳을 모두 고쳐야 하는 것이고, 고치는 중에는 사용자마다 다른 값을 볼 수 있습니다.

쏠림을 어떻게 아나

서버별 조회 수만 보면 어느 서버가 뜨거운지는 알지만 어느 키 때문인지는 모릅니다.

지표알 수 있는 것
서버별 조회 수쏠림이 있는지
키별 조회 수 상위 목록어느 키 때문인지

키별 집계를 모든 조회에 붙이면 그 집계가 새로운 부하가 됩니다. 표본만 남기거나 뜨거운 후보만 세는 방식으로 가볍게 유지합니다.

값 크기 쏠림은 다른 문제다

조회가 고르더라도 어떤 키의 값이 다른 키보다 훨씬 크면 메모리가 한쪽으로 기웁니다. 담당 키 개수도 고르고 조회도 고른데 메모리만 꽉 차는 상태입니다.

이때는 값 크기에 상한을 두는 편이 낫습니다. 큰 값 하나가 작은 값 수천 개를 밀어내면 적중률 전체가 내려갑니다.

면접에서 이렇게 나옵니다

Q.가상 노드를 썼는데도 한 서버만 부하가 높으면 무엇을 의심하시겠습니까

뜨거운 키입니다. 가상 노드는 담당 키 개수를 고르게 하지만 조회 횟수는 고르게 하지 못합니다.

인기 상품이나 대문 배너 같은 키는 다른 키보다 수백 배 자주 읽힙니다. 그 키 하나가 전체 조회의 10퍼센트면 담당 서버가 초당 5만을 받습니다.

한 키는 쪼개지지 않으므로 지점을 늘려도 해결되지 않습니다. 지점이 몇 개든 그 키는 한 지점에 걸립니다.

확인 방법은 서버별 조회 수와 키별 조회 수 상위 목록을 함께 보는 것입니다. 서버별만 보면 쏠림이 있는지는 알지만 어느 키 때문인지는 모릅니다.

흔한 실수: 지점 수를 늘려 해결하려는 것. 개수 편차와 조회 편차는 다른 문제이고, 지점을 늘리는 것은 앞의 문제에만 듣습니다.

Q.뜨거운 키를 어떻게 다루시겠습니까

클라이언트 로컬 캐시를 먼저 씁니다. 가장 값싸고 효과가 큽니다.

뜨거운 키는 정의상 자주 읽히므로 아주 짧게 들고 있어도 대부분의 조회가 로컬에서 끝납니다. 1초만 들고 있어도 초당 5만 조회가 초당 몇 번으로 줄어듭니다.

방법대가
로컬 캐시잠깐 낡은 값을 볼 수 있다
키를 여러 개로 나누기갱신할 곳이 그만큼 늘어난다
전용 서버로 빼기예외 목록을 사람이 관리한다

기준은 얼마나 오래된 값까지 괜찮은지입니다. 값이 자주 바뀌어 로컬 캐시가 어려우면 이름을 나눕니다.

흔한 실수: 로컬 캐시의 무효화를 완벽하게 만들려는 것. 뜨거운 키는 인스턴스 수천 곳에 퍼져 있어 지울 곳도 수천 군데입니다. 짧은 유지 시간으로 불일치가 남는 시간을 스스로 제한하는 편이 단순하고 확실합니다.

Q.키를 여러 개로 나누는 방법의 대가는 무엇인가요

값을 바꿀 때 나눈 개수만큼 모두 고쳐야 합니다.

인기상품:123#0 부터 #9 까지 열 개
읽을 때 무작위로 하나를 고른다
쓸 때는 열 곳을 모두 고친다

열 개가 서로 다른 위치에 흩어져 부하가 나뉘는 것이 얻는 것입니다. 그리고 고치는 중에는 사용자마다 다른 값을 볼 수 있습니다. 어떤 사용자는 새 값을, 어떤 사용자는 낡은 값을 봅니다.

메모리도 그만큼 더 씁니다. 같은 값을 열 벌 담기 때문입니다.

흔한 실수: 나누는 개수를 크게 잡는 것. 부하가 아주 큰 소수의 키에만 쓰는 기법이고, 개수는 그 키의 조회가 서버 한 대의 여유 안에 들어올 정도면 충분합니다. 필요 이상으로 나누면 갱신 비용만 늘어납니다.

Q.조회는 고른데 한 서버의 메모리만 꽉 차면 무엇을 보시겠습니까

값 크기의 쏠림입니다. 조회 쏠림과 다른 문제입니다.

담당 키 개수도 고르고 조회도 고른데, 어떤 키의 값이 다른 키보다 훨씬 크면 그 값을 맡은 서버의 메모리가 먼저 찹니다.

쏠림의 종류무엇으로 보나
개수 쏠림서버별 담당 키 수
조회 쏠림서버별 조회 수
크기 쏠림서버별 사용 메모리와 값 크기 분포

이때는 값 크기에 상한을 두는 편이 낫습니다. 큰 값 하나가 작은 값 수천 개를 밀어내면 적중률 전체가 내려갑니다.

흔한 실수: 세 가지 쏠림을 하나로 묶어 생각하는 것. 원인이 다르면 대응도 다릅니다. 지표를 세 개로 나눠 보지 않으면 가상 노드를 늘리는 잘못된 처방으로 가게 됩니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

읽었으면 문제로 확인해보세요

안정 해시 설계 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.