Hace poco descubrí, en una charla de Drupal Madrid, que existía una herramienta llamada Vagrant que permitía mejorar con creces el funcionamiento de una máquina virtual en un entorno de desarrollo. Mapea puertos, carpetas, IPs, ... Y todo de forma totalmente transparente.
En la misma charla también se habló de otras dos herramientas que, integradas con Vagrant, permitían gestionar la configuración de todos los servicios de una máquina directamente a código fuente. Estas dos herramientas eran Chef y Puppet. Permiten tener un apache, un mysql, y una configuración de php específica en código fuente, lo que te permite reinstalar y reinstalar una y otra vez. Fuera de Vagrant sirve para sincronizar configuración de servidores. Con esto, si se rompe la máquina de desarrollo, la destruyes, y la inicias de nuevo, y en 10 minutos la tienes como nueva.
Esta charla comenzó un debate muy interesante y me llevó a plantearla en mi proyecto de fin de carrera y en una charla para la drupal camp de Cáceres de 2013 sobre la definición de un flujo de desarrollo en Drupal utilizando Vagrant Drupal Development.
Mal rendimiento en las carpetas compartidas entre Windows (host) y Ubuntu (guest)
Yendo más al tema, Vagrant en Windows como host y Ubuntu (por ejemplo) como guest tiene un problema de rendimiento en las carpetas compartidas bastante serio que viene heredado de Virtualbox o VMWare. Si el host es Linux o Mac no existe un problema tan crítico, aunque también tiene un rendimiento bajo. Para mostrarlo hagamos una extracción de drupal8, aprovechando que tiene muchos ficheros, recién bajado a /home/vagrant/rendimiento (sistema ext4) y a /var/www (shared folder) y comprobemos el tiempo en opciones de escritura y lectura sobre el sistema de ficheros:
vagrant@precise32:~/rendimiento$ pwd /home/vagrant/rendimiento vagrant@precise32:~/rendimiento$ time tar xzf drupal-8.0-alpha7.tar.gz real 0m1.436s user 0m0.080s sys 0m1.336s vagrant@precise32:~/rendimiento$ time tar czf /home/vagrant/drupal-8.0.tar.gz drupal-8.0-alpha7/ real 0m3.149s user 0m2.012s sys 0m1.124s
vagrant@precise32:/var/www/rendimiento$ pwd /var/www/rendimiento vagrant@precise32:/var/www/rendimiento$ time tar xzf drupal-8.0-alpha7.tar.gz real 1m19.588s user 0m0.216s sys 0m9.849s vagrant@precise32:/var/www/rendimiento$ time tar czf /home/vagrant/drupal-8.0.tar.gz drupal-8.0-alpha7/ real 0m17.622s user 0m3.508s sys 0m5.440s
Como se puede ver, el rendimiento del sistema de ficheros es realmente lamentable en procedimiendos de apertura y clausura de ficheros. Según esta prueba, escribir en shared folder tiene un rendimiento 55 veces peor que en el sistema de ficheros ext4 y en operaciones de lectura tene un rendimiento de 5.5 veces peor.
Crear un tipo de contenido, guardar una vista o reinstalar el sitio se convierte en un auténtico suplicio.
Ante esto busqué soluciones:
- rsync: crear un cron en el crontab que ejecutase rsync cada 15-20 segundos entre la carpeta compartida y una carpeta del sistema y cambiar el DocumentRoot de apache a esa carpeta del sistema. El problema es que tenemos la CPU casi al 100% durante todo el rato, aunque se le apliquen los parametros de sólo actualiza, sin zippear, ... Además, incluíamos el problema de duplicar el tamaño, pues tenemos repetido lo mismo en /var/www y en /apps
- lsyncd: es un servicio que funciona por debajo con rsync al que le configuras de forma muy sencilla qué carpetas quieres tener sincronizadas gracias al evento inotify de linux. Cuando un fichero cambia su fecha de actualización, sincroniza únicamente ese fichero. ¿Problema en shared folders? No levantan el evento inotify, por lo tanto no actualiza.
- CIFS: Es un sistema de ficheros más o menos común que se utiliza con Samba, pero antes de ponerme a instalar Samba dentro de la máquina opté por utilizar otro sistema de ficheros, el siguiente.
- NFS: Es un sistema de ficheros pensado para mover y sincronizar ficheros por red, de forma totalmente transparente. Con esto se podría hacer que Windows (host) tuviese instalado un servidor NFS y que ubuntu montase el directorio por NFS. Parecía sencillo y me lancé.
Configuración del servidor de NFS en Windows
Busqué varios servidores gratuitos para Windows y busqué también si existía alguna herramienta propia de Windows que levantase un servicio NFS. En sendas búsquedas obtuve buenos resultados.
Servicios propios de Microsoft para montar un servidor NFS en Windows
Existe una herramienta de Windows que se llama Windows services for UNIX. Entre otras muchas herramientas, permite instalar un servidor NFS en Windows. El problema es que sólo acepta hasta Windows Vista, y tengo un Windows 7 Profesional. Es el sistema operativo del trabajo y no puedo hacer otra cosa. En casa mi Linux Mint y mi Debian van a las mil maravillas :)
Buscando un poco más, descrubrí que Windows 7 Enterprise y Windows 7 Ultimate vienen con un servidor propio de NFS en herramientas de Windows. Si tienes estas versiones simplemente es instalar una nueva característica de Windows y habilitar los dos checks.
En mi caso ninguna de estas dos opciones me sirvió, así que fui a buscar un servidor gratuito de NFS que pudiese instalar en el Windows 7 Profesional.
Servicios y programas para instalar un servidor NFS en Windows
Brujuleando destacaron 3 programas:
- FreeNFS: Un programa muy sencillito que le indicas la carpeta que quieres compartir por NFS, las IPs a las que quieres dar permiso y ya está. Yo no lo he conseguido hacer funcionar por la subred de Virtualbox (La 192.168.44.0)
- WinNFSd: Un servicio por linea de comandos con un funcionamiento excelente respecto a su sencillez. para ejecutar es .\WinNFSd.exe d:\nfs-directory\ te ofrece en la propia línea de comandos unos mensajes de debug y de intentos de conexiones. Tampoco lo conseguí hacer funcionar por la subred de Vritualbox, pues me levantaba el servidor en la subred de la oficina. Es cierto que el código es público y se podría llegar a modificar un poquito para adecuarlo a nuestra necesidad, pero...
- Hanewin NFS: Es el único que he conseguido hacer funcionar, pero tiene la pega que es un servidor con una version shareware de 30 días y con un coste de 19,95€. Me ha sorprendido muy gratamente la robustez y la configurabilidad que tiene este programa. Ya sólo por el currazo que tiene este programa y la sencillez que tiene merece la pena pagar al autor. Este programa te habilita la edición del fichero "exports" donde le indicas los directorios a compartir, con qué IP's, qué versiones de NFS quieres levantar, sobre qué puertos, ... Además, se instala como servicio por defecto encendido. Para encenderlo y apagarlo
Una vez instalado el servidor NFS en Windows, en mi caso con Hanewin NFS hasta que encuentre algo mejor y libre, configurarlo en la Ubuntu guest es muy sencillito.
Configuración del cliente NFS en Ubuntu
Esto ya es pan comido visto lo anterior. Ejecutamos un update y un install de nfs-common:
vagrant@precise32:~$ sudo apt-get update; sudo apt-get install nfs-common
Una vez instalado, preguntamos qué directorios nos tiene disponibles el servidor NFS con el siguiente commando:
vagrant@precise32:~$ sudo showmount -e 192.168.44.1 vagrant@precise32:~$ sudo showmount -e 192.168.44.1 Export list for 192.168.44.1: /d/projects.git 192.168.44.44,127.0.0.1
Vemos que nos tiene disponible el directorio /d/projects.git. Pues montamos el directorio en /apps y probamos
vagrant@precise32:~$ sudo mount -o soft,intr,rsize=8192,wsize=8192 192.168.44.1:/d/projects.git /apps
Ahora podremos entrar y ver que toda nuestra carpeta de windows D:\projects.git la tenemos disponible en /apps. Comprobemos rendimientos de este directorio con lectura y escritura comprimiendo y descomprimiendo drupal 8.
vagrant@precise32:/apps$ pwd /apps vagrant@precise32:/apps$ time tar xzf drupal-8.0-alpha7.tar.gz real 0m37.671s user 0m0.184s sys 0m6.916s vagrant@precise32:/apps$ time tar czf /home/vagrant/drupal-8.0.tar.gz drupal-8.0-alpha7 real 0m5.460s user 0m1.560s sys 0m3.668s
Para hacerlo permanente tendremos que editar el fichero /etc/fstab
vagrant@precise32:~$ sudo vim /etc/fstab
y añadimos al final del fichero:
192.168.44.1:/d/projects.git /apps nfs soft,intr,rsize=8192,wsize=8192
Con esto, en cada arranque se montará el directorio en apps.
Conclusión
La escritura sigue siendo mala, 25 veces peor que en un sistema de ficheros ext4, pero la lectura casi no se perjudica con 1.8 veces peor que en un sistema de ficheros ext4 respecto a los 5.5 que tenían las carpetas compartidas. Teniendo en cuenta que en Drupal, las escrituras de fichero las hace casi siempre el desarrollador, que vaya 25 veces peor no es tan crítico, pero como es Apache y PHP los que hacen todas esas lecturas, bajar de 5.5 a 1.8 es una mejora de rendimiento muy importante, acelerando el drush-site install de 8-10 minutos a 1,5 minutos en el proyecto que estamos ahora desarrollando.
Seguro que las pruebas de rendimientos sobre un sistema de ficheros se pueden hacer mucho mejor con búsquedas u otras herramientas, pero una descompresión y una compresión me parecía una buena forma de medir rendimientos.
Mi recomendación y decisión sigue siendo trabajar en un ubuntu o linux mint nativo (con SDD alucinas), que viene ya muy bien preparado para trabajar con casi todo con muy poca configuración
En un futuro
En un futuro quizá se podría buscar una solución al servidor NFS en Windows buscando otro servidor o consiguiendo encontrar la opción correcta en FreeNFS o WinNFSd.
También se podría incluir en el chef de vdd, que es la configuración que he usado, una receta para instalar el nfs client y configurarla.
Investigar si por Samba/CIFS el rendimiento y configuración mejora.
Si tenéis cualquier idea o sugerencia no dudéis en comentar.
Add new comment