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'/>
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 실행 옵션)