InfraPlatform

[꿀팁]고성능 Nginx를위한 튜닝(5)-마이크로캐싱

IT오이시이 2021. 1. 9. 21:22
728x90

#Nginx-install #nginx-설치 #웹서버 설정 #Nginx웹서버설치 #웹서버튜닝 #Nginx웹서버 설정 #Nginx웹서버설치 #웹서버튜닝 #high performancen nginx #system performance tunning #웹서버 튜닝 #성능개선 #시스템튜닝 #파일시스템 튜닝 #대용량 웹서버 튜닝

 

1. 디스크의 I/O 병목 줄이기
2. 프로세스 처리량 늘리기 (Process)
3. TCP 관련 처리량 늘리기
4. 메모리 및 CPU 튜닝하기 (Processor)
5. 마이크로캐싱
6. 로그 부하 줄이기
7. Dos, DDos 방어 설정

 

 

 

[꿀팁]고성능 Nginx를위한 튜닝(5)-마이크로캐싱

 

"Nginx의 성능을 극대화 하기위해서는 시스템의 성능 개선만 있는 것은 아닙니다.
시스템의 성능 개선에는 비용적인 기술적인면에서 한계가 있기 때문에

적절한 캐싱으로 해결 해야  효율적입니다. "

 

1.마이크로캐싱이란!
2. Nginx를 이용한 WAS 부하 관리
3. Nginx 캐싱의 활용한 컨텐츠와 서비스 응답 캐싱 설정 
4. memcache/redis 를 이용한 캐싱
5. memory cache를 이용한 예시

 

1.마이크로캐싱이란!


웹서비스에서 캐싱이라는 것은 웹캐싱서버나 CDN(Contents Delivery Network) 업체들을 통해 정적인 콘텐츠를 캐싱하는 것으로 알려져 있습니다.
마이크로캐싱(microcaching)이라는 것은
매우 짧은 시간 동안 응답 컨텐츠를 캐싱하여 동적이거나 개인화되지 않은 컨텐츠의 전달을 가속화하는 효과적인 방법입니다.
대량의 트래픽이 유입되는 시스템에서는 순간적으로 동일한 응답과 중복된 데이터가 필요한 상황들이 존재 합니다. 중복 응답이나, 일정 시간동안 데이터 값의 변동이 없는 경우에 캐싱을 통해서 유입되는 요청을 웹서버의 캐싱으로서 응답을 함으로써 백엔드 웹서비스 Was의 부하를 줄일 수 있습니다.

이러한 "마이크로캐싱"은 정적 컨텐츠, 개인화컨텐츠, 동적컨텐츠 까지 응답값이 개별 URI로 특정 시간동안 독립적으로 유효한 경우 적용 가능 합니다.

예를 들어 실시간 키워드 목록, 인기글 목록, 게시물의 갯수, 환율조회 등과 같은 페이지에서 특정 URI(parameter포함)로 인식되면서 내용이 일정기간 유지되고 동일한 응답을 제공하는 경우 사용하면 효과 적입니다.

이것을 이용하면 대량의 조회시스템에 적용하여 빈빈한 DB조회나 SUM(),COUNT() 같은 집계성 DB호출을 특정시간 동안 캐싱으로 대체하면 DB의 부하도 줄여 줍니다.

이런 관점에서 마이크로 캐싱을 활용해 보시면 좋겠습니다.

 

2. Nginx를 이용한 WAS 부하 관리

Nginx를 활용하는 중요한 관점은 웹서버와 웹서비스 Was의 기능적 분리도 있지만 대량의 트래픽으로 인한 충격을 DB나 백엔드 Was로 전달하지 않는 완충 장치로 활용 하는 것입니다.
"즉 성능개선을 한다고 Nginx의 성능만 극대화 하는 개선에 중점을 둘 것이 아닙니다."
유입되는 트레픽으로 부터 웹서버 뒤에 있는 웹서비스 WAS나 DB의 성능을 보호 하여 처리량을 일정하게 유지하는 것이 성능의 최적화로 중요하다는 의미입니다. 그래서 Nginx를 웹서버로 활용하기보다 대량으로 유입되는 트레픽을 일정하게 유지하기 위한 큐잉과 Buffering하는 Nginx의 역할이 더 중요하다고 강조합니다.


이런 관점에서 이전의 연재글에서는 주로 backlog나 Buff를 통해서 부하에 대한 완충을 하는 것을 다루었습니다. 이번 글에서는 요청에 대한 응답의 빈도를 줄이기 위해 캐싱을 활용 하는 것을 다루어 보고자 합니다.

물론 별도 Redis, Membase, ecache 등 다양한 메모리 캐시를 활용 할 수도 있지만 프로그램 수정 없이도 캐싱 효과를 제공 할 수 있다는 점이 가장 큰 장점이라고 할 수 있습니다.
Nginx를 활용하여 이미지, css, js 등의 웹리소스와 같은 정적(Static) 컨텐츠 뿐만 아니라, 반복적으로 요청되는 데이터 호출이나 일정 기간동안 동일한 내용으로 유지되는 동적인 컨텐츠를 일시적으로 캐싱(마이크로캐싱)할 수 있습니다. 이것으로 비즈니스 영역의 웹서비스 WAS가 처리할 일을 줄여주고, 빈번한 DB 호출도 경감하여 서비스의 성능을 유지할 수가 있습니다.
마이크로 캐싱을 활용하는 예를 들면 "항공권의 좌석 예약 조회에 1만명이상이 동시에 조회를 하는 상황에서 잔여 좌석을 조회 하는 경우 좌석 조회 요청의 응답을 1초정도의 마이크로 캐싱을 하면, 중복되는 응답 요청을 캐싱으로 처리하여 조회 요청 처리량의 부하를 줄일 수 있습니다.

 

3. Nginx 캐싱의 활용한 컨텐츠와 서비스 응답 캐싱 설정

Nginx는 캐싱이 활성화되면 응답을 디스크 캐시에 저장하고 매번 동일한 콘텐츠에 대한 요청을 프록시하지 않고도 클라이언트에 응답이 가능합니다.
일반적인 정적컨텐츠는 물론 proxy를 통해 특정 URI(URL과 parameter) 로 인식되는 웹서비스(WAS) 같은 동적 응답도 캐싱이 가능합니다.

http {
    ...
    proxy_cache_path /data1/cache levels=1:2 keys_zone=my_cache_d1:10m max_size=1g inactive=1m use_temp_path=off;
    proxy_cache_path /data2/cache levels=1:2 keys_zone=my_cache_d2:10m max_size=1g inactive=1m     use_temp_path=off;

    split_clients $request_uri $my_cache {
       50% “my_cache_d1”;
        50% “my_cache_d2”;
    }


    server {
        listen 80 default_server;
       listen [::]:80 default_server;
       root /var/www/html;
        # Add index.php to the list if you are using PHP
       index index.html index.htm

       server_name _;

        # 정정 (Static) 컨텐츠 캐싱 활성화 (브라우저 캐싱 활용)
       location ~* \.(?:manifest|appcache|html?|xml|json)$ {
           expires -1;
       }
        location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
           access_log off;
           expires 1M;
           add_header Cache-Control "public";
        }
        location ~* \.(?:css|js)$ {
        access_log off;
        expires 1y;
        add_header Cache-Control "public";
    }

    # 동적 응답 캐싱 활성화 (마이크로 캐싱)
    location /sc {
        proxy_cache my_cache;
       proxy_cache_methods GET HEAD POST;
       proxy_cache_key "$scheme$request_method$host$uri$is_args$args";
       # proxy_cache_key "$host$request_uri$cookie_user";

       proxy_cache_bypass $cookie_nocache $arg_nocache $http_pragma;
        proxy_cache_min_uses 3;

        #proxy_cache_lock on;
        proxy_cache_valid 200 302 1m;
        proxy_cache_valid 404 1m;
        add_header X-Cache-Status $upstream_cache_status;

        # cache PURGE (NGINX Plus 버전에 포함)
        proxy_cache_purge $purge_method ;
       ...
       proxy_pass http: //was_upstream;
    }

}

 

(캐싱 설정 예시)

proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=1m use_temp_path=off;

 

* /path/to/cache levels=1:2 : "/path/to/cache" 와 같이 2depth 디렉토리를 설정하여 많은 수의 파일을 한 디렉토리에 저장되지 않도록 합니다.

* keys_zone사용 타이머와 같은 메타 데이터 및 캐시 키를 저장하기위한 공유 메모리 영역을 설정합니다.
메모리에 키 사본이 있으면 NGINX는 디스크로 이동할 필요없이 요청이 메모리에 저장된 값의 캐시 유무(HIT/Miss)를 신속하게 확인할 수 있으므로 검사 속도가 크게 빨라집니다. 1MB 영역은 약 8,000 개의 키에 대한 데이터를 저장할 수 있으므로 예제에서 구성된 10MB 영역은 약 80,000 개의 키에 대한 데이터를 저장할 수 있습니다.

* max_size캐시 크기의 상한을 설정합니다. 1GB 까지 설정 하였습니다.
- 값을 지정하지 않으면 사용 가능한 모든 디스크 공간을 캐시가 사용합니다.

* inactive항목이 액세스되지 않고 캐시에 남아있을 수있는 기간을 지정합니다. 예에서는 1분 동안 요청되지 않은 파일은 만료 여부에 관계없이 캐시 관리자 프로세스에 의해 캐시에서 자동으로 삭제됩니다.

* split_clients : 디스크의 부하 분산을 위해서 여러개의 디스크에 캐싱 영역을 할당하고 분산 저장 하는 것입니다.

* proxy_cache_min_uses : 항목을 캐시하기 전에 클라이언트가 항목을 요청해야하는 횟수이상일때 캐싱을 합니다.
- default : proxy_cache_min_uses = 1


*proxy_cache_purge : 캐시 퍼지 요청을 보내면 캐시가 제거 됩니다. curl 같은 명령을 이용하여 캐시를 삭제 요청을 보낼수 있습니다. (프록시 캐시 퍼지 기능은 NGINX Plus 버전에 포함되어 있습니다.)

curl -X PURGE -D – "https://www.example.com/*"

 

[Proxy Carh 관련 참고]  

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

- proxy_cache: 프록시 캐시를 사용하도록 지정 
- proxy_cache_background_update: 백그라운드에서 프록시 캐시를 업데이트 
- proxy_cache_bypass: 특정 요청을 캐시하지 않고 원래 서버로 전달 
- proxy_cache_convert_head: HEAD 요청에 대해 GET 요청과 동일한 캐시 업데이트를 수행 
- proxy_cache_key: 캐시 키를 구성하는 데 사용되는 변수를 지정 
- proxy_cache_lock: 여러 요청이 동시에 동일한 캐시 항목을 업데이트하지 않도록 막는 데 사용 
- proxy_cache_lock_age: 캐시 항목의 잠금을 얼마 동안 유지할 것인지 지정 
- proxy_cache_lock_timeout: 캐시 항목의 잠금을 획득하기 위해 대기하는 최대 시간을 지정 
- proxy_cache_max_range_offset: 범위 요청에 대한 캐시된 데이터의 최대 오프셋을 지정 
- proxy_cache_methods: 캐시를 사용할 HTTP 메서드를 지정 
- proxy_cache_min_uses: 캐시된 항목이 유효해지기 전에 최소한으로 사용되어야 하는 요청 수를 지정 
- proxy_cache_path: 캐시 파일이 저장될 디렉토리를 설정 
- proxy_cache_purge: 캐시된 항목을 삭제하는 요청을 처리 
- proxy_cache_revalidate: 캐시된 항목이 유효한지 다시 확인
- proxy_cache_use_stale: 원래 서버로의 요청이 실패한 경우에도 캐시된 데이터를 사용 여부 설정 
- proxy_cache_valid: 특정 상태 코드에 대한 캐시 유효 기간을 지정

 

 

4. memcache/redis 를 이용한 캐싱

자주 접하지 않은 내용이지만 Nginx에서 memcache/ redis 를 이용한 캐싱도 지원을 합니다.

Memcache cache 를 이용한 Preload 

http {
    upstream cache_backend {
        server
host:11211; # a pool with at most 1024 connections
        keepalive 1024 single;
    }

    server {
       location / {
            set $memcached_key "$uri?$args";
           memcached_pass
cache_backend;
            default_type text/html;
            error_page 404 502 504 = @fallback;
        }
        location @fallback {
            proxy_pass http://http_backend;
        }
    }
}
memcached_bind    : Memcached 모듈이 바인딩할 IP 주소와 포트를 지정
memcached_buffer_size    :  Memcached 모듈이 사용하는 버퍼 크기를 지정
memcached_connect_timeout  : Memcached 서버와의 연결 시도 타임아웃을 지정
memcached_force_ranges  : Memcached 모듈이 범위 요청을 지원하도록 강제
memcached_gzip_flag   :  Gzip 압축을 사용하여  캐시된 데이터의 전송량을 줄일 수 있음
memcached_next_upstream  : Memcached 서버가 응답하지 않을 경우 다음 업스트림 서버로 전달
memcached_next_upstream_timeout  :  다음 업스트림 서버로 전환하기 전의 타임아웃을 지정
memcached_next_upstream_tries :  서버가 응답하지 않을 경우, 다음 서버로 전환 시도할 횟수 설정
memcached_pass  : 요청을 전달할 Memcached 서버의 주소와 포트를 지정
memcached_read_timeout  : 서버로부터 응답을 기다리는 동안의 타임아웃 시간을 설정
memcached_send_timeout : 서버로 데이터를 전송하는 동안의 타임아웃 시간을 설정
memcached_socket_keepalive : 소켓 keep-alive를 사용하여 소켓 연결을 유지하는 데 도움

 

HTTP Redis Cache 사용

load_module /path/to/modules/ngx_http_redis_module.so;

http {
    upstream cache_backend {
        server 127.0.0.1:6379; # a pool with at most 1024 connections
        keepalive 1024 single;
    }

    server {
        location / {
            set $redis_key "$uri?$args";
            redis_pass
cache_backend;
            default_type text/html;
            error_page 404 502 504 = @fallback;
        }
       location @fallback {
             proxy_pass http://http_backend;
        }
    }
}

 

www.nginx.com/resources/wiki/modules/redis/
www.nginx.com/resources/wiki/modules/redis/#variables
www.nginx.com/resources/wiki/modules/redis/#keep-alive-connections-to-redis-servers

 

 

5.  memcached  cache를 이용한 예시

  - memcache에 저장된 경우 chche에서 읽고 cache에 없는 경우 웹서비스 호출을 하게 됩니다.

http {   
      .... 
  server{
        location /python/css/ {
        alias "/code/location/css/";
    }
    location /python/ {
        set $memcached_key "$request_method$request_uri";
        charset utf-8; memcached_pass 127.0.0.1:11211;
        error_page 404 502 504 = @pythonfallback;
        default_type text/html;
    }
    location @pythonfallback {
        rewrite ^/python/(.*) /$1 break;
        proxy_pass http://127.0.0.1:5000;
        proxy_set_header X-Cache-Key "$request_method$request_uri";
    }
}



[참고] 
* docs.nginx.com/nginx/admin-guide/content-cache/content-caching/

#Nginx웹서버 설정 #Nginx웹서버설치 #웹서버튜닝

 

1. 디스크의 I/O 병목 줄이기
2. 프로세스 처리량 늘리기 (Process)
3. TCP 관련 처리량 늘리기
4. 메모리 및 CPU 튜닝하기 (Processor)
5. 마이크로캐싱
6. 로그 부하 줄이기
7. Dos, DDos 방어 설정

 

728x90
반응형