우리 회사는 랜딩 페이지를 만들고 배포하며 HTTP 캐시를 적극적으로 이용하고 있습니다. 캐시를 적절하게 이용한다면 웹 서비스와 관련된 데이터를 처리하는데 필요한 시간과 리소스를 줄임으로써 웹 서비스의 성능을 크게 향상시킬 수 있습니다.

하지만 캐시를 잘못 관리하였을 때, 기존에 있었던 캐시가 남아있어 예상치 못한 문제가 발생할 수 있고 필요 이상의 요청이 발생할 수 있습니다.

이번 포스트에서는 어떻게 사용하냐에 따라 득이 될 수도 독이 될 수도 있는 캐시를 적절하게 사용하는 방법에 대하여 공유하도록 하겠습니다.

Cache-Control

캐시 제어는 웹 서비스 캐시에 저장된 데이터의 주기를 관리하는 것입니다. 캐시 주기를 설정하여 얼마큼의 시간 동안 캐시를 저장할지 조절할 수 있습니다.

max-age

max-age=<seconds>를 사용하면 클라이언트 측의 캐시 유효기간을 설정할 수 있습니다. 한번 받아온 데이터는 유효기간이 지나기 전까진 서버에 요청하지 않고 메모리에서 캐시를 읽어와 사용합니다. 그로 인해 서버로부터 불필요한 네트워크 요청을 줄일 수 있고 속도 또한 향상됩니다.

하지만 max-age는 조심스럽게 사용해야 합니다. 만약 캐시 유효 기간을 길게 설정한다면 데이터가 변경되어 업데이트를 하였어도 클라이언트의 브라우저 캐시 유효 기간이 남아있어 변경된 데이터가 반영되지 않기 때문입니다. 저 또한 max-age를 길게 설정하여 위와 같은 상황을 겪은 적이 있습니다.

s-maxage

max-age가 클라이언트의 캐시 유효기간을 설정하는 옵션이라면 s-maxage는 프록시 서버의 캐시 유효기간을 설정하는 옵션입니다. 여기서 말하는 프록시 서버는 대표적으로 CDN이 있습니다.

예를 들어 max-age=0, s-maxage=81500으로 설정했다면 브라우저는 데이터가 필요할 때마다 서버에 요청을 보내고, CDN은 81500초 동안 캐시를 가지고 있게 됩니다.

HTTP 캐시 무효화

위의 예시를 다시 살펴보면 max-age=0, s-maxage=81500이라고 설정되어 있습니다. 프록시 서버의 유효기간이 길게 설정되어 있기 때문에 추가적인 업데이트를 할 때 기존에 있던 캐시를 삭제해 주는 작업이 필요합니다. 그 작업을 HTTP 캐시 무효화 또는 일반적으로 CDN Invalidation이라고 부릅니다.

max-age를 길게 설정하였다면 이미 클라이언트의 브라우저에 위치해 있기 때문에 시간이 경과할 때까지 따로 캐시를 삭제할 방법이 없습니다. 이렇든 한번 저장된 max-age는 지우기 어렵기 때문에 신중히 설정해야 합니다.

마무리

각각의 서비스마다 캐시 전략이 달라야 한다고 생각합니다. 트래픽 패턴과 제공하는 데이터의 타입 그리고 앱의 특성을 고려하여 적절하게 캐시를 설정한다면 효율적으로 서비스를 제공할 수 있을 것입니다.

개인적인 생각으로는 한번 설정하면 시간이 만료될 때까지 삭제하기 어려운 max-age보다, s-maxage를 사용하여 캐시 관리를 하고 업데이트가 필요할 때 CDN Invalidation을 하여 업데이트해주는 방식이 좋다고 생각합니다.

이번 포스트를 통해 HTTP 캐시 설정에 대하여 고민하신 분들께 조금이나마 도움이 되기를 바랍니다.