-
NGINX 4: 콘텐츠 캐싱하기DevOps 2023. 3. 15. 21:33반응형
이번 장은 Nginx를 이용해서 콘텐츠를 캐싱하는 방법과 다양한 옵션에 대해 알아보겠습니다.
콘텐츠에 대한 요청이 있을 때 미리 캐시 된 콘텐츠를 제공함으로써 서버의 부하를 줄이고 사용자에게 빠른 응답을 제공할 수 있습니다. 사용자에게 더 나은 경험을 제공하기 위해서 콘텐츠가 사용자 가까이에서 제공돼야 합니다. 이를 위해 사용자 가까이에 있는 서버에 콘텐츠를 캐싱하는 전략을 사용할 수 있는데 이를 CDN(Contents Delivery Network)라고 합니다. Nginx를 이용하면 Nginx 서버가 배치된 모든 곳에 콘텐츠를 캐시 할 수 있어 효과적으로 자신만의 CDN을 만들 수 있습니다.
1. 캐시 영역
proxy_cache_path 지시자를 이용해서 공유 메모리 캐시 영역과 콘텐츠 위치를 지정할 수 있습니다.
proxy_cache_path /var/nginx/cache keys_zone=CACHE:60m levels=1:2 inactive=3h max_size=20g; proxy_cache CACHE;
- proxy_cache_path 지시자는 캐시 응답을 저장하기 위해 /var/nginx/cache 디렉터리를 생성합니다.
- keys_zone로 메모리에 CACHE라는 공유 메모리 영역을 60MB 크기로 생성합니다.
공유 메모리 영역은 활성화된 캐시 키와 응답에 대한 메타데이터 정보를 저장합니다. - levels는 캐시 파일을 저장할 디렉터리 구조를 어떻게 생성할지 정의합니다.
서브 디렉터리의 이름의 길이를 콜론으로 구분해 지정하며 최대 3단계의 서브디렉터리를 생성할 수 있습니다.
해싱된 캐시 키를 디렉터리 경로로 사용합니다. (ex. /var/nginx/cache/c{1글자}/29{2글자}/b7f54...29c{해시 키}) - inactive는 캐시 후 요청이 없는 콘텐츠를 얼마나 저장할지 기간을 지정합니다.
- max_size는 캐시 영역의 크기가 20GB를 넘지 않도록 설정합니다.
- proxy_cache 지시자는 어떤 캐시 영역을 사용할지 지정합니다.
- proxy_cache_path 지시자는 http 컨텍스트에서만 캐시 영역에 대해 정의할 수 있고, proxy_cache 지시자는 정의된 캐시 영역을 http, server, location 컨텍스트에서 활용할 수 있습니다.
2. 캐시 락
proxy_cache_lock 지시자는 동일한 리소스에 대한 요청이 여러 개 들어오면 한 번에 하나의 요청을 통해서만 캐시가 만들어지도록 하며, 캐시가 만들어지는 동안 수신된 요청은 가장 먼저 도착한 요청으로 캐시가 생성될 때까지 처리되지 않고 기다립니다.
proxy_cache_lock on; proxy_cache_lock_age 10s; proxy_cache_lock_timeout 3s;
- proxy_cache_lock 지시자를 on으로 설정하면 생성 중인 캐시에 대해 동일한 요청이 들어와도 Nginx가 요청을 처리하지 않고 캐시 생성이 완료될 때 까지 대기합니다.
- 캐시는 proxy_cache_lock_age 지시자에 지정된 시간(default 5초) 내에 생성돼야 하며 시간이 초과되면 대기중인 요청을 업스트림 서버로 전달하여 응답 결과 캐시를 다시 시도합니다.
- proxy_cache_lock_age와 다르게 proxy_cache_lock_timeout 지시자는 대기중인 요청을 업스트림으로 보내서 응답 결과를 가져오지만 캐시는 생성하지 않습니다. (첫 요청이 생성하고 있는 캐시 시도를 그대로 유지)
3. 해시 키 값 캐시
proxy_cache_key 지시자와 변수를 이용해서 다양한 해시 키를 만들어 응답 결과에 대해 유동적으로 캐시할 수 있습니다.
proxy_cache_key "$host$request_uri $cookie_user"
- Nginx가 요청된 응답 결과를 캐시로 저장할 때 호스트명, URI, 쿠키 값으로 사용자마다 서로 다른 해시를 생성해 캐시 키로 사용하도록 합니다. 사용자 마다 다른 동적인 콘텐츠를 생성하고 각 사용자에게 전달할 때 사용합니다.
- proxy_cache_key 지시자의 default 값은 "$scheme$proxy_host$request_uri"이며, $scheme은 http나 https 값을 가지고 $proxy_host는 요청을 보낼 업스트림 호스트를 갖습니다. $request_uri는 요청의 경로를 나타냅니다.
셋을 모두 합치면 Nginx가 요청 받은 URL을 나타내게 됩니다. - 해당 지시자를 통해서 우리는 응답 결과 콘텐츠의 성격에 따라서 다양한 조합으로 키를 생성할 수 있습니다.
4. 캐시 우회
proxy_cache_bypass 지시자를 이용해서 지정한 location에 대해 캐시를 우회할 수 있다.
proxy_cache_bypass $http_cache_bypass;
- 이 설정은 cache-bypass라는 HTTP 요청 헤더값이 0이 아닐 때 Nginx가 캐시를 우회하도록 합니다.
- 특정 응답 값을 트러블 슈팅이나 디버깅 등의 목적으로 캐시하지 않도록 지정할 때 사용합니다.
5. 캐시 성능
Cache-Control 헤더를 이용해서 사용자 환경에 콘텐츠를 캐시합니다.
location ~*\.(css|ks)$ { expires 1y; add_header Cache-Control "public"; }
- location 블록은 사용자가 CSS와 Javascript 파일을 캐시하도록 명시합니다.
- expires 지시자는 사용자 환경에 캐시된 콘텐츠가 1년 간 유효하도록 지정합니다.
- add_header 지시자는 HTTP 응답에 Cache-Control 헤더를 추가하고 public으로 지정해 사용자에게 콘텐츠가 전달되는 중간에 위치한 어떤 캐시 서버라도 리소스를 캐시할 수 있도록 합니다.
public은 다른 사용자의 요청이 콘텐츠가 저장된 캐시 서버를 지날 경우 Nginx에 요청이 전달되지 않습니다. - 헤더값을 private으로 지정하면 실제 사용자 환경에만 리소스를 캐시합니다.
private은 사용자 환경에 콘텐츠가 캐싱되기 때문에 동일한 콘텐츠에 대해서 모든 사용자가 Nginx에 최소 한 번은 요청해야 합니다.
6. 캐시 퍼지 (엔젠엑스 플러스)
proxy_cache_purge 지시자를 이용해서 캐시된 콘텐츠를 무효화할 수 있습니다.
map $request_method $purge_method { PURGE 1; default 0; } server { location / { proxy_cache_purge $purge_method; # proxy_cache_path purger=on # 와일드카드 퍼지 사용 설정 } }
- HTTP 요청 메서드가 PURGE이면 요청된 리소스에 대한 캐시를 무효화합니다.
다음은 main.js 파일을 무효화하는 curl 명령의 예입니다.
$ curl -XPURGE localhost/main.js- proxy_cache_purge 지시자는 0이 아닌 값(HTTP method가 PURGE이면 1 할당)이 할당되면 조건에 맞는 요청의 캐시를 무효화합니다.
- 실제로는 geo_ip 모듈이나 사용자 인증 방법을 함께 사용해서 아무나 캐시를 무효화할 수 없도록 설정해야 합니다.
- 또한 Nginx는 proxy_cache_path 지시자에 purger=on 인수 전달을 통해 와일드카드(*)를 사용하여 URI 접두어가 같은 캐시를 모두 무효화할 수 있습니다.
7. 캐시 분할
slice 지시자와 내장 변수를 사용해서 용량이 큰 응답 결과를 작은 조각으로 나누어 캐시할 수 있습니다.
proxy_cache_path /tmp/mycache keys=zone=mycache:10m; server { proxy_cache mycache; slice 1m; proxy_cache_key $host$uri$is_args$args$slice_range; proxy_set_header Range $slice_range; proxy_http_version 1.1; proxy_cache_valid 200 206 1h; location / { proxy_pass http://origin:80; } }
- slice 지시자를 사용하면 Nginx가 업스트림 서버의 응답을 1MB 크기 파일 조각으로 나눕니다.
- 나눠진 파일들은 proxy_cache_key 지시자에 지정된 규칙에 따라 저장됩니다.
- proxy_set_header 지시자를 사용해 origin server로 요청을 보낼 때 Range 헤더를 추가하고 헤더값으로 $slice_range 변수값을 쓰도록 지정합니다. origin server는 Range 헤더에 지정한 데이터를 응답하고 Nginx는 1MB에 대한 응답 조각을 캐시합니다.
ex) Range: {bytes = 5001 - 10000} = $slice_range - Range 기능은 HTTP/1.1 버전부터 지원하기 때문에 proxy_http_version 지시자를 통해 1.1 버전을 명시합니다.
- 캐시 분할 모듈은 변경되지 않고 용량이 큰 파일에만 적용해야 합니다.
반응형'DevOps' 카테고리의 다른 글
NGINX 6: 인증 (0) 2023.03.19 NGINX 5: 프로그래머빌리티 & 자동화 (0) 2023.03.18 NGINX 3: 트래픽 관리하기 (0) 2023.03.12 NGINX 2: 고성능으로 부하 분산하기 (2) 2023.03.11 NGINX 1: 주요 설정 파일 및 명령어 알아보기 (0) 2023.03.07