Construyendo entornos de hosting
Me he encontrado una charla del grupo de usuarios de Ruby de San Diego que no la he visto enlazada en ninguno de mis blogs habituales (aunque puede ser que no estuviera mirando). La charla trata sobre construir sistemas de hosting para aplicaciones Ruby (aunque hay mucho aplicable a otro tipo de aplicaciones, por supuesto), desde el hardware hasta el software (la segunda parte sigue siendo muy interesante para hosting gestionado).
El video de la charla está disponible y el ponente ha recopilado enlaces y las transparencias.
Tras el salto, mis notas (en horrible español técnico y con enlaces).
Un servidor no es un ordenador de escritorio: necesita ser durable, mantenible y escalable.
DEBES utilizar RAID hardware. Una de las ventajas más grandes del RAID harware es la caché protegida por la batería (las escrituras pendientes no se pierden debido a un fallo de corriente). El RAID hardware permite además hacer write-back en vez de write-through. La diferencia entre los dos es escribir a la velocidad de la memoria frente a escribir a la velocidad del disco. También necesitas discos que se puedan cambiar “en caliente”. Si pierdes un disco no quieres tener que parar el servidor para sustituirlo.
DEBES tener una consola de gestión remota REAL (no se refiere a SSH o similares). Necesitas algo que se ejecute cuando el sistema operativo no se está ejecutando. Algo como Dell OpenManage.
DEBES tener fuentes de alimentación redundantes. Las fuentes de alimentación contienen piezas físicas, que, como los discos duros, pueden fallar. También es recomendable utilizar diferentes circuitos para las diferentes fuentes de alimentación.
NECESITAS una CPU para servidores, no para escritorios. Buena cache L2 (de segundo nivel) y gran ancho de banda para memoria. Actualmente, para servidores, Nehalem son los procesadores a instalar. Cuentan con controlador de memoria en el chip, pero no se debe llenar los canales de memoria con DIMMs porque cada uno ralentiza el canal.
Para sistema operativo no hay discusión: una distribución de Linux con soporte a largo plazo (LTS, long term support). Dos posibilidades: Red Hat Enterprise Linux (publicada en el 2007 y con soporte hasta el 2014) o Ubuntu Server LTS (publicada en el 2008 y soportada hasta el 2013). La idea es que nunca se necesita actualizar el sistema operativo de un servidor una vez instalado, únicamente aplicar las actualizaciones de seguridad.
NO instales una distribución al completo (nada de XWindows en un servidor). Instala únicamente lo que necesites. Paquetes extra significa bugs extras, problemas de seguridad extra y trabajo de mantenimiento extra.
Utiliza gestión de volumenes lógicos (LVM, Logical Volume Management), de forma que puedas añadir más discos duros físicos sin tener que crear nuevas particiones e incluyendo el nuevo espacio en las particiones ya existentes.
Utiliza ext3 como sistema de ficheros: muchos más usuarios significa que los problemas que puedas llegar a tener pueden haber sido resueltos antes. Utiliza la opción noatime cuando montes particiones, de otra forma cada lectura del disco significa una escritura para el tiempo de acceso, lo que empeorará el ancho de banda del disco y envenenará la cache.
Utiliza /etc/hosts y no dependas en el DNS. Todos los servidores (bases de datos, ficheros,…) deben poder ser resueltos sin necesidad de utilizar DNS.
Utiliza iptables incluso si tienes más líneas de defensa (como firewalls hardware) o tu servidor no esta directamente conectado a Internet.
Redirige el correo electrónico del root a un correo real. Muchos programas envian correos a root, sin la redirección los correos podrían perderse durante meses o años.
Utiliza Chef.
Para desplegar aplicaciones utiliza Apache y Passenger. La configuración del host virtual de Apache y la configuración de Passenger deben estar en archivos diferentes. Activa el GlobalQueue de Passenger (esta opción utiliza una única cola, en vez de una cola por worker, mejorando el rendimiento en el caso de peticiones largas). Modifica MaxPoolSize dependiendo de cada servidor y cada aplicación: aumentalo hasta que el servidor empiece a necesitar swapping. Establece el PoolIdleTime a 0 para que los worker no se desactiven cuando esté “ociosos” (y vigila que no existan leaks por procesos de larga duración).
En vez de utilizar el Ruby proporcionado por la distribución utiliza Ruby Enterprise Edition. La principal ventaja es un recolector de basura configurable. Evan Weaver tiene un buen wrapper optimizado para procesos de larga duración.
Comprueba tus backups (restaura desde el backup para comprobarlo). El único backup en el que puedes confiar es el que hayas comprobado que funciona más recientemente. Si no puedes permitirte perder una semana de datos, comprueba tus backups cada semana.
NECESITAS Gigabit para tu red interna, incluso si tu upstream no dispone de esa velocidad (lo más probable). Lo que pretendes es reducir la latencia dentro de tu red (cuanto más ancho de banda, menos tardará el servidor de bases de datos en proporciona la información al servidor de aplicaciones). Hay soluciones baratas por unos $100 (Linksys). El control de flujo (flow control) evita problemas cuando tu red Gigabit se encuentra con tu red Megabit (problemas de packet dropping).
Monitoriza. Dos tipos: disponibilidad y eficiencia. Nagios es código abierto. Pingdom es barato ($10/mes, con push notifications para el iPhone). Tiene la ventaja de ejecutarse en una red diferente a la tuya y comprobar la disponibilidad “al mundo” de tu aplicación. New Relic RPM tiene versión gratuita y versión de pago (cara), pero es muy buena herramienta.
¿Por qué no Nginx?
Es menos estable y “peor” soportado. Frente a Apache, Nginx sirve con mucho menos gasto de CPU contenido estático, pero si el problema es este, posiblemente deberías estar sirviendo el contenido estático desde Amazon S3.
¿Capistrano sí o Capistrano no?
Capistrano no es abandonware pero si doneware y posiblemente no se actualice. Se debe utilizar un sistema de despliege automatizado mediante scripts. Capistrano sigue siendo una opción muy buena, pero no es la única y existen muchas alternativas.
¿Seguridad e iptables?
Sí es la última línea de defensa y tienes firewalls hardware delante, trata de hacerlo simple: cierra todos los puertos, abre HTTP, abre SSH para algunos rangos, y cosas como DNS… Si no puedes restringir SSH a ciertos rangos, limita el número de conexiones desde una subred para evitar ataques de diccionario.
¿No es el controlador RAID un punto de fallo único?
Sí, es un punto de fallo único (single point of failure). Si necesitas evitar esto, será necesario un NAS o similar.
¿Se debe utilizar Monit o God?
No es necesario para Passenger, pero es necesario para cosas como BackgroundJob, Workling,… También es necesario rotar los archivos de registro (log), de otra forma crecerán hasta llenar el disco duro y harán fallar al servidor. Haz que el servidor no requiera intervención humana.
¿Se debe aplicar todo esto a hostings gestionados?
La parte de hardware es irrelevante, pero se debe aplicar la parte de software siempre que se pueda. Mantén tus propios backups, a pesar de que el hosting realice backups de tus datos. Para tu propio servidor no utilices virtualización, proporciona mucha flexibilidad, pero el precio en eficiencia no lo vale.
¿Se debe compilar desde código fuente?
Utiliza siempre que puedas soluciones estándares proporcionadas con la distribución. Compila desde código únicamente cuando sea necesario (Ruby Enterprise Edition, versiones modernas de Git). Deberias “paquetizar” tus productos para desplegar nuevos servidor más rápido y más estandarizadamente. Muchas veces puedes elegir paquetes de la distribución más moderna y re-compilarlos tu mismo para una versión anterior.
¿Por qué Long Term Support?
Quieres construir el servidor, lanzar tu producto, y no volver a tocar el servidor de nuevo.
¿Se debería utilizar JRuby?
En principio no. No es tan estándar y tan utilizado como el Ruby de Matz. Además consume más memoria. En la práctica no es competición para Ruby en entornos de producción.

