nginx

How to purge the Nginx cache

꺼비72 2023. 6. 19. 22:56
반응형

Nginx 에서 cache된 contents를 삭제하는 방법은 크게 3가지 정도가 가능하다.

 

1. cli로 삭제하는 방법

2. bypass 방법으로 삭제하는 방법

3. nginx-cache-purge 모듈로 삭제하는 방법

 

1. cli 명령어로 삭제

https://kubby72.tistory.com/entry/cli로-nginx-cache-file찾기

 

cli로 nginx cache file 찾기, 삭제 및 TTL변경

https://kubby72.tistory.com/entry/nginx-cache-key설정 에서 nginx에서 cache file을 저장하는 logic을 설명하였다. 이번에 간단한 script를 통해 해당 파일을 찾고 이를 삭제, 변경하는 방법에 대해 설명하고자 합니

kubby72.tistory.com

에서 설명한 것 처럼 아래와 같이 script를 만들서 삭제할 수 있다.

$ cat purge
#!/bin/bash
files=$(search $1 | cut -f 1 -d ":")
if [ -n "$files" ]; then
        for i in $files; do
            [ -f $i ] || continue
            key=$(head -n 2 $i | grep -EI -a "^KEY:")
            rm $i
            echo "$i ($key) file is deleted "
        done
else
        echo "Contents $1 is not cached."
        exit 3
fi

$ purge my/1.jpg
/var/cache/nginx/6/d3/399dc83e97062c14f36ee6bbb2187d36 (KEY: my/1.jpg) file is deleted

 

2. bypass method로 삭제

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_bypass

 

Module ngx_http_proxy_module

Module ngx_http_proxy_module The ngx_http_proxy_module module allows passing requests to another server. Example Configuration location / { proxy_pass http://localhost:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } Directives

nginx.org

 

이번에는 bypass 명령어로 cache된 contents를 새로이 갱신할 수 있는 방법에 대해 설명하도록 하겠습니다.

proxy_cache_path /var/cache/nginx keys_zone=my_zone:10m inactive=10h;

server {
    listen       80;
    server_name  my;
    set $bypass 0;

    if ($remote_addr ~ "^(127.0.0.1)$") {
    set $bypass $http_cache_purge;
    }
    
    location / {
      proxy_cache my_zone;   
      proxy_cache_key $host$uri$is_args$args;
      proxy_pass http://org; 
      add_header X-CACHE-STATUS $upstream_cache_status;
      proxy_cache_bypass $bypass;
    }
}

if ($remote_addr ~ "^(127.0.0.1)$")는 localhost에서만 실행가능하게 한 보안설정이고, 위 설정은 

요청해더에 Cache-Purge: true 가 설정된 경우 BYPASS 메서드를 호출하는 설정입니다.

bypass된 요청은 원본에서 contents를 가져와서 다시 cache됩니다.

 

아래와 같이 my/1.json을 요청해 cache시키고 해당 파일이 cache되어 있음을 확인합니다.

$ curl my/1.json -I
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Mon, 19 Jun 2023 12:51:48 GMT
Content-Type: application/json
Content-Length: 6
Connection: keep-alive
Last-Modified: Thu, 15 Jun 2023 00:26:34 GMT
ETag: "648a5aba-6"
Expires: Mon, 19 Jun 2023 12:55:02 GMT
Cache-Control: max-age=200
X-CACHE-STATUS: HIT
Accept-Ranges: bytes

$ get_ttl my/1.json
/var/cache/nginx/5/69/1f0419833724d7ff705cd5204bcd1695 (KEY: my/1.json, TTL: 168) EXPIRE at 2023/Jun/19 21:55:02 KST

$ cat /usr/share/nginx/html/1.json
aaaaa

$ cat /usr/share/nginx/html/1.json  ## 원본의 1.json을 bbbb로 변경
bbbbb

$ curl my/1.json -H 'Cache-Purge: true'
bbbbb

위와 같이 -H 'Cache-Purge: true' 를 통해 bypass를 실행하면 원본이 변경된 걸 확인할 수 있다.

$ get_ttl my/1.json  해당파일의 위치를 확인하고, 파일내용을 확인하면 새로운 파일로 cache됨을 확인할 수 있다.
/var/cache/nginx/5/69/1f0419833724d7ff705cd5204bcd1695 (KEY: my/1.json, TTL: 138) EXPIRE at 2023/Jun/19 22:01:56 KST

$ cat /var/cache/nginx/5/69/1f0419833724d7ff705cd5204bcd1695
▒Q▒dWP▒d▒P▒d▒[:`▒
"64905057-6"
KEY: my/1.json
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Mon, 19 Jun 2023 12:58:36 GMT
Content-Type: application/json
Content-Length: 6
Last-Modified: Mon, 19 Jun 2023 12:55:51 GMT
Connection: close
ETag: "64905057-6"
Expires: Mon, 19 Jun 2023 13:01:56 GMT
Cache-Control: max-age=200
Accept-Ranges: bytes

bbbbb

 

3. Nginx Cache Purge 모듈로 삭제

nginx + 에 있는 purge모듈이 아닌 하기 공개소스...

https://github.com/nginx-modules/ngx_cache_purge

 

GitHub - nginx-modules/ngx_cache_purge: nginx module which support to purge ngx_http_(fastcgi|proxy|scgi|uwsgi)_module cache bac

nginx module which support to purge ngx_http_(fastcgi|proxy|scgi|uwsgi)_module cache backend - GitHub - nginx-modules/ngx_cache_purge: nginx module which support to purge ngx_http_(fastcgi|proxy|sc...

github.com

컴파일 옵션 (기존 옵션에 추가)

 --add-module=../ngx_cache_purge --add-module=../nginx-upstream-dynamic-servers--prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'

퍼지를 실행할 곳을 127.0.0.1로  설정하고, 응답을 json으로 설정

server {
    listen       80;
    server_name  my;

    location / {
      proxy_cache my_zone;
      proxy_cache_key $host$uri$is_args$args;
      add_header X-CACHE-STATUS $upstream_cache_status;
      proxy_cache_purge PURGE from 127.0.0.1;
      cache_purge_response_type json;

      proxy_pass http://org;
    }
}

아래와 같이 PURGE 요청하면 key값을 응답하고 정상적으로 purge됨을 확인할 수 있다.

$ curl -X PURGE http://my/1.json
{"Key": "my/1.json"}

* Purge도 가능하다.

1~10까지 json파일을 cache시키고
$  for i in {1..10}; do  curl -Is my/$i.json  ; done

일전에 만든 search로 파일을 찾아보면 아래와 같이 10개의 파일이 cache되어 있음을 확인할 수 있다.
$ search my
/var/cache/nginx/f/ce/e14c1704f4981047f631471ece0a1cef:KEY: my/4.json
/var/cache/nginx/6/1a/d2b44c77a1258af3a5ae6473441ee1a6:KEY: my/7.json
/var/cache/nginx/7/d3/78b22117915bcaee10bd0a6b595ebd37:KEY: my/8.json
/var/cache/nginx/2/83/0aab7b16684b4e64765680944cdeb832:KEY: my/6.json
/var/cache/nginx/d/ea/2d6d90138689c16f5332d0b4970ffead:KEY: my/3.json
/var/cache/nginx/d/cb/e678ceaaa4db37bcfc0b3f1ea98f5cbd:KEY: my/9.json
/var/cache/nginx/5/69/1f0419833724d7ff705cd5204bcd1695:KEY: my/1.json
/var/cache/nginx/3/49/115fb0d9c6024dd2ff9b226d80a43493:KEY: my/2.json
/var/cache/nginx/a/2c/8371c90b8117afbef16b7bf3b625d2ca:KEY: my/5.json
/var/cache/nginx/0/35/6d5f67fb880c6295d379dda9d34f1350:KEY: my/10.json

$ curl -X PURGE http://my/*   ## 와 같이 * purge를 하면
{"Key": "my/*"}

$ search my
$ 

파일이 모두 삭제되었음을 확인할 수 있다.

 

그래도 남는 문제

1. gzip contents : 동일한 cache key의 경우 overwrite 

2. 대소문자 구분 안하는 contents

3. $request_uri != $uri$is_args$args 문제 (purge 요청 uri와 cache uri가 서로다름, 한글 등등..)

4. * purge 시 전체 disk에서 해당 key를 찾는 방식으로 속도 및 부하문제

 

위 방법은 정규화과정을 거쳐서 단순화한 후 purge를 처리할 수 있게 해야한다. 이는 다음에....

'nginx' 카테고리의 다른 글

accept-encoding nomalization  (0) 2024.04.29
nginx gzip, brotli (ngx_gzip, ngx_brotli) 설정  (0) 2024.04.29
nginx proxy hierarchy  (0) 2023.06.19
nginx upstream module - part 3 (dns lookup)  (0) 2023.06.19
nginx upstream module - part2  (0) 2023.06.19