Varnish on CentOs
Que es Varnish??? Si quieres instalarlo seguro que ya sabes lo que es y para que sirve…
Nosotros vamos a utilizar Varnish como proxy inverso (reverse-proxy) de contenido estático, pero este “Open Source” está diseñado como acelerador de contenidos, ya sea estático o dinámico. De momento solo vamos a utilizarlo como cache de imágenes, de nuestro portal.
La instalación es sencilla, pero tendremos que familiarizarnos con su propio lenguaje de VCL http://www.varnish-cache.org/trac/wiki/VCL, luego explicare el fichero de configuración que tenemos aplicado en nuestro sistema.
La estructura, tenemos dos servidores Varnish, que atienden por el puerto 80 (estos dos server están balanceado) a su vez tenemos dos backend que contienen los repositorios de imágenes, que responden al puerto 81 con un LighttpD sobre Windows.
Desglose técnico:
Varnish Server:
PROXY01 -> CentOs 5.6 kernel 2.6.18-238.9.1.el5 x64 – 12 GB RAM – 136 GB disco.
PROXY02 -> CentOs 5.6 kernel 2.6.18-238.9.1.el5 x64 – 12 GB RAM – 136 GB disco.
Backend Server:
IMG01 -> Windows 2008 Enterprise R2 x64 – 9 GB RAM – 1.5 TB imágenes (1 TB ocupado)
IMG02 -> Windows 2008 Enterprise R2 x64 – 9 GB RAM – 1.5 TB imágenes (1 TB ocupado)
Storage System:
Una vez ya sabemos cómo tenemos construido el sistema, vamos a proseguir con la instalación y configuración del sistema.
Instalación, tenemos que isntalar el repositorio de varnish para poder realizer un yum install.
[#] rpm --nosignature -i http://repo.varnish-cache.org/redhat/el5/noarch/varnish-release-2.1-2.noarch.rpm
[#] yum install varnish
Ya tenemos la instalación de Varnish, dejamos activado el autoarranque del servidor y de los sistemas de LOG.
[#] chkconfig varnish on
[#] chkconfig varnishlog on
[#] chkconfig varnishncsa on
Los tiene dos servicios de log los cuales se guardan en /var/log/varnish/ tenemos el varnishlog es el propio sistema de log, con formato Varnish, nos muestra el flujo de las peticiones, lo podemos utilizar en consola.
[#] varnishlog
16 TxHeader b Accept-Encoding: gzip, deflate
16 TxHeader b Host: images.
16 TxHeader b X-Varnish: 705369720
16 RxProtocol b HTTP/1.1
16 RxStatus b 200
16 RxResponse b OK
16 RxHeader b Content-Type: image/jpeg
16 RxHeader b Accept-Ranges: bytes
16 RxHeader b ETag: "2884099485"
16 RxHeader b Last-Modified: Sun, 01 May 2011 10:52:54 GMT
16 RxHeader b Content-Length: 1901
16 RxHeader b Connection: close
16 RxHeader b Date: Mon, 02 May 2011 10:21:53 GMT
16 RxHeader b Server: LightTPD/1.4.28 (Win32)
18 TTL c 705369720 RFC 120 1304331713 0 0 0 0
18 VCL_call c fetch
18 TTL c 705369720 VCL 604800 1304331713
18 VCL_return c deliver
18 ObjProtocol c HTTP/1.1
18 ObjStatus c 200
18 ObjResponse c OK
18 ObjHeader c Content-Type: image/jpeg
18 ObjHeader c ETag: "2884099485"
18 ObjHeader c Last-Modified: Sun, 01 May 2011 10:52:54 GMT
18 ObjHeader c Date: Mon, 02 May 2011 10:21:53 GMT
18 ObjHeader c Server: (Win32)
18 ObjHeader c X-Cacheable: YES
18 ObjHeader c cache-control: max-age = 2592000
Y el varnishncsa sistema de log con formato web, lo podemos comprobar mediante
[#] tail –f /var/log/Varnish/Varnishncsa.log
172.xx.xx.xx - - [02/May/2011:12:30:38 +0200] "GET /test.jpg " 400 349 "-" "-"
Es recomendable modificar la configuración del logrotate para que cambien los log a diario vi /etc/logrotate.conf
[#] vi /etc/logrotate.conf
# see "man logrotate" for details
# rotate log files weekly
daily
# keep 4 weeks worth of backlogs
rotate 7
Almacenamiento de Varnish.
Tenemos dos opciones para almacenar en cache los objetos, uno es utilizar la memoria RAM, este tiene la ventaja que trabaja más rápido que el disco y la desventaja necesitamos mucha memoria RAM si queremos tener una gran numero de objetos cacheados. La otra opción es utilizar disco físico como almacenamiento, esta opción está muy bien pensada porque por lo contrario de otros sistemas reverse-proxy, Varnish utiliza un único fichero con la capacidad que le indiquemos y lo gestiona de una manera óptima e indexada.
En la configuración explicare como utilizar una opción o la otra, todo dependerá de nuestros requisitos, nosotros hemos utilizado la opción de disco con particiones ext4 porque este formato de disco optimiza los fichero de gran tamaño.
En CentOs, a partir de la versión 5.6 es totalmente compatible el formato ext4 una vez tenemos instalado la versión correcta, instalamos la herramienta de para dar formato a nuestra partición.
[#] yum -y install e4fsprogs
Como no tenemos la posibilidad de tener dos disco en RAID-1 para el servidor, hemos realizado dos particiones sobre el RAID-1 de 136 GB, la partición /cache_disk la utilizaremos solo para almacén de objetos.
[#] df -h
Filesystem Size Used Avail Use% Mounted on
/dev/cciss/c0d0p1 21G 2.5G 17G 13% /
/dev/cciss/c0d0p2 98G 2.3G 91G 3% /cache_disk
tmpfs
Vamos a desmontar c0d0p2.
[#] umount /dev/cciss/c0d0p2
Le damos formato a la partición.
Le damos formato a la partición.
[#] tune4fs -O extents,uninit_bg,dir_index /dev/cciss/c0d0p2
Optimización de la partición.
[#] e4fsck -fDC0 /dev/cciss/c0d0p2
Tenemos que configurar el fichero fstab para dejar los cambios en el inicio.
[#] vi /etc/fstab
Tenemos que realizar la siguientes modificaciones, quitar LABEL=/cache_disk y ponemos /dev/cciss/c0d0p2, cambiar ext3 por ext4 y para el Varnish poner las opciones noatime,nodiratime la configuración nos quedaría de la siguiente manera.
/dev/cciss/c0d0p2 /cache_disk ext4 defaults,noatime,nodiratime 1 2
Volvemos a montar la unidad y reiniciamos para comprobar que todo funciona OK.
[#] mount /dev/cciss/c0d0p2
Configuración Varnish
Ya tenemos instalado Varnish y preparado el servidor para realizar la configuración, lo primero que tenemos que conocer son los tres ficheros de configuración de Varnish.
Fichero de configuración del servidor Varnish
[#] vi /etc/sysconfig/varnish
----------------------------------------------------------------------
# Configuration file for varnish
#
# /etc/init.d/varnish expects the variable $DAEMON_OPTS to be set from this
# shell script fragment.
#
# Maximum number of open files (for ulimit -n)
NFILES=131072
# Locked shared memory (for ulimit -l)
# Default log size is 82MB + header
MEMLOCK=82000
# # Main configuration file. You probably want to change it :)
VARNISH_VCL_CONF=/etc/varnish/myconfig.vcl
#
# # Default address and port to bind to
# # Blank address means all IPv4 and IPv6 interfaces, otherwise specify
# # a host name, an IPv4 dotted quad, or an IPv6 address in brackets.
# VARNISH_LISTEN_ADDRESS=
VARNISH_LISTEN_PORT=80
#
# # Telnet admin interface listen address and port
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082
#
# # Shared secret file for admin interface
VARNISH_SECRET_FILE=/etc/varnish/secret
#
# # The minimum number of worker threads to start
VARNISH_MIN_THREADS=1
#
# # The Maximum number of worker threads to start
VARNISH_MAX_THREADS=1000
#
# # Idle timeout for worker threads
VARNISH_THREAD_TIMEOUT=120
#
# # Cache file location
VARNISH_STORAGE_FILE=/cache_disk/varnish_storage.bin
#
# # Cache file size: in bytes, optionally using k / M / G / T suffix,
# # or in percentage of available disk space using the % suffix.
VARNISH_STORAGE_SIZE=90G
# # Cache memory size: same that Storage_file
VARNISH_MEMORY_SIZE=10G
#
# # Backend storage specification
VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"
#
# # Default TTL used when the backend does not specify one
VARNISH_TTL=120
#
# # DAEMON_OPTS is used by the init script. If you add or remove options, make
# # sure you update this section, too.
DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
-f ${VARNISH_VCL_CONF} \
-T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
-t ${VARNISH_TTL} \
-w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \
-u varnish -g varnish \
-S ${VARNISH_SECRET_FILE} \
-s ${VARNISH_STORAGE} \
# -s malloc,${VARNISH_MEMORY_SIZE} \
-p obj_workspace=4096 \
-p sess_workSpace=262144 \
-p listen_depth=4096 \
-p overflow_max=2000 \
-p ping_interval=2 \
-p log_hashstring=off \
-h classic,5000009 \
-p thread_pool_max=4000 \
-p lru_interval=20 \
-p esi_syntax=0x00000003 \
-p sess_timeout=2 \
-p thread_pools=4 \
-p thread_pool_min=400 \
-p shm_workspace=32768 \
-p srcadd_ttl=0 \
-p thread_pool_add_delay=2"
Que hemos configurado,
VARNISH_VCL_CONF=/etc/varnish/myconfig.vcl
Que fichero vamos a utilizar para la configuración del proxy, este fichero lo explicaremos más adelante.
VARNISH_STORAGE_FILE=/cache_disk/varnish_storage.bin
Donde vamos a ubicar el fichero de cache, este fichero lo ubicamos en la partición ext4 que hemos creado anteriormente, el acceso y rendimiento es óptimo.
VARNISH_STORAGE_SIZE=90G
El espacio disponible que damos al Varnish para que almacene objetos.
VARNISH_MEMORY_SIZE=10G
Si utilizamos la memoria como almacén de objetos, esta será la memoria que utilizara, en nuestro caso no lo utilizamos, esto lo indicamos.
-s ${VARNISH_STORAGE} \
# -s malloc,${VARNISH_MEMORY_SIZE} \
Ahora vamos a ver la configuración del daemon DAEMON_OPTS
-p obj_workspace=4096 \
-p sess_workSpace=262144 \
-p listen_depth=4096 \
-p overflow_max=2000 \
-p ping_interval=2 \
-p log_hashstring=off \
-h classic,5000009 \
-p thread_pool_max=4000 \
-p lru_interval=20 \
-p esi_syntax=0x00000003 \
-p sess_timeout=2 \
-p thread_pools=4 \
-p thread_pool_min=400 \
-p shm_workspace=32768 \
-p srcadd_ttl=0 \
-p thread_pool_add_delay=2"
Esta optimizada la configuración para el servidor con 2 Procesadores Intel DualCore x64.
thread_pool_add_delay=2
thread_pools = <Number of cpu cores>
thread_pool_min = <800/number of cpu cores>
thread_pool_max = 4000
Ya tenemos configurado el servidor, ahora tenemos que configurar el servicio, aquí entra en juego el lenguaje propio del Varnish VCL, nuestra configuración es muy sencilla solo reverse-proxy de imágenes.
Configuración VLC
[#] vi /etc/Varnish/inmesp.vcl
## This is a basic VCL configuration file for varnish.
#
## Backend definition.
# set default backend if no server cluster specified
backend inmesp_default {
.host = "img01";
.port = "81";
.probe = {
.url = "/test.jpg";
.interval = 10s;
.timeout = 5 s;
.window = 5;
.threshold = 3;
}
}
# create a round-robin director: "images_cluster" uses server1 and server2 as backend servers.
director inmesp_cluster round-robin {
{ .backend = {
.host = "img01";
.port = "81";
.probe = {
.url = "/test.jpg";
.interval = 5s;
.timeout = 1 s;
.window = 5;
.threshold = 3;}
}
}
{ .backend = {
.host = "img02";
.port = "81";
.probe = {
.url = "/test.jpg";
.interval = 5s;
.timeout = 1 s;
.window = 5;
.threshold = 3;}
}
}
}
## Only permit cluster to purge files from cache
acl purge {
"proxy01";
"proxy02";
}
## vcl_recv is called whenever a request is received
sub vcl_recv {
# This uses the ACL action called "purge". Basically if a request to
# PURGE the cache comes from anywhere other than localhost, ignore it.
if (req.request == "PURGE")
{if (!client.ip ~ purge)
{error 405 "Not allowed.";}
return (lookup);}
# Serve objects up to 2 minutes past their expiry if the backend
# is slow to respond.
set req.grace = 120s;
# Use our round-robin "inmesp_cluster" cluster for the backend.
# Use "inmesp_default" for one only backend
if (req.http.host ~ "^images.domain.com$")
{set req.backend = inmesp_default;}
else
{set req.backend = inmesp_cluster;}
## Cache based on file path - if it's in /images/, it probably
## doesn't change much.
if (req.request == "GET" && req.url ~ "^/PATH1|/PATH2") {
unset req.http.cookie;
return (lookup);}
else{return (pass);}
## If your app has a less predictable layout - you can instead
## cache based on file extension - be sure to update vcl_fetch
## if you use this method.
#if (req.request == "GET" && req.url~ "\.(gif|jpg|jpeg|png|tiff|tif|ico)$") {
# unset req.http.cookie;
# return (lookup);
#}
return (lookup);
}
# Called if the cache has a copy of the page.
sub vcl_hit {
if (req.request == "PURGE")
{purge_url(req.url);
error 200 "Purged";}
}
# Called if the cache does not have a copy of the page.
sub vcl_miss {
if (req.request == "PURGE")
{error 200 "Not in cache";}
}
# Called after a document has been successfully retrieved from the backend.
sub vcl_fetch {
# set minimum timeouts to auto-discard stored objects
set beresp.grace = 120s;
if (req.request == "GET" && req.url ~ "^/inmogeo|/inmesp" ) {
unset beresp.http.Set-cookie;
set beresp.http.X-Cacheable = "YES";
set beresp.cacheable = true;}
## How to cache things longer on Varnish than on the client
if (beresp.cacheable) {
# Remove Expires from backend, it's not long enough
unset beresp.http.expires;
# Set the clients TTL on this object
set beresp.http.cache-control = "max-age = 2592000";
# Set how long Varnish will kepp it
set beresp.ttl = 1w;
# marker for vcl_deliver to reset Age:
set beresp.http.magicmarker = "1";
return (deliver);
}
#if (req.request == "GET" &&
# req.url ~ "\.(gif|jpg|jpeg|png|tiff|tif|ico)$" ) {
# unset beresp.http.set-cookie;
# set beresp.http.X-Cacheable = "YES";
# set beresp.cacheable = true;
# return (deliver);
# }
## Don't cache anything that is not a 20x response. We don't want
## to cache errors. If you want to cache redirects, you
## can set this to be higher than 300 (temporary redirects are 302)
if (beresp.status >= 300) {
return (pass);
}
## if varnish thinks it's not cachable, don't cache it.
if (!beresp.cacheable) {
return (pass);
}
return (pass);
}
sub vcl_deliver {
## Add cache hit data
if (obj.hits > 0) {
#if hit add hit count
set resp.http.X-Cache = "HIT";
set resp.http.X-Cache-Hits = obj.hits;}
else {
set resp.http.X-Cache = "MISS";}
## How to cache things longer on Varnish than on the client
if (resp.http.magicmarker) {
# Remove the magic marker
unset resp.http.magicmarker;
# By definition we have a fresh object
set resp.http.age = "0";
set resp.http.X-Age = resp.http.Age;
unset resp.http.Age;
unset resp.http.Server;
unset resp.http.X-Served-By;
set resp.http.X-Served-By = "proxy01";}
}
# Called if the cache has a copy of the page.
sub vcl_hit {
if (req.request == "PURGE")
{purge_url(req.url);
error 200 "Purged";}
if (!obj.cacheable) {
return(pass);}
}
En otro momento explicare que significa cada configuración que hemos realizado, aunque no tiene mucha complicación. ()
Fichero secret, en este fichero tenemos que poner la contraseña para poder acceder al Varnish desde consola
[#] vi /etc/Varnish/secret
Tuning Varnish
Vamos a realizar unas modificaciones para el Varnish.
[#] vi /etc/sysctl.conf
net.ipv4.ip_local_port_range = 1024 65536
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
net.ipv4.tcp_fin_timeout = 3
net.ipv4.tcp_tw_recycle = 1
net.core.netdev_max_backlog = 30000
net.ipv4.tcp_no_metrics_save=1
net.core.somaxconn = 262144
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
fs.file-max = 131072
vm.swappiness = 0
# Keep Alive
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 5
Hay que añadir estos límites para el usuario Varnish
[#] /etc/security/limits.conf
@varnish soft nofile 131072
@varnish hard nofile 131072
@varnish soft memlock 400000
@varnish hard memlock 400000
Como ya habíamos modificado, la partición para la cache de objetos la tenemos en ext4 y noatime y nodiratime.
1 comentario:
Muy buen aporte!
Gracias!
Publicar un comentario