1. Varnish 사이트에서 Current Release 및 설치법 확인

1) https://www.varnish-cache.org/releases

2) https://www.varnish-cache.org/installation/redhat


2. 설치 (CentOS 이므로 Redhat 선택)


rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.0.el6.rpm

yum install varnish



3. 기본 설정

1) 기본 vcl (Varnish Configuration Lanaguage) 파일인 /etc/varnish/default.vcl 수정

...

backend default {

    .host = "127.0.0.1";

    .port = "80";

    .connect_timeout = 1s;

    .first_byte_timeout = 5s;

    .between_bytes_timeout = 2s;

}

 ...

2) 시스템 전역 설정 파일 : /etc/sysconfig/varnish


4. 실행 / 종료

1) service varnish start

2) service varnish stop 

3) netstat -tulpn | grep varnish

(1) 기본 실행 포트 : 6081

(2) 관리 포트 : 6082


5. CLI (/usr/bin/varnish*)

1) admin (관리포트 이용)


varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082


help
200 430
help [command]
ping [timestamp]
auth response
quit
banner
status
start
stop
vcl.load <configname> <filename>
vcl.inline <configname> <quoted_VCLstring>
vcl.use <configname>
vcl.discard <configname>
vcl.list
param.show [-l] [<param>]
param.set <param> <value>
panic.show
panic.clear
storage.list
vcl.show <configname>
backend.list
backend.set_health matcher state
ban <field> <operator> <arg> [&& <field> <oper> <arg>]...
ban.list 


2) 로그 생성


varnishncsa -a

-F "\'%h %{X-Forwarded-For}i %u ...."


3) 통계 보기 (hit ratio)


varnishstat


3) shared memory log

   - The varnishlog utility reads and presents varnishd(1) shared memory logs.

varnishlog



5. 설정을 위해 알아 두어야 하는 것들..

1) Server mode

(1) Grace mode : TTL 이 지난 캐시 데이터를 전송하는 경우를 말함 (A graced object is an object that has expired, but is still kept in cache. Grace mode is when Varnish uses a graced object)

원본 서버나 네트워크에 장애가 있는 경우

- 특정 데이터에 대한 요청을 이미 원본 서버에 보낸 경우

- 해당 모드에서는 동일 데이터에 대해 한 번에 하나의 요청만을 원본 서버에 보낸다. 

- TTL + grace time 이 지난 후에는 캐시에서 데이터가 삭제된다.


* req.grace :  defines how long overdue an object can be for Varnish to still consider it for grace mode.

sb vcl_recv {

  set req.grace= 1h;

}


* beresp.grace : defines how long past the beresp.ttl-time Varnish will keep an object

sub vcl_fetch {

  set beresp.grace = 1h;

}


-  원본 서버로 지정된 daemon에 대해 지정된 주기로 health check를 수행한다. 원본 서버에 문제가 있으면 그 원본 서버에는 요청을 보내지 않는다. 사용할 원본 서버가 없는 경우에는 grace mode로 동작한다.


(2) Saint mode : 원본 서버가 보낸 답장이 비정상인 경우, 비정상 응답 대신 캐시된 데이터를 보내는 경우.

- 원본 서버가 status code 500을 보냈거나 특정 헤더를 추가하여 보낸 경우 Saint mode 로 동작 할 수 있다.

Saint mode is out, yes. However we are working on reimplementing it as a VMOD. There are some archtectural challenges so I'm not sure when we'll be able to deliver this.

Grace in v4 works like this. Varnish will deliver a graced object when there is no fresh object and it will refresh it asynchronously. You can alter the behaviour in vcl_hit, please see the default VCL.

https://www.varnish-cache.org/forum/topic/2777


sub vcl_fetch {

  if ( beresp.status == 500 ||

    beresp.http.content-length == 0 ) {

    set beresp.saintmode = 10s;

  }

  set beresp.grace = 1h;

}


2) Collapsed forwarding

(1) 여러 클라이언트가 동일한 URI에 대한 다수의 요청을 보낼 경우, Varnish 는 원본 서버에 1개의 요청만을 보낸다.

(2) 원본 서버에서 데이터가 도착 할 때까지 waiting 된다.


3) Cookie / Vary

(1) Varnish 는 기본적으로 Cookie를 가지는 데이터는 캐시하지 않는다. (Cookie 가 들어간 데이터는 동적 데이터로 간주)

(2) 강제로 캐시하기 위해서는 쿠키를 삭제하는 설정등의 추가적인 설정이 필요하다.

(3) vary header 값이 존재하면 하나의 hash key 에 여러개의 caching data 가 존재한다.


4) Cache 삭제

(1) Purge : 데이터 강제 삭제

(2) Ban : 정규 표현식을 사용하여 원하는 형태의 데이터가 사용되지 않도록 filtering 함. 실제 cache data는 삭제되지 않음.


5) 저장 공간 (malloc, file, persistent) https://www.varnish-cache.org/docs/trunk/users-guide/storage-backends.html

(1) malloc : malloc() 함수를 사용하여 메모리를 할당. 데이터가 전부 메모리에 저장될 수 있으면, malloc을 사용하고 그렇지 않으면 file을 사용한다.

(2) file : file 저장 공간에서도 어떤 데이터는 디스크에 저장되지 않고 메모리에만 있을 수 있다. 

(3) persistent : Varnish가 재실행되어도 이전의 데이터가 남아 있기를 원한다면 persistent 저장 공간을 사용한다. 공간이 부족할 때 LRU(Least Recently Used) 대신 FIFO(First In, First Out)로 victim이 선택된다.


6) ESL (Edge Side Includes)

(1) 여러 웹 페이지 또는 데이터를 조합하여 전송할 수 있는 기능

(2) 태그  : <esi:include src='small_data.html'/>


7) VCL (Varnish Configuration Language) 

1) 요청 흐름

(1) 캐시에 저장된 데이터가 사용되는 경우

- vcl_recv() → vcl_hash() → vcl_hit() → vcl_deliver()

(2) 요청한 데이터가 캐시에 없는 경우

- vcl_recv() → vcl_hash() → vcl_miss() → vcl_fetch() → vcl_deliver()

2) VCL 함수

(1) vcl_recv : 클라이언트로 부터 요청을 받으면 실행되는 함수. 웹 요청을 변경하거나 캐시 사용 여부를 결정.

(2) vcl_hash : (Cache Key) hash 함수의 입력을 결정한다. 기본은 query string을 포함한 URL과 웹 서비스의 도메인 네임이다. 쿠키 값이나 User-Agent 값을 추가할 수 있다.

(3) vcl_fetch : 원본 서버가 보낸 답장을 받으면 실행되는 함수. 원본 서버가 보낸 답장을 변경하거나 TTL 값을 정함.

(4) vcl_deliver : 사용자에게 답장을 보내기 전에 실행되는 함수. 사용자에게 보낼 답장을 변경할 수 있음.

3) VCL 리턴

(1) lookup : 요청받은 데이터가 캐시에 있는지 확인

(2) pass : 캐시에 저장된 데이터는 무시하고 백엔드(backend) 서버에 요청을 보내라는 의미. 백엔드 서버가 보낸 데이터는 캐시에 저장하지 않는다. 함수 호출 흐름은 그대로 수행.

(3) pipe : pass와 유사. 함수 호출 흐름은 무시되고, 브라우저와 백엔드 서버가 주고 받는 데이터를 중계만 한다.


7) Status code to be cached


200: OK

203: Non-Authoritative Iniformation

300: Multiple Choices

301: Moved Permanently

302: Moved Temporarily

307: Temporary Redirect

410: Gone

404: Not Found


8) Version 3 to Version 4 (http://www.listekconsulting.com/articles/varnish-cache-migrate-3-4/)

(1) sess_timeout has been renamed to timeout_idle.

(2) req.request is now req.method

(3) error return( synth(error_code,message))

(4) remove unset

(5) vcl_fetch vcl_backend_response

(6) req.backend.healthy std.healthy(resp.backend_hint) The current documentation is wrong, use backend_hint and not backend

(7) req.request req.method

(8) session_linger timeout_linger Parameter for varnishd

(9) client.port std.port(client.ip) Requires Standard VMOD: import std;

(10) server.port std.port(server.ip)


6. 추가 설정 (튜닝)

1) VSM (Varnish Shared Memory)

(1) log 를 저장하는 공간

(2) Linux 의 tmp filesystem 을 mount 하여 사용할 것을 권장


2) Transient storage

(1) transient storage is where all extremely short-lived objects are placed.

(2) 캐시주기가 10초 이하인 데이터를 저장 (Parameter shortlived : default 10)

(3) default 가 unlimited 이기 때문에 스왑 문제가 발생할 수 있다.

(4) shortlived 값을 0 으로 하여 사용하지 않도록 설정할 수 있다.

(5) 또는 적절한 메모리를 할당하여 해당 만큼만 쓰도록 설정한다. (-s option)


 shortlived: 0 seconds

 -s Transient=malloc,100M


3) Thread


 thread_pool: 2

 thread_pool_min: 5

 thread_pool_max: 500


4) Client IP

(1) X-forwarded-For = client.ip 와 같은 처리가 필요할 수 있다.


5) 요청 및 답장의 크기 / Listen Queue

http_req_hdr_len: 8192 bytes

http_req_size: 32768 bytes

http_resp_hdr_len: 8192 bytes

http_resp_size: 32768 bytes

listen_depth: 1024 (8192) 


6) timeout (https://www.varnish-cache.org/docs/3.0/reference/varnishd.html)

(1) 브라우저와 Varnish Server 사이의 Timeout

sess_timeout : Idle timeout for persistent sessions. If a HTTP request has not been received in this many seconds, the session is closed

send_timeout : 브라우저로 데이터는 보내는 시간

idle_send_timeout : Time to wait with no data sent. If no data has been transmitted in this many seconds the session is closed

(2) Varnish Server와 원본 서버 사이의 Timeout

connect_timeout : 연결이 얼마 이내에 이뤄져야 하는가 (sess_timeout has been renamed to timeout_idle. at version 4)

first_byte_timeout : 원본 서버로부터 첫번째 바이트가 도착하는 시간

between_bytes_timeout : Default timeout between bytes when receiving data from backend. We only wait for this many seconds between bytes before giving up. A value of 0 means it will never time out. VCL can override this default value for each backend request and backend request. This parameter does not apply to pipe.

sess_timeout: 1 seconds

send_timeout: 60 seconds

idle_send_timeout: 6 seconds

connect_timeout: 0.7 seconds

first_byte_timeout: 5 seconds

between_byte_timeout: 2 seconds


7) not found

(1) 원본 서버에 파일이 없는 경우, 파일이 정상적으로 업로드 된 후 신속하게 캐시 될 수 있도록 임시적으로 ttl 을 짧게 수정하여 처리한다.


sub vcl_fetch {

  if ( beresp.status != 200 ) {

    set beresp.ttl = 1s;

  }

  else {

    set beresp.ttl = 1m;

  }

}


8) access log (https://www.varnish-cache.org/docs/trunk/reference/varnishncsa.html)

(1) varnishncsa 를 이용해 로그를 남길 수 있다. (Varnish 가 실행되어 있어야 함)

           - varnishncsa -w /var/log/varnish/access.log

varnishncsa -a

-F "\'%h %{X-Forwarded-For}i %u ...."

-w /var/logs/varnish_access.log -D

-P /var/log/varnishncsa.pid

-m "RxURL:.*\.php"


9) Linux Kernel 튜닝


 net.core.somaxconn 128 -> 8192

 net.ipv4.tcp_wmem 4096 16384 4194304 -> 4096 262144 4194304


10) Partitioning Storage (https://www.varnish-software.com/blog/partitioning-your-varnish-cache)


DAEMON_OPTS="-a :80 \

             -T localhost:6082 \

             -f /etc/varnish/default.vcl \

             -S /etc/varnish/secret \

             -s default=malloc,64m \

             -s foo=malloc,128M \

             -s bar=malloc,128M"


sub vcl_backend_response {

    if (bereq.http.host ~ "foo") {

       set beresp.storage_hint = "foo";

       set beresp.http.x-storage = "foo";

    } elsif (bereq.http.host ~ "bar") {

       set beresp.storage_hint = "bar";

       set beresp.http.x-storage = "bar";

    } else {

       set beresp.storage_hint = "default";

       set beresp.http.x-storage = "default";

   }

}


7. CURL 이용

1) header 확인

- curl -I http://file.test.co.kr/test.jpg

2) Purge

curl -X PURGE http://file.test.co.kr/test.jpg


8. 참고 사이트

1) http://deview.kr/2013/detail.nhn?topicSeq=3

2) http://helloworld.naver.com/helloworld/textyle/352076

3) http://phk.freebsd.dk/pubs/varnish_cms.pdf

4) https://www.varnish-software.com/static/book/VCL_Basics.html

5) https://www.varnish-cache.org/docs/trunk/reference/varnishd.html (varnishd 실행 옵션)


Posted by 얼랄라