CDN 과 엣지 전달
사용자에 가까운 서버에 콘텐츠를 복사해 두고 그곳에서 내주는 방식
왜 필요한가
빛의 속도는 정해져 있습니다. 서울에서 미국 동부까지 왕복이 물리적으로 약 200밀리초입니다.
| 사용자 위치 | 서울 원본까지 왕복 | 근처 엣지까지 왕복 |
|---|
| 서울 | 10밀리초 | 10밀리초 |
| 도쿄 | 40밀리초 | 10밀리초 |
| 미국 동부 | 200밀리초 | 15밀리초 |
| 브라질 | 300밀리초 | 20밀리초 |
서버를 아무리 빠르게 만들어도 이 왕복 시간은 줄지 않습니다. 그래서 거리를 줄이는 것이 유일한 답입니다.
무엇을 얻는가
| 효과 | 내용 |
|---|
| 지연 감소 | 물리적 거리가 짧아진다 |
| 원본 부하 감소 | 엣지에서 처리되어 원본까지 오지 않는다 |
| 대역폭 비용 | 원본에서 나가는 트래픽이 줄어든다 |
| 가용성 | 원본이 잠시 죽어도 캐시된 것은 나간다 |
| 공격 완화 | 대량 트래픽을 엣지가 흡수한다 |
무엇이 아닌가
| 오해 | 실제 |
|---|
| 서버 처리가 빨라진다 | 원본에서 계산하는 시간은 그대로다 |
| 모든 응답이 빨라진다 | 사용자마다 다른 응답은 캐시되지 않는다 |
| DB 조회가 줄어든다 | 캐시 적중한 요청만 줄어든다 |
| 코드가 단순해진다 | 무효화와 캐시 헤더 관리가 늘어난다 |
무엇을 올릴지
| 대상 | 캐시 | 이유 |
|---|
| 이미지, CSS, JS | 길게 | 바뀌면 파일명이 바뀐다 |
| 공용 API 응답 | 짧게 | 모두에게 같은 응답이면 가능하다 |
| 개인화 응답 | 하지 않는다 | 남의 응답이 나갈 수 있다 |
| 로그인 후 페이지 | 하지 않는다 | 같은 이유 |
세 번째가 실제 사고가 나는 자리입니다. 공유 캐시는 사용자를 구분하지 않아서, 한 사람의 응답이 뒤이어 온 다른 사람에게 나갑니다.
무효화가 어려운 이유
엣지가 전 세계에 수백 곳 있고, 지우라는 명령이 모든 곳에 닿기까지 시간이 걸립니다.
| 방법 | 내용 |
|---|
| 파일명 버전 | 내용이 바뀌면 이름이 바뀐다. 무효화가 필요 없다 |
| 퍼지 API | 특정 경로를 지운다. 전파에 수십 초 |
| 짧은 만료 | 애초에 오래 두지 않는다 |
| 재검증 | 만료 후 원본에 "바뀌었나" 묻고 안 바뀌면 그대로 쓴다 |
첫 번째가 가장 확실합니다. 빌드할 때 파일 내용의 해시를 이름에 넣으면, 새 배포는 새 주소가 되어 캐시가 자연히 갈립니다. 그래서 정적 자원은 만료를 1년으로 걸어도 안전합니다.
Q.CDN 의 장점이 아닌 것은 무엇인가요?
CDN 은 거리를 줄이는 장치입니다. 서버가 하는 일을 빠르게 만들지는 않습니다.
| 장점인 것 | 장점이 아닌 것 |
|---|
| 사용자까지의 지연 감소 | 원본의 처리 시간 단축 |
| 원본 부하와 대역폭 감소 | DB 쿼리 자체의 개선 |
| 대량 트래픽 흡수 | 개인화 응답의 가속 |
| 캐시된 것은 원본 장애에도 나간다 | 쓰기 요청의 가속 |
특히 마지막이 자주 오해됩니다. POST 나 PUT 은 캐시할 수 없어 그대로 원본까지 갑니다. 읽기 위주 서비스에서 효과가 크고, 쓰기 위주면 이득이 거의 없습니다.
두 번째 열의 세 번째도 중요합니다. 로그인 사용자마다 다른 응답은 캐시하면 안 되고, 그러면 CDN 을 거쳐도 매번 원본까지 갑니다. 이때 CDN 은 지연을 줄이지 못하고 오히려 한 단계 더 거칩니다.
흔한 실수: CDN 을 붙였는데 응답이 안 빨라졌다고 원인을 CDN 에서 찾는 것. 캐시 적중률을 먼저 봐야 합니다. 적중률이 낮으면 캐시할 수 없는 응답을 보내고 있는 것입니다.
Q.한국 서버인데 미국 사용자가 느립니다. 무엇을 하나요?
원인이 물리적 거리라면 서버 성능을 손대도 달라지지 않습니다. 거리를 줄이거나 왕복 횟수를 줄여야 합니다.
| 순서 | 대응 | 효과 |
|---|
| 1 | 정적 자원을 CDN 으로 | 이미지와 스크립트가 근처에서 온다 |
| 2 | 연결 수립 비용 줄이기 | TLS 세션 재사용, 연결 유지 |
| 3 | 왕복 횟수 줄이기 | 순차 호출을 병렬로, 요청 수를 줄인다 |
| 4 | 공용 API 응답도 엣지 캐시 | 짧은 만료라도 효과가 크다 |
| 5 | 엣지에서 계산 | 간단한 처리를 엣지 함수로 옮긴다 |
| 6 | 지역 서버 배치 | 그 지역에 애플리케이션과 읽기 복제본을 둔다 |
2번과 3번이 값싸고 효과가 큽니다. 왕복이 200밀리초라면 순차 호출 5번은 그것만으로 1초입니다. 병렬로 바꾸면 200밀리초가 됩니다.
6번은 비용이 크고 데이터 정합성 문제가 따라옵니다. 쓰기를 어디로 보낼지, 복제 지연을 어떻게 다룰지 정해야 합니다.
흔한 실수: 서버 사양을 올려 해결하려는 것. 서버가 10밀리초에 응답하고 왕복이 200밀리초라면, 서버를 두 배 빠르게 해도 전체는 205밀리초에서 200밀리초가 됩니다.
Q.CDN 캐시를 어떻게 무효화하나요?
| 방법 | 전파 | 적합한 곳 |
|---|
| 파일명에 버전 넣기 | 즉시. 주소가 다르니 무효화가 필요 없다 | 정적 자원 |
| 퍼지 API 로 경로 지정 | 수십 초 | 개별 페이지 수정 |
| 태그 기반 퍼지 | 수십 초 | 관련 페이지 묶음 |
| 짧은 만료 | 만료 시간만큼 | 자주 바뀌는 공용 응답 |
| 재검증 | 만료 시점에 원본에 확인 | 바뀌는 빈도가 낮을 때 대역폭 절약 |
첫 번째를 기본으로 삼습니다. 빌드 결과에 내용 해시를 붙이면 새 배포가 새 주소가 되므로, 만료를 1년으로 걸어도 옛 파일이 남을 걱정이 없습니다.
HTML 은 이 방법을 쓸 수 없습니다. 주소가 고정이어야 하니까요. 그래서 HTML 은 짧게 캐시하거나 아예 캐시하지 않고, 그 안의 자원 주소만 바꿉니다.
| 주의 | 내용 |
|---|
| 전파 지연 | 퍼지 후에도 몇십 초는 옛 것이 나갈 수 있다 |
| 브라우저 캐시 | CDN 을 지워도 사용자 기기의 것은 안 지워진다 |
| 대량 퍼지 | 한꺼번에 지우면 원본으로 요청이 몰린다 |
흔한 실수: 정적 자원에 짧은 만료를 걸어 무효화 문제를 피하려는 것. 매번 다시 받아 CDN 을 둔 효과가 사라집니다. 파일명을 바꾸고 만료는 길게 가는 것이 맞습니다.
Q.개인화된 응답을 CDN 에 올리면 어떤 일이 벌어지나요?
먼저 요청한 사람의 응답이 뒤이어 온 사람에게 나갑니다. 공유 캐시는 사용자를 구분하지 않습니다.
| 순서 | 벌어지는 일 |
|---|
| 1 | A 가 /mypage 를 요청한다. 엣지에 A 의 응답이 캐시된다 |
| 2 | B 가 같은 주소를 요청한다 |
| 3 | 엣지가 캐시 적중으로 판단해 A 의 응답을 준다 |
| 4 | B 가 A 의 이름과 주문 내역을 본다 |
실제로 여러 서비스에서 발생한 사고 유형입니다. 개발 환경에서는 캐시가 없거나 사용자가 한 명이라 드러나지 않습니다.
| 막는 방법 | 내용 |
|---|
| 캐시 금지 헤더 | 개인화 응답에 private 와 no-store 를 명시한다 |
| 경로 분리 | 공용과 개인화를 다른 경로로 나눈다 |
| 키에 사용자 포함 | 꼭 캐시해야 하면 캐시 키에 사용자 구분을 넣는다 |
| 기본을 금지로 | 캐시할 것만 허용하는 방향으로 설정한다 |
마지막이 안전합니다. 기본이 캐시 허용이면 새로 만든 개인화 엔드포인트가 그대로 노출됩니다.
흔한 실수: 쿠키가 있으면 캐시가 안 될 것이라고 가정하는 것. CDN 설정에 따라 쿠키를 무시하고 캐시하는 경우가 있어서, 헤더로 명시해야 합니다.
먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.
읽었으면 문제로 확인해보세요
네트워크 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.