웹 인프라

콘텐츠 전송 네트워크(CDN), 세계 곳곳에 흩어 둔 사본

가까운 서버에 사본을 두면 왜 빨라질까요? 개인화된 응답을 나누는 기준과, 파일이 바뀌어도 캐시를 오래 쓸 수 있는 이유를 살펴봐요.

이 글의 목차기다림이 문제였던 시절4
  1. 기다림이 문제였던 시절
  2. 무엇을 같은 응답으로 볼 것인가
  3. 낡은 사본을 다루는 두 가지 방법
  4. 저는 이 균형을 어떻게 잡았나

전국에서 주문이 들어오는 물건을 창고 한 곳에서만 보낸다고 해 볼게요. 창고가 아무리 잘 돌아가도 먼 곳의 손님은 오래 기다려요. 포장이 느려서가 아니라 물건이 지나야 할 길이 길기 때문이에요.

웹에서도 같아요. 서버가 아무리 빨라도 지구 반대편에서 접속하면 신호가 오가는 시간이 남아요. 이 왕복 시간을 지연(latency)이라고 부르는데, 서버를 좋은 것으로 바꿔도 줄지 않아요. 계산 시간이 아니라 거리에서 오는 시간이기 때문이에요. 게다가 연결을 맺고 암호화를 협상하는 과정에서 왕복이 여러 번 일어나므로, 한 번의 왕복 시간은 실제 체감에서 여러 배로 곱해져요.

이 거리를 줄이는 방법이 CDN(Content Delivery Network), 콘텐츠 전송 네트워크예요. 여러 지역의 서버에 사본을 두고 요청을 알맞은 곳으로 보내요. 방문자와 가까운 쪽에서 응답하는 지점을 엣지(edge)라고 불러요. 여기서 가깝다는 것은 지도상의 거리만 뜻하지 않아요. 네트워크 경로와 서버 상태도 영향을 줘요. 그리고 가까이에 두는 순간, 어떤 응답을 함께 써도 되는지 정해야 해요.

기다림이 문제였던 시절

1990년대 후반의 웹은 자주 멈췄어요. 인기 있는 사이트에 사람이 몰리면 화면이 좀처럼 뜨지 않았고, 서버를 늘려도 해결되지 않았어요. 요청이 한 지점으로 모이면 그 앞의 길이 먼저 막히기 때문이에요.

MIT의 수학자 Tom Leighton과 대학원생 Danny Lewin은 이것을 계산의 문제가 아니라 배치의 문제로 봤어요. 같은 내용을 여러 곳에 복제해 두고 요청을 알맞은 곳으로 나누는 방법을 응용수학과 알고리즘으로 풀었고, 1998년 Akamai를 세운 뒤 1999년 4월 당시 가장 붐비던 포털을 초기 고객으로 상용 서비스를 시작했어요. 미국 발명가 명예의 전당은 2017년 두 사람을 헌액하면서, 이들이 사람들 사이에서 월드 와이드 웨이트라고 불리던 기다림을 풀어냈다고 적었어요.

무엇을 같은 응답으로 볼 것인가

사본을 두는 순간 새 질문이 생겨요. 엣지는 어떤 요청을 이미 가진 응답으로 처리해도 되는지 판단해야 하는데, 그 판단의 기준이 캐시 키예요. 기본적으로는 주소가 같으면 같은 응답으로 봐요. 여기서 사고가 나요.

같은 주소라도 로그인한 사람에 따라 이름과 주문 내역이 달라질 수 있어요. HTTP 캐시 규격은 여러 사람이 쓰는 공유 캐시와 한 사람의 사설 캐시를 구별해요. 개인 응답에 붙이는 private는 공유 캐시에 저장하지 말라는 뜻이고, no-store는 응답을 저장하지 말라는 더 강한 지시예요. 개인화된 내용을 공유해도 되는 응답으로 잘못 설정하면 다른 사람에게 보일 수 있어요. 캐시 키에 로그인 정보를 무작정 더하는 것보다, 이 응답을 공유할 수 있는지부터 정해야 해요.

같은 주소가 같은 사람의 화면은 아니에요

빈 캐시에서 A와 B가 차례로 자기 화면을 요청한 두 설정을 비교해 보세요.

방문자 A가 받은 화면

A의 화면

원본에서 받음

방문자 B가 받은 화면

A의 화면

잘못 공유한 사본

사람마다 다른 화면을 같은 주소라는 이유로 공유하면 다른 사람의 화면이 갈 수 있어요. private는 공유 캐시에 저장하지 말라는 지시예요.

개인 응답을 일부러 잘못 공유한 가상의 비교예요. 각 설정은 빈 캐시에서 시작하며 특정 CDN의 기본 동작을 뜻하지 않아요.

낡은 사본을 다루는 두 가지 방법

원본이 바뀌었는데 엣지의 사본이 예전 것이면 방문자는 고친 내용을 보지 못해요. 해결책은 두 갈래예요. 하나는 바뀔 때마다 엣지에 지우라고 알리는 무효화이고, 다른 하나는 애초에 겹치지 않는 이름을 쓰는 것이에요.

파일 이름 변화에 따른 캐시 갱신과 수명 내용과 함께 이름이 바뀌는 자산은 이전 사본과 참조가 갈라져 오래 보관할 수 있고, 고정 이름의 입구 문서는 재검증이 필요하다. 개념 도해 파일 이름 변화에 따른 캐시 갱신과 수명 변경 뒤 캐시 갱신 경로 지문 자산 ① 내용 변경 ② 지문 B 이름 ③ 새 주소 요청 지문 A 미참조 입구 문서 ① 내용 변경 ② 이름 그대로 ③ 재검증 새 내용 수신 이름 조건별 보관 기간 장기 보관 경계 이름 고정 재검증 내용 지문 이름 이전 사본과 참조 분리 짧게 길게 · 캐시 보관 기간 내용과 함께 이름이 바뀌는 자산은 이전 사본과 참조가 갈라져 오래 보관할 수 있고, 고정 이름의 입구 문서는 재검증이 필요하다. SOSHIN · DEV NOTES
이름이 내용과 함께 바뀌는 파일은 오래 두어도 안전하고, 입구가 되는 문서만 매번 확인하면 돼요.

이미지와 스크립트에는 이름을 바꾸는 방법이 잘 맞아요. 파일 내용을 요약한 문자열을 이름에 넣으면 내용이 바뀔 때 주소도 바뀌어요. 새 화면은 새 주소를 요청하니 예전 캐시와 부딪히지 않죠. 다만 이미 열려 있는 화면은 옛 파일을 요청할 수 있어요. 그래서 새 파일을 먼저 올리고 이전 자산도 필요한 동안 남겨 두는 것이 중요해요. 파일명에 지문을 붙였다고 예전 파일을 바로 지워도 되는 것은 아니에요.

남는 것은 이름을 바꿀 수 없는 입구 문서예요. 방문자가 처음 받는 화면의 주소는 고정돼야 하므로 오래 보관할 수 없어요. 대신 이 문서 하나만 매번 확인하게 두면 그 안에서 참조하는 무거운 파일은 전부 길게 둘 수 있어요.

파일의 성격보관 방식잘못 정하면
이름에 지문이 붙은 자산아주 길게 보관짧게 두면 매번 같은 파일을 다시 받는다
주소가 고정된 입구 문서매번 확인길게 두면 새 배포가 반영되지 않는다
사람마다 다른 응답공유 캐시에 두지 않음남의 화면이 다른 사람에게 전달된다

저는 이 균형을 어떻게 잡았나

이 블로그는 글과 그림, 글꼴이 대부분이고 사람마다 달라지는 화면이 없어요. 세 번째 줄의 위험이 구조적으로 없는 조건이라 사본을 나눠 두기에 유리했어요. 정하기 어려웠던 것은 보관 기간이었어요.

처음에는 전부 짧게 두는 편이 안전하다고 생각했어요. 그런데 그렇게 하면 방문자는 매번 같은 파일을 다시 받고, 안전해 보이는 선택이 모두를 조금씩 기다리게 해요. 지문이 붙은 자산은 길게 두고 입구 문서와 검색 색인의 시작점만 매번 확인하게 나눈 뒤에야 양쪽이 정리됐어요.

캐시를 다루면서 남은 관점은 하나예요. 오래 보관하는 것 자체는 위험하지 않아요. 위험한 것은 바뀐 것과 바뀌지 않은 것을 같은 이름으로 부르는 일이에요. 이름을 제대로 나누면 보관 기간은 오히려 마음 놓고 늘릴 수 있어요.

소신을 상징하는 까마귀 목판화 일러스트
작성자소신 · Soshin

웹과 서버를 만들고, 개발하며 배운 것들을 글로 남깁니다.

좌우로 움직여 보세요