14강
캐시는 왜 필요한가
같은 질문에 같은 답을 100만 번 다시 계산하고 있다
먼저 보면 좋은 강의: 웹 요청의 해부, 지연 시간과 처리량
단계별로 보기
스페이스바로 재생/정지, 좌우 화살표로 단계 이동, R로 처음으로 돌아갑니다.
대기 중1 / 4 단계 — 데이터베이스가 무너진다
초당 150건이 데이터베이스까지 그대로 갑니다. 데이터베이스는 초당 66건이 한계입니다. 대기열이 차고, 요청이 버려집니다. 그런데 이 150건을 들여다보면 절반 이상이 똑같은 상위 몇 개 항목을 묻고 있습니다.
이 강의를 마치면
- 데이터베이스가 시스템에서 가장 늘리기 어려운 부품인 이유를 설명한다.
- 실제 요청이 골고루 흩어지지 않고 소수의 인기 항목에 몰린다는 사실을 관찰한다.
- 인기 항목의 답을 기억해 두면 원본 부하가 몇 분의 일로 줄어드는지 계산한다.
- 캐시가 '빠르게 만드는 장치'가 아니라 '원본을 지키는 장치'임을 설명한다.
데이터베이스는 왜 늘리기 어려운가
앞에서 우리는 서버가 모자라면 서버를 늘렸습니다. 두 대, 네 대, 여섯 대. 간단했습니다. 서버는 기억할 게 없기 때문입니다.
데이터베이스는 다릅니다. 데이터베이스는 진실을 보관하는 곳입니다. 같은 데이터베이스를 두 대로 복사해 두면 두 개의 진실이 생깁니다. 한쪽에서 재고를 3개로 고치고 다른 쪽에서 5개로 고치면, 어느 쪽이 맞습니까?
그래서 데이터베이스를 늘리는 일은 서버를 늘리는 일과 난이도가 완전히 다릅니다. 뒤에 나오는 데이터 단원 전체가 이 문제를 다룹니다.
지금 알아야 할 것은 하나입니다.
데이터베이스는 시스템에서 가장 비싸고, 가장 느리고, 가장 늘리기 어려운 부품이다.
그러니 전략은 분명해집니다. 데이터베이스에 일을 덜 시켜야 합니다.
질문은 골고루 오지 않는다
여기가 이 강의의 핵심입니다.
상품이 10만 개인 쇼핑몰을 생각해 봅시다. 오늘 들어온 조회 100만 건이 10만 개 상품에 골고루 퍼졌을까요? 절대 아닙니다.
상위 100개 상품이 조회의 약 50%
상위 1,000개 상품이 조회의 약 80%
나머지 99,000개 상품이 조회의 약 20%메인 화면에 걸린 상품, 방금 광고한 상품, 어제 뉴스에 나온 상품에 사람들이 몰립니다. 이건 이상한 현상이 아니라 거의 모든 서비스에서 관찰되는 기본 성질입니다.
그런데 데이터베이스는 어떻게 하고 있습니까? 1등 상품에 대한 똑같은 질문에 똑같은 답을 50만 번 다시 만들고 있습니다. 매번 디스크를 뒤지고, 조인하고, 정렬해서 말입니다.
그래서 적어둔다
캐시는 이 낭비를 없앱니다.
방금 만든 답을 옆에 적어둔다. 같은 질문이 또 오면 적어둔 걸 준다.
가게 주인의 메모지와 같습니다. "오늘 배송비 얼마예요?"를 하루에 200번 듣는다면, 주인은 200번 창고에 가서 확인하지 않습니다. 첫 번째에 확인하고 메모지에 적어서 카운터에 붙여 둡니다. 나머지 199번은 메모지를 봅니다.
숫자로 보면
들어오는 조회 초당 150건
캐시 적중률 95%
─────────────────────────────────
캐시가 처리 초당 142.5건
데이터베이스까지 가는 것 초당 7.5건데이터베이스가 감당할 일이 20분의 1이 되었습니다. 초당 66건이 한계인 데이터베이스가 초당 150건의 트래픽을 여유롭게 받아냅니다.
데이터베이스를 하나도 건드리지 않고 말입니다.
왜 이렇게 잘 먹히는가
두 가지가 겹치기 때문입니다.
- 질문이 소수에 몰린다. 적어둘 항목이 몇 개 안 됩니다. 상위 1,000개만
적어둬도 80%가 해결됩니다.
- 메모리는 디스크보다 압도적으로 빠르다. 캐시 조회는 1밀리초 안쪽,
데이터베이스 조회는 그 수십 배입니다.
그래서 캐시는 작은 메모리로 큰 효과를 냅니다. 10만 개 상품을 다 적어둘 필요가 없다는 점이 결정적입니다.
오해 하나를 정정하자
캐시를 "빠르게 만드는 장치"로만 이해하면 절반만 아는 것입니다. 더 중요한 건 이쪽입니다.
캐시는 데이터베이스가 죽지 않게 지켜 주는 장치다.
앞의 계산에서 캐시가 없으면 데이터베이스는 그냥 느려지는 게 아니라 무너집니다. 초당 150건이 들어오는데 66건만 처리하면 줄이 무한히 자라고 요청이 버려집니다. 3강에서 본 그대로입니다.
그래서 캐시가 잠깐이라도 비면(장애, 재시작, 배포) 그 순간 150건이 통째로 데이터베이스로 쏟아집니다. 캐시가 죽으면 데이터베이스가 같이 죽습니다. 이 위험은 뒤의 강의에서 다룹니다.
그러니 공짜는 아니다
적어둔 답은 과거의 답입니다. 원본이 바뀌어도 메모지는 그대로입니다. 이 문제가 캐싱 단원의 나머지 전부입니다. 하지만 지금은 효과부터 보겠습니다.
직접 해보세요
아래 과제에서 데이터베이스는 초당 66건이 한계인데 초당 150건이 들어옵니다. 데이터베이스를 건드리지 말고, 앞에 캐시를 하나 두어 살려 보세요.
이 강의가 단순화한 것
교육용 모형은 언제나 무언가를 생략합니다. 무엇을 생략했는지 아는 것도 학습의 일부입니다.
전제한 것
- 조회 대상은 100개 항목이고 인기도는 지프(Zipf) 분포를 따른다고 가정한다. 실제 서비스의 항목 수는 훨씬 많지만 쏠림의 성질은 같다.
- 캐시의 유효 시간이 실행 시간보다 길어서, 한 번 적어둔 답은 이 시뮬레이션 동안 만료되지 않는다.
- 이 과제의 트래픽은 전부 읽기다. 쓰기가 섞이면 이야기가 달라지며, 그건 뒤의 강의에서 다룬다.
- 캐시 자체의 용량과 장애는 여기서 다루지 않는다. 캐시는 죽지 않고 충분히 크다고 본다.
다루지 않은 것
- 캐시 용량 초과 시의 축출 정책(LRU/LFU/FIFO)
- 유효 시간 만료와 무효화
- 캐시가 비는 순간의 쏠림(cache stampede)
- 데이터베이스 자체의 버퍼 풀 캐시
더 읽을거리: Scaling Memcache at Facebook
이제 직접 만들어 보세요
읽어서 아는 것과 만들어서 아는 것은 다릅니다. 컴포넌트를 배치하고 트래픽을 흘려서 실제로 동작하는지 확인해 보세요.
이 강의에 물어보기
하루 5번이 강의 본문만 근거로 답합니다. 강의에 없는 내용은 지어내지 않습니다.