Avances tecnológicos del siglo XXI y ejemplos de estos
Marcos quesada caching_sf2
1. Caching en Symfony 2
Escalando aplicaciones web
Marcos Quesada
@marcos_quesada
2. About me
Code enthusiast & More ;)
Symfony 2 desde agosto 2011
Symfony BCN
marcos.quesadas@gmail.com
@marcos_quesada
es.linkedin.com/in/marcosquesada
3. Contenido de la presentación
Introducción
Cache Symfony 2
Varnish
Caching contenido estático + CDN
Transient Data
Arquitectura de escalado
Conclusiones
4. Introducción
Backend developer:donde almaceno los datos
Datos: strings, arrays, objects, HTML …
En dB / Static files …. o en memoria!
Cuando pensamos en cache
expiration&validation :
PERFORMANCE
Piensa en cold start:
cache Warmup & Low Hit Rates
Volumen datos Vs tiempo consumido
5. Performance
¿Cual va a ser nuestro volumen de páginas
vistas totales?
Planificación
Optimización
“The fastest HTTP request is the one not made.”
No resuelvas problemas que no tienes
Reducción del contenido a entregar
Análisis PageSpeed
Impacto directo con el coste de explotación
6. Metricas: localiza cuellos de botella
Monitoriza : Munin, Nagios ...
Profiling: XHProf
Pruebas de carga
Jmeter , Apache Benchmark ,httperf …
Identificando que cachear:
Datos con alta demanda
Caros de generar
Grandes en tamaño
Datos comunes
Trucos para encontrar datos cacheables
Monitor Queries
Output queries
Monitor Page Loads
Monitor Web Analytics
7. Introduction to HTTP Caching
Reverse HTTP proxy, a veces llamdo HTTP
accelerator o web accelerator
Cache-control
max-age
stale_while_revalidate
stale_if_error
Metricas
Cache hit Vs Cache miss
11. Symfony 2 cache
Symfony 2 es un framework con cache propia
¿Qué cache?
Definición de cache:
"A cache is a collection of data duplicating original values
stored elsewhere or computed earlier, where the original
data is expensive to fetch or to compute, compared to
the cost of reading the cache." (Wikipedia)
¿Que tipo de cache ?
Carpeta Cache ?
APC ?
Reverse Proxy Cache ?
14. Symfony 2 cache
Symfony2 incluye un reverse proxy escrito en PHP.
Otras denominaciones: Gateway caches ,reverse proxy
caches, surrogate caches, delegado inverso o HTTP
accelerators.
El sistema de cache de Symfony2 está basado en la
potencia y simplicidad del caching HTTP como define
su normativa RFC 2616
18. HttpFoundation Component
Object Oriented wrapper Server Globals Variables
SymfonyComponentHttpFoundationResponse
Colección de métodos para manipular las cabeceras HTTP del
Objeto Response
22. PURGE
La implementación del PURGE puede romper la compatibilidad con otros
Reverse Proxy Caches
Nunca debería ser necesario invalidar los datos almacenados en caché
porque la invalidación ya se tiene en cuenta de forma nativa en los
modelos de caché HTTP
Proteger el método PURGE de HTTP : restringe el acceso
23. Ventajas & Problemas
Truco debugar cache : error_log($kernel->getLog());
Cache:clear & cache:warmup
Clear sin fin
Imposible borrar app/cache
Multiples regeneraciones de cache en paralelo
stale_if_error
Deploys en producción complicados si hay mucho tráfico
Corte programado / Restricción de acceso
Alternativa: apc.stat = 0 , Pull & Clear Opcode cache
Purge total o parcial complicado
24. ESI
Habilita ESI , setea secciones como standalone
Esto permite varios TTLs en una misma página
Setea shared max age en responses y sections
Si se fija un max age como non-shared,toda la página queda cacheada,
ESI no funcionará:
$response->setSharedMaxAge(60)
25. ESI
Renders: symfony2 will create a subrequest for you,
call the widget and include the subresponse in your
masterresponse.
{% render 'MyBundle:Controller:widgetaction'
{'param1':'foo'} %}
Having every (sub)action represented as a request
makes ESI
{% render 'MyBundle:Controller:widgetaction'
{'param1':'foo'} with {'standalone':true} %}
27. ESI
app/config/config.yml
framework:
esi: { enabled: true }
{% render 'FooBundle:Bar:index' with {}, {'standalone': true} %}
Añadir la ruta (debe estar securizada)
# app/config/routing.yml
_internal:
resource:
"@FrameworkBundle/Resources/config/routing/internal.xml"
prefix: /_internal
28. Problemas
Debuggar ESI se vuelve complicado!
Enabling debugging with:
$framework = new HttpCache($framework, new Store(__DIR__.'/../cache'),
new ESI(), array('debug' => true)
);
The debug mode adds a X-Symfony-Cache header to each response that
describes what the cache layer did:
X-Symfony-Cache: GET /is_leap_year/2012: stale, invalid, store
X-Symfony-Cache: GET /is_leap_year/2012: fresh
29. Varnish
Reverse Proxy Cache
Escrito on C
Soporta ESI
Muy flexible y configurable (Varnish Configuration Language)
Almacena todo su contenido sobre la RAM: muy rápido
Muy altas prestaciones: Consumo de CPU relativamente bajo
Varnish puede consumir toda la RAM que le pongas,asegúrate que configuras
su max memory (por debajo de la RAM disponible)
30. Varnish
Varnish puede trabajar como Balanceador de Carga
Configurado contra multiples backends
Realiza Health-Checks en los web Servers
Número de Threads:
Varnish puede crear nuevos threads bajo demanda, y eliminarlos cuando
la carga total se reduce
Es perfecto para picos de tráfico
Una buena aproximación es mantener unos pocos threads idle durante el
tráfico regular, anticipando el incremento de tráfico en lugar de levantar
y destruir otros según cambia la demanda
En sistemas de 64-bit , el coste de tener unos cientos de threads extras es
muy limitado
31. Varnish Configuration Language
Configura cada request
Define:
Backends (web servers)
ACLs
Load balancing strategy
Can be reloaded while running
Tell Varnish to communicate with the content server (Nginx) on port 8080.
backend default {
.host = "127.0.0.1";
.port = "8080";
}
Unsetting Cookies:
sub vcl_recv {
unset req.http.cookie;
}
sub vcl_fetch {
unset beresp.http.set-cookie;
}
32. Varnish
Varnish- what can/cant't be cached?
Can:
Static Pages
Images,js,css
Static parts of pages that don't change often(ESI)
Can't
POST request
Very large files
Request with Set-Cookie !!!!
User-specific content
34. Real-time statistics Varnishtop
varnishtop -b -i TxURL
“-b” flag filters for requests made to the backend.
“-i TxURL” filters for the request URL that triggered
the request to the backend.
35. Real-time statistics : Varnishhist
Varnishhist shows a histogram for the past 1000 requests
36. Real-time statistics: varnishlog
varnishlog -c -o ReqStart
displays all varnish traffic for a specific client. It’s
helpful for seeing exactly what a particular page or
request is doing.
37. Real-time statistics :Varnishstat
Varnishstat is the tool used to monitor the basic health of Varnish. Unlike all the
other tools, it doesn’t read log entries, but counters that Varnish update in
real-time. It can be used to determine your request rate, memory
usage,thread usage, and just about anything that’s not related to a specific
request.
This command provides an overview of the stats for the current Varnish
instance. It shows hit/miss/pass rates and ratios, lots of other gory internal
details.
38. PURGE en Varnish
Varnish se puede configurar para aceptar un método HTTP especial PURGE
que invalida la caché para un determinado recurso:
acl purge {
"localhost";
"192.168.0.0/24";
}
sub vcl_recv {
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
return (lookup);
}
}
sub vcl_hit {
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not purged";
}
}
39. ESI on Varnish
# /etc/varnish/default.vcl
backend default {
.host = "127.0.0.1";
.port = "80";
}
sub vcl_recv {
set req.backend = default;
# Tell Symfony2 that varnish is there, supporting ESI
set req.http.Surrogate-Capability = "abc=ESI/1.0";
}
sub vcl_fetch {
# Enable ESI only if the backend responds with an ESI header
if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
unset beresp.http.Surrogate-Control;
// for Varnish >= 3.0
set beresp.do_esi = true;
// for Varnish < 3.0
// esi;
}
}
40. Varnish : problemas
Busca un setup estable:
“ The system worked great for a while, and then took a
nosedive as the Varnish cache ate up all the available RAM
and pushed the system into a swap death spiral.”
Cuidado con low hit rate (Usa ESI)
Riesgos de purgado
Cookies & sessions : planifica tu estrategia
43. CDN
Akamai:world's largest CDN serves about 20% of the web traffic using
over 100,000 servers located in over 1000 networks and over 70 countries
Amazon S3 + CloudFront
Ahorro de ancho de banda
45. Transient Data
Key => Value
APC
Memcached
Redis ...
La base de datos suele ser siempre el mayor
cuello de botella de performance en backend
Una capa de caching sobre la base de datos
resuelve de gran manera los problemas de
performance y escalabilidad
46. APC: PHP compilation
PHP Compilation
-scanning / lexing: plain text code turned in tokens
-parsing: tokens are collected into Expressions
-compilation: Expressions are translated into Opcodes for execution
-execution: Opcode stacks are processed, one at a time.
APC caches the Opcodes for later execution
50. APC tweaking
se recomienda: apc.stat=1 en desarrollo. Devolver a 0 en producción.
apc.shm_size: cuánta memoria va a ser asignada a APC
Como regla general,apc.shm_size debe ser el doble de la máxima
memoria utilizada por APC’s para evitar por completo la fragmentación
Vigilar Full Count: Se purga por quedarse sin espacio, si sube de 0 es probable
que surjan errores 500!
apc.user_ttl = 0: Sin limite TTL
Ejemplo configuración en php.ini:
extension=/usr/lib/php5/20090626/apc.so
apc.enabled = 1
apc.shm_size = 100M
apc.ttl = 0
apc.user_ttl = 0
apc.gc_ttl = 600
apc.stat = 1
52. Symfony 2 apc autoload
UniversalClassLoader:
the loader iterates over all configured namespaces to find a particular file, making
file_exists calls until it finally finds the file it's looking for.
ApcUniversalClassLoader( namespace )
Solution:cache on APC the location of each class after it's located the first time.
53. Memcached
Sistema distribuido de cacheo de objetos en memoria
Tecnicamente es un server
Client access sobre TCP or UDP: Fast asynchronous network I/O
Sistema escalable a multiples servers en forma de pools
Servers are independent, managed by clients
No redundacy or fail over! It's a cache!
No replication , no authentication …
No enumeration of keys
Sin mecanismo de clean-up
No tiene persistencia
54. Memcached
Offers built-in session handler
Giant “Hash table” or Array
Flujo:
Pool Memcached Servers
Assign values to keys that are stored in cluster
The client hashes the key to a particular machine in the cluster
Subsequent request for that key retrtive the value from the memcached
server on wich it was stored
Values time out after the specified TTL
Limites:
Key max 250 chars
Values Up to 1MB
55. Improving Memcached
Serialization
Si se usa memcached para almacenar datos complejos (array&objects),
necesitan ser serializados en strings
Consume recursos
Puede ser mejorado con igbinary
30% mas rápido
Produce datos mas compactos
hasta 45% menores con respecto
al serializador nativo PHP
http://github.com/phadej/igbinary
62. APC Vs Memcached
Aparte del Opcode, Cuando debemos usar
APC ?
Cuando los datos no sean distribuidos (único server)
Op Code + User cache ambos en APC == “all eggs in one basket”
Requests garantizados a una misma sesión ( sticly sessions)
file upload progress&sessions ( sticky sessions)
Es un componente PHP
Typical uses:
Application settings
Almacenar configuraciones
Caching de datos (db)
Data comunes para los usuarios
63. APC Vs Memcached
Cuando debemos usar memcached?
Cuando no está garantizado que las request vayan a una misma máquina
Datos específicos dirigidos al usuario
user sessions (Memcached Session Handler)
Habla diferentes lenguajes : PHP, Python, Ruby ,Java,Perl ...
Las instancias pueden ser compartidas en múltiples servers del pool
MAS LENTO APC, especialmente en array storage
69. Nginx
Stack alternativo a Apache
PHP-FPM
Soporte nativo de Memcached
Nginx maneja los rquest con una aproximación asynchronous event-driven
Le hace mas predecible en tiempo de respuesta Vs Apache
Alto rendimiento, consumo de memoria óptimo
Reload Gracely
Reverse Proxy Cache
Soporta ESI , aunque no es compatible al 100%
Escala muy bien , menos configurable que Varnish
70. Varnish Vs Nginx
Usa Nginx donde no se utilizan las plenas capacidades de Varnish (ESI
principalmente)
Si necesitas servir contenidos estáticos lo mas rápido posible, usa Nginx como
frontal
Si necesitas servir contenido dinámico con ESI , usa Varnish
Si usas CDN para contenido estático , la potencia de Nginx se vuelve menos
relevante
Por tanto
Nginx es claramente mas rápido que Varnish
Usamos Varnish por ESI
71. Conclusiones
Php 5.3 Vs php 5.4 :benchmarks & page-load 10-30% mas rápido.
Intercambia Apache por Nginx
Estudia tus necesidades para buscar tu configuración ideal
Soluciones Javascript (no bloqueantes) & Ajax
ESI te ayuda en Low Hit Caching rate (HTTP)
Soluciones de microcaching pueden ser suficientes
Ciclo de crecimiento
Mide – Mejora – vuelve a medir
Stress Test
Planifica tu deploy y tus subidas de código
Implementa mecanismos de Warmup
Usa tiempos de cache lo mas largo posible
http://symfony.com/doc/current/book/http_cache.html Step 1: A gateway cache, or reverse proxy, is an independent layer that sits in front of your application. The reverse proxy caches responses as they're returned from your application and answers requests with cached responses before they hit your application. Symfony2 provides its own reverse proxy, but any reverse proxy can be used. Step 2: HTTP cache headers are used to communicate with the gateway cache and any other caches between your application and the client. Symfony2 provides sensible defaults and a powerful interface for interacting with the cache headers. Step 3: HTTP expiration and validation are the two models used for determining whether cached content is fresh (can be reused from the cache) or stale (should be regenerated by the application). Step 4: Edge Side Includes (ESI) allow HTTP cache to be used to cache page fragments (even nested fragments) independently. With ESI, you can even cache an entire page for 60 minutes, but an embedded sidebar for only 5 minutes.
https://www.varnish-cache.org/docs/trunk/tutorial/esi.html Sub Request en renders (widgets)..., ESI http://100days.de/serendipity/archives/150-wetter.com-Relaunch-with-symfony2,-Assetic,-Varnish-and-Twig.html
http://www.slideshare.net/fabpot/caching-on-the-edge-with-symfony2 P 29
Cuando standalone es false (predeterminado), Symfony2 combina el contenido de la página incluida en la principal antes de enviar la respuesta al cliente. Pero cuando standalone es true, y si Symfony2 detecta que está hablando con una pasarela caché compatible con ESI, genera una etiqueta include ESI. Pero si no hay una pasarela caché o si no es compatible con ESI, Symfony2 termina fusionando el contenido de las páginas incluidas en la principal como lo habría hecho si standalone se hubiera establecido en false.
Basics http://www.ibm.com/developerworks/opensource/library/os-php-varnish/ http://kristianlyng.wordpress.com/2010/01/13/pushing-varnish-even-further/ Varnish - CPU Vs Memory - low cache hit rate What you can learn from this is actually simple: Do not focus on the CPU when you want to scale your Varnish setup. I know it’s tempting to buy the biggest baddest server around for a high-traffic site, but if your active data set can fit within physical memory and you have a 64-bit CPU, Varnish will thrive. And for the record: All CPU-usage graphs I’ve seen from Varnish installations confirm this. Most of the time, those sexy CPUs are just sitting idle regardless of traffic. About running all data set on mem & sync to disk as a rescue An otherimportant detail is that your shmlog shouldn’t trigger disk activity. On my setup, it didn’t sync to disk to begin with, but you may want to stick it on a tmpfs just to be sure. I suspect this has improved throughout the 2.0-series of Varnish, but it’s an easy insurance. Typically the shmlog is found in /usr/var/varnish, /usr/local/var/varnish or similar (“ls /proc/*/fd | grep _.vsl” is the lazy way to find it).
This command shows the most often-made requests to the backend: varnishtop -b -i TxURL It’s excellent for spotting often-requested items that are currently not being cached. The “-b” flag filters for requests made to the backend. “-i TxURL” filters for the request URL that triggered the request to the backend. Its output looks something like this:
This command displays all varnish traffic for a specific client. It’s helpful for seeing exactly what a particular page or request is doing. Set it to your workstation IP, load the page, see everything Varnish does with your connection including hit/miss/pass status. Varnishlog is really useful, but it puts out an overwhelmingly-large amount of data that isn’t easily filtered. The “-o” option groups all of the entries for a specific request together (without it all entries from all requests are displayed fifo) and it accepts a tag (“ReqStart” in this example) and regex (the IP address in this case) to filter for only requests associated with that tag & regex. It’s the only way I’ve found to filter down the firehose of log entries into something useful.
We did not want to use PHP sessions in this project as that would have been a major performance drawback. What we did instead: We implemented client side signed cookies as a C plugin in varnish (more about that in a separate post somewhen later). This way, varnish can cache the content for different user levels and distinguish between them without the need to invoke PHP
Conclusión http://engineering.emagister.com/2011/10/20/performance-tricks-para-apc/ Hay cosas que cuestan tan poco… 1. Aumentar el espacio de memoria para que el “Cache full count” sea 0. 2. Utilizad igbinary para acelerar el procese de serialización y deserialización (a parte lo podréis utilizar en código normal con igbinary_serialize y igbinary_unserialize, con sistemas de colas, por ejemplo). 3. Setead apc.stat a 0 en producción y forzar un reload o un flush del apc después de que algún fichero cambie (con una subida, por ejemplo) Material extra http://prezi.com/re8rsdjmpkko/oscon-09-high-performance-apc/ http://www.slideshare.net/vortexau/improving-php-application-performance-with-apc-presentation http://www.php.net/manual/en/apc.configuration.php http://talks.php.net/show/froscon08 http://phpolyk.wordpress.com/2011/08/28/igbinary-the-new-php-serializer/
When using the APC autoloader, if you add new classes, they will be found automatically and everything will work the same as before (i.e. no reason to &quot;clear&quot; the cache). However, if you change the location of a particular namespace or prefix, you'll need to flush your APC cache. Otherwise, the autoloader will still be looking at the old location for all classes inside that namespace.
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/ http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html Cache de DQL $config->setMetadataCacheImpl(newDoctrine\\Common\\Cache\\ApcCache()); Cache de resultados $config->setQueryCacheImpl(newDoctrine\\Common\\Cache\\ApcCache());
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/ http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html Cache de DQL $config->setMetadataCacheImpl(newDoctrine\\Common\\Cache\\ApcCache()); Cache de resultados $config->setQueryCacheImpl(newDoctrine\\Common\\Cache\\ApcCache());