ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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 버전을 명시합니다.
    • 캐시 분할 모듈은 변경되지 않고 용량이 큰 파일에만 적용해야 합니다.
    반응형
Designed by Tistory.