¿Dónde guardo los contenidos generados por los usuarios?

El otro día estaba discutiendo con un cliente del sector del Social Media (mucho Web 2.0) sobre dónde era mejor guardar los contenidos que suban los usuarios, si en disco, en base de datos o en el cloud (Amazon S3, Nirvanix, Rackspace Cloud Files, etc…).
No hay una respuesta de cuál es mejor o pero en cualquier caso, pero si restringimos la casuística a un site con contenido generado por usuario (ugc o user-generated content) y con más de un servidor que sirva nuestro contenido (ya sea por rendimiento o por disponibilidad) tenemos un perdedor, guardarlo directamente a disco. ¿Y por qué?

  1. Si tenemos más de un nodo nos debemos asegurar que todos los nodos puedan ver el mismo contenido. Sino, cuando un usuario acabe de actualizar su foto del perfil, sus amigos verán un error 404 de fichero no encontrado, excepto si han ido a parar al mismo servidor.
  2. Si ponemos un sistema de replicación multimaster (rsyncs cruzados, por ejemplo) podemos tener colisiones de nombres (dos usuarios han subido el fichero foto.jpg en nodos diferentes y el rsync nos lo ha sobrescrito) o tener problemas puntuales que afectaran a los usuarios dando mala imagen,desde que se sube un fichero hasta que está replicado (cada X minutos) estaremos entregando errores 404
  3. Pues pongamos un almacenamiento compartido,por ejemplo NFS, aparte de los problemas de escalabilidad en entornos con mucha escritura (es bastante mejorable la gestión de bloqueos en NFS), mejor que desambiguemos el nombre del fichero a un id único o bien añadiendo el nombre del servidor que lo escriba (foto.server1.jpg).
  4. Vale, NFS es malo, pues qué tal un OCFS2 o GFS, pues aunque son sistemas que dan un rendimiento muy superior al NFS, tienen el mismo problema con las escrituras, demasiadas escrituras con demasiados nodos, los tienden a afectar demasiado. Tanto NFS/CIFS como GFS/OCFS2, son perfectos para entornos con poco ratio de escrituras (ecommerce, noticias, blogs, etc)
  5. También, parte del problema de tener un entorno para ficheros, ya teniendo un entorno de base de datos (es raro el site actual si base de datos detrás), es que nos tenemos que preocupar de tener un entorno de alta disponibilidad, backup, etc adicional.

Así que nos quedan dos entornos externos que de alguna forma los podemos ver como accesos a nivel de aplicación y menos a nivel de sistema. De esta forma tenemos más opciones para adaptar el comportamiento a lo que nos interesa.
En el caso de guardar los datos en base de datos, tenemos pros y contras:
Pros

  1. Seguro que no tenemos problemas de colisiones
  2. Nos permite guardar metadatos para poder mejorar la gestión del espacio
  3. Nos aprovechamos de todas la mejoras existentes para el accesos en base de datos (memcache, librerias, APIs, etc)
  4. Facilidad para backups, replicaciones, gestión, alta disponibilidad, etc…

Contras

  1. Lectura lenta comparada con acceso a disco
  2. Capacidad de disco necesaria

Pero podemos solucionar los contras de forma bastante simple:

  1. Utilizar el disco del servidor Web como cache de los ficheros más demandados y si disponemos de suficiente ram, aprovechar herramientas como Memcached, Ehcache o Velocity
  2. Utilizar shards para separar contenidos y permitir escalar. Tal y como he escrito en el post anterior

Y por último nuestro amigo cloud. En base a los precios y servicios actuales, los servicios se posicionan en la gama media de sites, si nuestro site tiene muchos datos o mueve mucho tráfico, seguramente nos salga más a cuenta hospedarlos nosotros, y si por el contrario movemos muy poco tráfico, es muy probable que nuestro proveedor de hosting nos dé suficiente espacio y ancho de banda para alojarlo nosotros mismos. Esto si, sin perder de vista que luego tenemos que hacer la gestión de capacidad y poder aguantar los picos que esperemos y los que no 🙂
Así que a parte de controlar los costes, debemos tener en cuenta:

  • Si queremos control exhaustivo desde dónde se acceden los archivos, lo deberemos hacer pasar por nuestro servidor y aplicar la política adecuada, con lo cual pagaremos 2 veces por el mismo ancho de banda.
  • Puede existir cierta latencia en la creación del archivo en el proveedor de cloud, afectando al rendimiento de nuestra aplicación o posibles caídas de rendimiento y/o servicio externas que afecten al nuestro.
  • Si dejamos los ficheros «públicos», cualquiera puede establecer un enlace directo y gastarnos dinero sin darnos opciones de monetizarlo, así que mejor, cuidado.

Así que ya habéis visto, no existe la panacea, pero, al menos desde mi punto de vista, si queréis un site que escale a muchos usuarios -> muchos servidores, mejor tener el control de los ficheros a nivel de aplicación, y ahora mismo esto implica, o soluciones Cloud o soluciones basadas en Base de Datos.

Y ya sabéis, comentarios bienvenidos 🙂

Saludos