sábado, 19 de marzo de 2011

(Injusta) comparación de OpenStack Object Storage y MongoDB

Aclaración: antes que nada, quiero aclarar que no es justo para MongoDB compararlo con Object Storage. Mi intención es sólo comentar mi experiencia.


Ante la necesidad de guardar una gran cantidad de archivos en una aplicación web (más de 80GB), realicé pruebas con MongoDB (versiones 1.6.5 y 1.7.3), ya que entre las bases de datos NoSql, es la única que encontré que provee el API necesario para guardar y obtener  archivos almacenados (GridFS) (además permite ser configurado muy fácilmente para que los datos almacenados se repliquen entre distintas instancias de MongoDB). Pero me encontré con 2 problemas:
  1. Poca eficiencia en la utilización del espacio en disco: en las pruebas realizadas, al insertar archivos por un total de 12GB, en disco se utilizó 21GB.
  2. Dificultad para recuperar el espacio ocupado de archivos borrados: el borrado de los archivos es un "borrado lógico", y para recuperar el espacio que utilizan, hace falta ejecutar "repairdb()", que básicamente, hace una copia de la BD, de todos los datos no-borrados... esto es un problema si la base de datos es más grande que el espacio libre de la partición.
Este tipo de problemas los pude superar usando OpenStack Object Storage (versión 1.2.0):
  1. Utilización de espacio en disco: al insertar archivos por 4202MB, en disco se utilizó 4281MB.
  2. Recuperación de espacio en disco: el espacio es liberado al borrar los archivos.
En cuanto a las pruebas de stress:
  • MongoDB en ningún caso dió error
  • al realizar pruebas con Object Storage, he obtenido algunos "Read timed out" al momento de subir los archivos.
Cabe aclarar que MongoDB lo corria directamente en mi computadora, en cambio, Object Storage estaba instalado en una guest KVM.

En cuanto a la instalación:
  • la instalación de MongoDB me llevó muy poco tiempo y es muy fácil
  • la de Object Storage me costó más, sobre todo la utilización desde Java, ya que el cliente de Java necesita validar correctamente los certificados SSL con los que se configuró el servidor (algo que no pasa con el cliente Python).

jueves, 17 de marzo de 2011

Funciones privadas para unittest.assertRaises()

Para facilitar el uso de unittest.assertRaises() podemos usar funciones privadas. Esto al menos con python < 2.7 (ya que en python 2.7 assertRaises() permite ser usado como "context manager").


sábado, 12 de marzo de 2011

OpenStack Object Storage - Ejemplo con Python

Adjunto un pequeño ejemplo en Python.


----- Inicio del ejemplo -----

----- Fin del ejemplo -----

viernes, 11 de marzo de 2011

Probando OpenStack Object Storage

Luego de unas horas, pude tener andando mi instancia de OpenStack Object Storage. El servidor lo instalé en un Ubuntu 10.04.2 LTS (Lucid), siguiendo las instrucciones de Installing OpenStack Object Storage on Ubuntu.

Algunas cuestiones a tener en cuenta:

  • En la página de "Configuring OpenStack Object Storage", al crear los "self-signed certs" utilizando el comando "openssl req -new -x509 -nodes -out cert.crt -keyout cert.key", en un momento solicita "Common Name (eg, YOUR name) []:"; aquí hay que ingresar el nombre del host que se utilizará para conectarse, o el IP con el que se accederá al Object Storage desde la red. Por ejemplo, en mi caso, utilicé "192.168.122.233". Al conectarnos desde Python, no parece influir el "Comon Name" elegido, pero sí influye al conectarnos desde Java.
  • En vez de usar "swift-ring-builder account.builder create 18 3 1", utilicé "swift-ring-builder account.builder create 18 1 1", ya que sólo hay 1 servidor. Quizá se pueda usar 3, y de esa manera, al agregar servidores, los datos se distribuyan automáticamente...
  • Al ejecutar los comandos "swift-ring-builder account.builder add ...." hay que especificar "DEVICE"... Bueno, aunque el parámetro se llama "device", esto NO se refiere a la partición! Sino al nombre del directorio donde está montada la partición donde se guardarán los datos. El servicio supone que las particiones donde se guardarán los datos están montadas en "/srv/node/DEVICE". Por ejemplo, si los datos los vamos a guardar en la partición /dev/sdb1, y montamos esa partición en "/srv/node/sdb1", entonces DEVICE = sdb1. NO hay que tomar a DEVICE como /dev/sdb1, esto es un error. Por ejemplo, en mi caso, utilice "sdb1" como DEVICE (para seguir la nomenclatura de la documentación), pero en realidad utilizo la partición "/dev/vdb1", ya que es un instancia de KVM y utilizo virtio para mapear los discos. Por lo tanto, en el fstab tengo: "/dev/vdb1 /srv/node/sdb1 xfs noatime,nodiratime,nobarrier,logbufs=8 0 0".
Los fuentes del servidor (Swift) pueden bajarse de http://www.openstack.org/projects/storage/. El cliente para Python, puede bajarse de https://github.com/rackspace/python-cloudfiles. El de Java, desde https://github.com/rackspace/java-cloudfiles. Desarrollar un pequeño test en Python fue sencillo. En Java fue bastante más complicado, porque  al utilizar certificados firmados por mí mismo (al instalar el servidor genere los certificados con openssl, y por lo tanto no fueron firmados por una entidad de confianza), y por lo tanto Java generaba errores al intentar crear la conexión https a un servidor con certificados no confiables... Más información de esto en un próximo post :-)