Escalabilidad Web - Fundamentos
Gustavo Picón <
[email protected]>
Noviembre 2007
Escalabilidad
● Escalabilidad es aumentar la capacidad de
atender usuarios o volumen de datos de
manera lineal con la capacidad de cómputo
añadida.
● Escalabilidad vertical: hacia arriba, “upgrades”
a cada nodo
● Escalabilidad horizontal (hacia fuera): aumentar
el número de nodos
Performance
● Escalabilidad no es performance
● Performance puede ayudar a escalabilidad
● Escalabilidad puede dañar performance
individual
● Encontrar balance y costos
Tecnología y Arquitectura
● No mitos “sólo se puede escalar con
Java” (JA!)
● “PHP/Python/Ruby no escalan” (JA!)
● La escalabilidad depende del diseño de la
arquitectura, NO de la tecnología utilizada
Qué nos debemos preguntar?
● “Qué tan rápidos somos?”
● NO. Esto es performance.
● “Si duplicamos el número de servidores, somos
el doble de rápidos?”
● SI. Esto es escalabilidad.
● No: “qué tan rápido”, Si: “cuántos”
● Load testing
● Probar con “clientes lentos”
Escalar verticalmente
● Reemplazar el servidor por uno mas grande
● Usar CPUs mas rápidos
● Un servidor que es el doble de rápido cuesta
bastante mas que el doble.
● Las super computadoras no escalan así ;-)
Escalar horizontalmente
● Agregar servidores (1, 10, 100, 1000)
● Barato
● Depende de la red (gigabit, 10GB, Infiniband)
● Que podemos tener gratis: redundancia (HA!)
● Ojo: escalabilidad NO ES alta disponibilidad
● Pero se intersecan.
● Eliminar SPFs! (escalabilidad+HA+seguridad)
Shared Nothing (SN)
● Cada nodo es independiente y auto-suficiente
● Eliminar SPFs
● Storage separado
● DB separada de web server farm
● Caching! Memcached servers.
● Sesiones
Sesiones
● Una de las principales claves para escalar
● Nunca almacenarlas en el servidor.
● Nunca
● En serio, nunca. Jamás.
● Esto ayuda a escalar y es mas seguro
Caching
● La mejor performance: páginas estáticas
● Generarlas offline
● No funciona con MILLONES de páginas o
muchas variaciones
● A nivel de aplicación
● Muchas desventajas
● No se puede usar con no-html (apis)
Caching bloques de HTML
● Hacer cache de bloques de html pre-generado
● Ensamblar la página resultante por request
● Desventajas: Poco control, no se puede usar
con no-html (APIs)
Cache de datos
● Hacer cache de datos que son CAROS de
obtener de la base de datos (JOINs, SPs,
COUNT(), etc), o que requieren cálculo del
servidor
● Generar página de los datos del cache
● Ventaja: se puede usar con contenido no-html
(APIs)
● Aliviamos a las Bases de Datos (sus DBAs los
amarán)
● Evitar tocar la BD
Estrategias de caching
● Cache HIT
● Cache MISS
● Conocer los hábitos de datos de la aplicación
● Revisar los logs de la BD (para saber que
queries siguen llegando)
● Cache de toda la BD
● La BD se convierte en solo escritura (como
Perl)
● Complicado en caching: expirar
Cuando expira el caching
● Pedimos un dato X
● Buscamos en cache (no está, cache MISS)
● Consultamos por X en la BD
● Almacenamos X en el cache por N minutos
● Retornamos X
● Pedimos un dato X
● Buscamos en cache (si está, cache HIT)
● Retornamos X
Stampeding
● Algoritmo anterior funciona solo con poca
concurrencia
● Si una clave expira, y un query demora Y
segundos para una concurrencia de Z
usuarios/s, corremos el riesgo de Y*Z queries a
la BD en unos pocos segundos
● Pésima performance, matamos lentamente a la
BD
● Stampeding (estampidas)
● Locks, sleep, trabajoso pero necesario
Mejor: no expirar nunca el cache
● Pedimos un dato X, siempre esta en cache
(100% HIT)
● Al modificar X:
● Actualizamos la BD
● Inmediatamente actualizamos el cache (que
nunca expira)
● Complicado, no hay nada out-of-the-box que
haga esto
● Fallback: leer de la BD y almacenar en cache
Memcached
● We love LiveJournal
● Usuarios: wikipedia, slashdot, digg, facebook,
livejournal, etc
● Storage = RAM
● Event based (no procesos/threads)
● Basado en nodos, fácil de hacer “granjas”
● APIs en multitud de lenguajes
Base de Datos
● Lo mas complicado de hacer escalar
● El SPOF mas común
● DISTRIBUIR
● Spindles, discos, nodos (RAID, network RAID)
● Agregar multimaster/esclavos ayuda a
escalar... hasta un límite.
● Solo se distribuyen lecturas, no escrituras
● Problema clásico al crecer: Las BDs estan
escribiendo todo el tiempo
Particionar los datos
● 1er paso: denormalizar
● “La normalización es para nenitas” - Cal
Henderson
● 2do paso: sharding
● “La integridad referencial es para nenitas” -
tabo
● Dividir bloques de datos por DB server
● Por roles que nunca harán joins
● O hacer joins en la aplicación
Denormalizar aun más
● Tablas resúmen
– GROUP BY
– COUNT
● Bases de datos resúmen
– para búsquedas (full-text search)
– índices de datos particionados
Stored Procedures?
● NO
● No escalan horizontalmente
● Trabajo en la BD? (cuento de vendors)
● Trabajo en el APP server!
● Solo en casos críticos (no hay que ser
dogmáticos tampoco)
Almacenamiento Estático
● Almacenar BLOBs en la BD merece
fusilamiento
● A menos que trabajes para Google
● Usar el filesystem (muy eficiente en linux/bsd)
● Metadata en la BD
● Amazon S3, Joyent Bingodisk
Servidor Web?
● Apache con módulos = pesado
● Memoria límite
● Agregar mas servidores = bueno, pero ahorrar
también
● Lighttpd
● FastCGI
● (nginx, scgi)
● Apache tambien soporta fastcgi
● Lighttpd/nginx para contenido estático
Clientes Lentos
● Proxy Reverso
● Caching no deseable (squid)
● Perlbal
● Perlbal tambien hace balanceo de carga! (we
love LiveJournal)
Buenas prácticas
● Unicode (UTF-8)
● Backups
● Subversion (SVN)
● Configuración en SVN
● Scripts para deployment
● Logs de BD (binarios), para desaster recovery
● Log queries/páginas lentas
Use the source Luke
Comentarios de: Escalabilidad Web - Fundamentos (0)
No hay comentarios