[Solar-general] Como montamos Meneame en Amazon EC2
Pablo Manuel Rizzo
info en pablorizzo.com
Dom Ene 10 18:58:37 CET 2010
No recuerdo si esto circuló por aquà o no, yo lo leà ahora y está muy
interesante.Esto es muy técnico, asà que disculpen. Aunque también tiene
información de costos que les puede interesar a quienes no sean técnicos
informáticos. Saludos!
______________
Cómo montamos Menéame en Amazon EC2La primera vez que alquilamos servidores
dedicados para Menéame fue en ThePlanet.com. Aunque funcionaba muy bien y no
tuvimos problemas decidimos traerlos a España para mejorar el ping y apostar
por hosting español. Asà nos fuimos a Ferca, que nos atendieron muy bien y
no tuvimos problemas hasta que fueron absorbidos por Acens. Allà cambió, a
peor, con caidas frecuentes de la red, problemas con sus firewalls que
bloqueaban conexiones, desaparición del servicio de emergencias,
imposibilidad de ver nuestras estadÃsticas… y lo que colmó nuestra paciencia
es que a pesar que nos cobraron religiosamente los meses de noviembre y
diciembre no nos enviaron las facturas (aún esperamos respuesta).
El tema del hosting suele ser un dolor de cabeza, y si además necesitas una
arquitectura sofisticada, o escalable debes sacar el talonario y prepararte
a gastar dinero que desde mi punto de vista no tiene justificación.
Comollevaba probando y “jugando†con Amazon EC2 desde hace
tiempo<http://gallir.wordpress.com/2008/01/09/probando-amazon-ec2-es-todo-gnulinux-con-xen/>decidÃ
hacer pruebas. Después de horas de cálculadora y viendo que nos
costarÃa sólo un poco más que Acens (pero menos que otras ofertas que
recibimos) pero nos darÃa mucha más flexibilidad y fiabilidad decidimos
hacer la migración.
La arquitectura básica es la que se muestra en la siguiente imagen (prohido
reirse de mi dibujo a mano con la mejor voluntad y dedicación):
<http://gallir.files.wordpress.com/2009/12/escanear0001a.jpg>
*Actualización*: *Britxardo* me envió un par de *parches* con los esquemas:
<http://gallir.files.wordpress.com/2009/12/meneame-in-ec2-before.png>
*Tenemos dos servidores (instancias) permanentes, aws0 y aws1*, y un *número
variable de instancia*s que sólo atienden a las peticiones web. Todos los
servidores ejecutan Ubuntu Karmic, de las imágenes (AMI) oficiales de Ubuntu
para EC2.
El kernel que se ejecuta en cada instancia debe ser compatible con el
“anfitrión†de Amazon, Canonical tiene un convenio con Amazon para validar
su kernel, que son mucho más modernos que otras distribuciones (estas
imágenes –AMI– se encuentran en “Community AMIs†de EC2). También nos
interesaba Ubuntu Karmic porque en la migración cambiarÃamos el tipo de
motor de la base de datos a MyISAM a InnoDB y la versión de InnoDB del MySQL
5.1 está muy mejorada con respecto a la 5.0 de la última Ubuntu LTS (08.04).
Servidor principal: aws0
Es el “servidor centralâ€, del tamaño *large* (m1.large) de 64 bits, cuesta $
0.38 por hora, con 7.5GB de RAM y además la imagen está montada y arranca de
un EBS (*Elastic Block Service*, un “disco persistente†con mejor
rendimiento). Además de las ventajas obvias de persistencia de datos permite
que en cualquier momento detengamos la instancia y la volvamos a iniciar con
otros parámetros, por ejemplo más CPU y memoria RAM.
Los servicios que da este servidor son:
- Servidor MySQL: Aprovechando la migración hemos pasado a usar InnoDB y
usar las transacciones/commit donde más hacÃan falta.
- Servidor NIS y NFS: Todo el software del Menéame y las cuentas de
usuario están exportadas por NFS que son usadas por aws1 y las instancias
web. Para centralizar la gestión de cuentas usamos el NIS.
- Servidor principal DNS: Es el primario de la zona meneame.net y
notame.net.
- Servidor memcache: Usado por todas las instancias web.
- Servidor SVN para la gestión del software.
- Servidor SSH
- Servidor SMTP: Recibe todos los correos desde las otras instancias.
Debido a las restricciones de Amazon EC2 para el correo saliente, todos los
correos lo enviamos vÃa AuthSMTP (más adelante lo explicamos)
TenÃamos muchas dudas de cómo se iba a comportar con carga real a la base de
datos, y estamos gratamente sorprendidos, durante el funcionamiento normal
no supera el 50% de uso de la CPU como se puede ver en la imagen (los picos
de madrugadas son por el cálculo del karma y otras tareas como generación de
“summariesâ€)
<http://gallir.files.wordpress.com/2009/12/aws0-stats.png>
Mysql
Es fundamental la configuración mÃnimamente correcta del servidor MySQL, en
caso de InnoDB es muy crÃtico el tamaño del buffer, como tenemos un total de
7.5 GB le asignamos 5 GB de RAM.
[mysqld]
default-character-set=utf8
server-id=1
set-variable=max_connections=1000
set-variable=query_cache_wlock_invalidate=True
table_cache=1024
innodb_buffer_pool_size = 5G
innodb_flush_method = O_DIRECT
innodb_flush_log_at_trx_commit = 0
innodb_additional_mem_pool_size = 16M
innodb_log_buffer_size = 8M
innodb_file_per_table = True
join_buffer_size = 1M
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 2M
thread_cache_size = 64
thread_concurrency = 8
query_cache_size = 96M
query_cache_limit = 16K
query_cache_type = 2
tmp_table_size = 64M
max_heap_table_size = 64M
wait_timeout = 60
Servidor secundario y de backups: aws1
Esta es una instancia *m1.small*, de 32 bits, cuesta $0.095 por hora, con
1.7 GB de RAM, un sistema raiz de 10 GB y otro adicional (en /mnt) de 150 GB
(ninguno de los dos es persistente)
- Secundario DNS
- Réplica en tiempo real de la base de datos (*slave*)
- Sphinx para las búsquedas
Esta instancia ya la tenÃamos funcionando desde noviembre como secundario
DNS, ahora simplemente la reaprovechamos para hacer más cosas. Las
fundamental es la réplica en tiempo real de la base de datos, que nos sirve
para hacer backups a discreción sin afectar al servicio web, también lo
usamos para muchos scripts de control que son “pesados†en consultas (en
MyISAM era imprescindible hacerlo asà porque bloquea todos los updates, con
el InnoDB ya no se nota, de todas formas seguimo usando el *slave* para
estas tareas).
También estamos usando (no acabamos de configurar todo) el
S3Sync<http://s3sync.net/>para hacer backups diarios a S3. El S3Sync
emula de alguna forma el
tradicional rsync, pero para trabajar sobre el sistema de S3.
<http://gallir.files.wordpress.com/2009/12/aws1-stats.png>
Réplicas con balanceo de carga y escalado automático
Decidimos poner todo el servicio web en un sistema que se autoescale
automáticamente, no sólo por la cuestión de precios sino por la tranquilidad
que en momentos de mucha carga no habrá problemas de saturación (como nos
ocurrió durante la Eurocopa, que tuvimos que montar un servidor adicional en
EC<http://blog.meneame.net/2008/06/26/novedads-votos-a-comentarios-anotaciones-calculo-del-karma-promote-amazon-ec2-y-futbol/>2,
pero al hacer réplica en EEUU de un servidor en España no iba muy fino por
las enormes latencias).
La decisión fue poner todos los servicios web en una misma imagen:
- Apache con PHP para HTTP y HTTPS (puerto 80 y 443)
- Lighttpd para los ficheros estáticos (puerto 81)
Desde hace tiempo usamos mnmstatic.net como dominio para los ficheros
estáticos, esto mejora la carga desde el navegador y evita que el navegador
envÃe los cookies de meneame.net [*] cada vez que se baja una imagen, en las
pruebas que habÃamos hecho *se ahorra hasta 14KB de tráfico de subida* en
cada página.
[*] No son sólo los nuestros, que son sólo dos, sino también todos los que
definen vÃa javascript los medidores como Google Analytics, podéis
verificarlo en vuestros navegadores.
Cada instancia al arrancarse monta por NFS el directorio donde tiene acceso
a todo el software y las imágenes (estáticas y dinámicas). Esto se hace el
el fstab, pero hay que tener cuidado con las opciones, fundamentalmente la
opción *bg* para que que bloqueada al arranque, y otras para aumentar la
eficiencia y tolerancia a errores.
# /etc/fstab: static file system information.
proc /proc proc defaults 0 0
/dev/sda3 None swap defaults 0 0
/dev/sda1 / ext3 defaults 0 0
/dev/sda2 /mnt ext3 defaults 0 0
x.x.x.amazonaws.com:/home /home nfs
rw,bg,noatime,soft,nolock,intr,async,nodev,nocto,ac,actimeo=15 0 0
Balanceo (*Load Balancer*)
Como tenemos que balancear del puerto 80 dos tráficos diferentes (al Apache
y al Lighttpd) tuvimos que definir dos baleanceadores diferentes
(web-balancer y static-balancer). Cada balanceador te da una dirección IP y
nombre DNS. Uno de los balanceadores –web-balancer– redirecciona a los
puertos 80 y 443 y el otro –static-balancer– redirecciona del puerto 80 al
81 del lighttpd.
<http://gallir.files.wordpress.com/2009/12/load-balancers.png>
Para cada una de las réplicas elegimos primero el tamaño pequeño (*m1.small*),
pero el primer dÃa de funcionamiento (el lunes) y a pesar que durante las
fiestas el tráfico es bastante menor que lo habitual vimos que el *
AutoScaler** creaba cinco instancias para poder atender a la demanda, y
durante las horas de menor tráfico no bajaba de dos*. Me soprendió bastante,
no esperaba que el consumo del Apache fuese tan elevado.
Me puse a estudiar y comparar con el vmstat, và que las estadÃsticas del
monitor de EC2 (*CloudWatch*) no se correspondÃan con estas. Investigando
más me di cuenta del problema, el vmstat –al menos con el kernel de Ubuntu–
no toma en cuenta la “capacidad†real de CPU asignada sino la del
procesador. La asignada es un 40% de la total de la CPU (fácil de
comprobar, se pone un proceso que consuma el 100% de cpu –por ejemplo *yes >
/dev/null*– y se mira la columna idle del vmstat, en este caso el idle
indicaba 60%).
Entonces tenÃa que buscar una solución más barata, y encontré una solución
muy buena, bonita, potente y barata, *usar una instancia orientada a CPU
para el Apache.* EC2 ofrece este tipo de instancias, las *High-CPU Instances
*. Con la *c1.medium* y por sólo el doble de precio ($0.19/hora) podÃa tener
una máquina con la misma memoria y algo menos de prioridad de E/S (que es
muy poca, sólo los logs del Apache) pero con 5 veces la capacidad de CPU.
Asà que reconfiguré el *AutoScaler* para que cree las instancias del tipo *
c1.medium* y problema solucionado: desde que lo pusimos en marcha no ha
creado ninguna instancia adicional, nunca superó al 80% de CPU:
<http://gallir.files.wordpress.com/2009/12/web-stats.png>
*AutoScaler*
La configuración del escalador automático es casi lo último que se hace,
necesitas tener definido los balanceadores y la imagen (AMI) que se usará
para arrancar las réplicas. A diferencia de lo anterior, que se puede crear
y modificar con la consola web del Amazon AWS, todavÃa no existe esa opción
para el *AutoScaler* (aunque seguro que la agregan en las próximas semanas).
Por ahora toca hacer con los scripts, se necesitan definir tres cosas que
están mostradas en el código de abajo:
# Crea la configuración para lanzar las instancias
as-create-launch-config web01cpu --image-id ami-ami-d3fad1a7
--instance-type m1.small
--group default,www
# Define el grupo de autoscale llamado web-group
# Se "conecta" a los dos balanceadores
# Después de tomar una decisión no hace nada durante 180 segundos
as-create-auto-scaling-group web-group --launch-configuration web01cpu
--availability-zones eu-west-1a --min-size 1 --max-size 6 --load-balancers
web-balancer,static-balancer --cooldown 180
# Define los parámetros para crear o destruir
# Crea cuando consume más del 80% de cpu durante dos minutos
# Destruye cuando baja del 30%
as-create-or-update-trigger web-trigger --auto-scaling-group web-group
--namespace "AWS/EC2" --measure CPUUtilization --statistic Average
--dimensions "AutoScalingGroupName=web-group" --period 60 --lower-threshold
30 --upper-threshold 80 --lower-breach-increment=-1 --upper-breach-increment
1 --breach-duration 120
Con todo lo comentado anteriormente, esta es la situación habitual de
funcionamiento del Menéame:
<http://gallir.files.wordpress.com/2009/12/estado-normal-instancias.png>
Para mostrar el funcionamiento del escalador puse la CPU de la instancia web
al 100% (ejecutando dos *yes > /dev/null* para poner al 100% cada una de las
CPU) para obligar a crear otra instancia.
Aquà se puede ver como el *trigger* indica *HighBreaching*, es decir que se
superó el lÃmite superior
$ as-describe-triggers web-group --headers
TRIGGER TRIGGER-NAME GROUP STATUS NAMESPACE MEASURE
STATISTIC PERIOD
TRIGGER web-trigger web-group HighBreaching AWS/EC2 CPUUtilization
Average 60
Aquà se oberva como la “capacidad deseada†es de 2 y que inició la creación
y arranque de una nueva instancia:
$ as-describe-auto-scaling-groups web-group --headers
AUTO-SCALING-GROUP GROUP-NAME LAUNCH-CONFIG AVAILABILITY-ZONES
LOAD-BALANCERS MIN-SIZE MAX-SIZE DESIRED-CAPACITY
AUTO-SCALING-GROUP web-group web01cpu eu-west-1a
static-balancer,web-balancer 1 6 2
INSTANCE INSTANCE-ID AUTO-SCALING-GROUP AVAILABILITY-ZONE STATE
INSTANCE i-04ef2c73 web-group eu-west-1a InService
INSTANCE i-4e7dbe39 web-group eu-west-1a Pending
Finalmente las dos instancias ya están activas y accesibles:
$ as-describe-auto-scaling-groups web-group --headers
AUTO-SCALING-GROUP GROUP-NAME LAUNCH-CONFIG AVAILABILITY-ZONES
LOAD-BALANCERS MIN-SIZE MAX-SIZE DESIRED-CAPACITY
AUTO-SCALING-GROUP web-group web01cpu eu-west-1a
static-balancer,web-balancer 1 6 2
INSTANCE INSTANCE-ID AUTO-SCALING-GROUP AVAILABILITY-ZONE STATE
INSTANCE i-04ef2c73 web-group eu-west-1a InService
INSTANCE i-4e7dbe39 web-group eu-west-1a InService
Asà es como se ve en la consola:
<http://gallir.files.wordpress.com/2009/12/escalado.png>
Problemas encontrados
Tuvimos dos problemas fundamentales.
HTTP SSL detrás del balanceador
El primero es que las instancias sólo “ven†la IP privada del balanceador y
envÃa una cabecera HTTP para indicar la original, esto no ocasionó gran
problema porque el software del Menéame ya estaba preparado. Pero con el SSL
(o HTTPS) la cosa es muy distinta, en estos caso la conexión entre el
balanceador y la instancia no es vÃa HTTP, sino TCP (por razones obvias, la
comunicación va cifrada) por lo que no se recibe nada de información de la
IP del cliente.
Esto obligó a modificaciones y agregar campos de control en los formularios
de registro y login vÃa el servidor
seguro<http://viewvc.meneame.net/index.cgi?view=rev&revision=2084>.
No fue nada importante, pero me obligó a pensar bastante en una solución
razonablemente segura (digo *razonable* porque seguro que se le pueden
encontrar problemas si se le dedica tiempo).
EnvÃo de correo por AuthSMTP
El segundo problema fue inesperado y el que nos retrasó la migración del dÃa
sábado al domingo. El viernes recibimos un email de Amazon indicándones que
estábamos enviando correo saliente (nuestras pruebas de envÃo de validación
de cuenta y recuperación de contraseña) y que nos iban a bloquear la salida.
Además vimos* que agregan automáticamente nuestras **IPs al
Spamhause*<http://www.spamhaus.org/pbl/query/PBL346296>
.
Aunque te envÃan el URL de un formulario para pedir la autorización decÃan
que hay que esperar por lo menos dos dÃas hábiles (hoy nos enviaron un email
diciendo que ya estudiaron el caso y nos autorizan, pero las IPs siguen
apareciendo en Spamhause). Fue un momento de *depresión*, además và que es
un problema en Amazon por las medidas que tomaron para evitar *spammers* en
su servicio.
Pero encontré una solución buena, bonita y barata:
AuthSMTP<http://www.authsmtp.com/>
.
Por un precio muy razonable ellos se encargan de enviar el correo de tus
usuarios o todo el dominio. Funciona muy bien y muy rápido, te olvidas del
problema que las IPs de tus servidores de correo aparezcas en esas
demonÃacas bases de datos de spammers.
En nuestro caso la configuración del Postfix de aws0 fue muy sencilla, sólo
tuvimos que agregar las siguientes lÃneas al main.cf:
relayhost = mail.authsmtp.com:2525
smtp_connection_cache_destinations = mail.authsmtp.com
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = static:USUARIO:PASSWORD
smtp_sasl_security_options = noanonymous
default_destination_concurrency_limit = 4
soft_bounce = yes
Con esto se solucionó el problema más grave que encontramos y pudimos hacer
la migración.
Costes mensuales
- 1 m1.large: $ 273
- 1 m1.small: $ 64.8
- 1, 2 instancias c1.medium web de media (máxima): $ 164.16
- 2 TB transferencia de datos: $ 340
- 1 EBS de 50GB almacenamiento + aproximadamente 50 Mops= $ 11
- 3 instancias medias medidas con Cloudwatch: $32.4
- 2 Balanceadores: $40.32 + $16 de 2 TB de tráfico, $56.32
Coste total estimado: $ 941.68, al cambio actual del euro queda *en 649 €
mensuales*
Fin
SÃ, se pueden encontrar ofertas más baratas, y es un poco más de lo que
pagamos a Acens (pero mucho menos que otras ofertas que recibimos), pero te
olvidas de estar atado por una arquitectura, de tener que hacer engorrosas y
largas negociaciones si necesitas un nuevo servidor, de abrir averÃas por la
red (en Amazon está todo monitorizado y es
público<http://status.aws.amazon.com/>,
una caÃda afecta a muchos servidores, asà que no tardan nada en resolver).
Y lo más importante, es el futuro, mucho más sofisticado, pero también más
divertido (y creo que además más ecológico, el hardware está mucho mejor
aprovechado) y como *administrador de sistemas/programador/CTO tienes una
libertad y flexibilidad impensable hace pocos años*.
Como conclusión, por ahora muy positivo. Ya veremos como evoluciona,
conociendo la historia de EC2 no dudo que agregarán cada vez más servicios y
que bajarán los precios una vez al año.
PS: Son las cinco de la mañana, lo publico como está, disculpad los errores
que haya, ya los corregiré luego.
http://gallir.wordpress.com/2009/12/30/como-montamos-meneame-en-amazon-ec2/
--
Pablo Manuel Rizzo
-------------------------------
http://pablorizzo.com
-------------------------------
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: /pipermail/solar-general/attachments/20100110/c6ce59cd/attachment.htm
Más información sobre la lista de distribución Solar-general