La tendencia es trasladar todas las herramientas que antes dominaban los escritorios de nuestros ordenadores a la web y a nuestros dispositivos móviles.
Hoy día nuestro navegador web y smartphone se ha convertido en una herramienta indispensable tanto en nuestro tiempo de ocio como a la hora de hacer nuestro trabajo, ya que la mayoría de aplicaciones de escritorio que antes utilizábamos para comunicarnos, almacenar fotografías, contabilizar nuestro tiempo, hacer presentaciones, etcétera; hoy tienen su equivalente en app o web.
Las apps, el Software-as-a-Service (SaaS) y los servicios en la nube hoy dominan el mercado y gracias a esto han surgido cientos de startups de éxito que han creado aplicaciones que dan servicio a millones de usuarios. Lo que antes se ejecutaba en un entorno cerrado de servidores con 10-10.000 usuarios, hoy día se ejecuta en la web con varios millones de usuarios.
"Lo que antes se ejecutaba en un entorno cerrado de servidores con 10-10.000 usuarios, hoy día se ejecuta en la web con varios millones de usuarios"
Una de las piezas clave de estos sistemas son los sistemas gestores de bases de datos (DBMS) que hemos exprimido al máximo y han tenido que superar los retos de escalabilidad y concurrencia que suponen estos nuevos modelos de negocio.
El modelo de bases de datos relacionales que postuló Codd en 1970 aún sigue vigente hoy día y DBMSs relacionales como MySQL o Oracle han sido optimizados al máximo y aun hoy siguen dominando el mercado. Incluso Twitter con sus millones de usuarios sigue usando MySQL, eso sí, con varias capas de middlewares que han desarrollado a mano y que les permite modelar bases de datos orientadas a grafos distribuidas y guardando parte de los datos en un sistema no SQL, concretamente en Cassandra.
Cuando han sido llevados al límite, al igual que les ocurrió a los desarrolladores de Twiter, los ingenieros nos hemos visto obligados a usar subterfugios como middlewares, cachés intermedias, trabajar fuera de la 3FN duplicando algunos datos y soluciones poco intuitivas que complican el mantenimiento del software y contribuyen a su degradación.
Cuando han sido llevados al límite, al igual que les ocurrió a los desarrolladores de Twiter, los ingenieros nos hemos visto obligados a usar subterfugios como middlewares, cachés intermedias, trabajar fuera de la 3FN duplicando algunos datos y soluciones poco intuitivas que complican el mantenimiento del software y contribuyen a su degradación.
¿Entonces... hay alternativa? ¿Cómo nos enfrentamos a este tipo de desarrollos?
Hoy día la inmensa mayoría de personas que nos dedicamos a la web hemos escuchado hablar de los sistemas de bases de datos no relacionales, bien por ese nombre o por sistemas Not Only SQL (noSQL). Si no te suena a lo mejor has oído hablar de MongoDB, uno de los sistemas noSQL que más repercusión está teniendo.
Sin embargo dado que durante nuestra formación universitaria se nos ha orientado a usar datos sumamente estructurados, con formas normales y reglas estrictas para garantizar la consistencia de los datos... a muchos desarrolladores nos cuesta decantarnos por este tipo de sistemas que sin embargo, pueden marcar la diferencia en determinados proyectos. Los sistemas no SQL son fácilmente escalables, mucho más versátiles y por supuesto veloces. No obstante, 'Magic always comes with a price', y no todo son ventajas. A cambio de esta escalabilidad y versatilidad tenemos que renunciar a algunas características de los sistemas relacionales.
En la siguiente gráfica podemos ver como se clasifican algunos sistemas. Por un lado tenemos Memcached, que al no tener prácticamente funcionalidades puede escalar fácilmente. Al lado derecho de la gráfica tenemos a los sistemas relacionales, que ofrecen una gran funcionalidad a costa de perder velocidad y escalabilidad. Entre medias de ambos tendríamos los sistemas noSQL que renunciando a algunas funcionalidades de los sistemas relacionales rápidamente escalan puesto en el eje de ordenadas.
Por tanto, antes de comenzar un desarrollo la pregunta es...
...¿Podemos renunciar a estas características?
¿A cuales?
En la siguiente gráfica podemos ver como se clasifican algunos sistemas. Por un lado tenemos Memcached, que al no tener prácticamente funcionalidades puede escalar fácilmente. Al lado derecho de la gráfica tenemos a los sistemas relacionales, que ofrecen una gran funcionalidad a costa de perder velocidad y escalabilidad. Entre medias de ambos tendríamos los sistemas noSQL que renunciando a algunas funcionalidades de los sistemas relacionales rápidamente escalan puesto en el eje de ordenadas.
Por tanto, antes de comenzar un desarrollo la pregunta es...
...¿Podemos renunciar a estas características?
¿A cuales?
¿Escalabilidad? ¡Sí, por favor!
Existen dos formas de escalar un sistema, lo que llamamos escalabilidad vertical y escalabilidad horizontal:- Escalabilidad vertical: Consiste en mejorar las capacidades del equipo por ejemplo aumentando la memoria RAM, con dispositivos de almacenamiento de datos más veloces y con más y mejores procesadores. Obviamente esto tiene un límite y llega un punto en el que es necesario rediseñar el sistema.
- Escalabilidad horizontal: Consiste en añadir nodos al sistema de forma que las peticiones se distribuyan entre los distintos nodos. Aunque es necesario que las aplicaciones estén preparadas para ello, este escalado es mucho más ventajoso en términos de coste y posibilidades futuras. En principio no tiene límite ya que podemos añadir tantos nodos como queramos y nos permite empezar con un hardware mínimo que podemos mejorar progresivamente sin necesidad de realizar migraciones del sistema.
Un ejemplo donde los beneficios de la escalabilidad horizontal se ven muy claros sería en sistemas con tráfico estacional con picos importantes como podría ser la venta de entradas de un concierto; esta configuración nos permitiría el día de apertura de la venta, escalar el sistema para aguantar la avalancha inicial de compras y luego reducirlo progresivamente en función de la demanda para reducir costes de servidores.
Si el sistema que estamos desarrollando puede ser atendido por único servidor de bases de datos y no se prevé que en el futuro vaya a crecer masivamente, mi recomendación es clara: Los sistemas SQL presentan muchas más funcionalidades y ventajas que los noSQL
Como ya se ha comentado, para conseguir esta escalabilidad, los sistemas noSQL tienen que sacrificar algunas características. Si recordamos el teorema de Brewer, afirmaba que cualquier sistema distribuido solo podría cumplir con 2 de las 3 características siguientes:
- Consistencia: La información siempre permanecerá consistente y coherente cuando realicemos operaciones sobre los datos y será la misma independientemente del nodo del que recibamos la respuesta.
- Disponibilidad: Toda la información almacenada en el sistema estará siempre disponible incluso aunque parte de los nodos no sean accesibles.
- Tolerancia a particiones: El sistema seguirá funcionando incluso aunque parte del mismo deje de estar accesible y algunos nodos queden fuera de la red.
Las bases de datos relacionales cumplen con las características de consistencia y disponibilidad. Sin embargo, para que los sistemas no relacionales puedan alcanzar las cotas de escalabilidad exigidas, no pueden prescindir de la tolerancia a particiones, lo que ha hecho que surjan dos corrientes: Los que deciden renunciar a la consistencia como Cassandra o CouchDB y los que sacrifican la disponibilidad como MongoDB, Paxos o Redis. En el primer caso seremos nosotros como desarrolladores los que tengamos que gestionar las posibles inconsistencias que puedan producirse en los datos, cosa que complica bastante el desarrollo, en el segundo, ante el fallo de algún nodo, puede que parte de los datos no sean accesibles y debemos preparar nuestros sistemas para que puedan seguir funcionando sin esos datos.
Será nuestra responsabilidad como desarrolladores estudiar en cada proyecto la mejor solución valorando la importancia de cada característica para estudiar cual podemos sacrificar.
Consistencia, consultas JOIN y transacciones
En los sistemas relaciones ideales la máxima es almacenar los datos en un único lugar sin duplicidades, para lo cual llevamos el esquema de datos a la tercera forma normal. Por ejemplo si queremos almacenar un listado de suscriptores a nuestro blog junto con sus intereses, tendremos una tabla de suscriptores, otra de intereses y relacionaremos ambas mediante sus identificadores únicos. Para obtener la información completa cruzaremos la información de ambas tablas con una consulta JOIN que nos devolverá la información como si de una sola tabla se tratase.Este ejemplo es sencillo no presenta muchos problemas, pero algunas consultas JOIN en bases de datos complejas pueden complicarse demasiado y terminar por resultar ineficientes. Aquí es donde entra en juego la flexibilidad de los sistemas NoSQL que se preguntan: Dado que el espacio de almacenamiento ya no supone un problema, ¿Por qué no tener toda la información relativa a un registro (o documento) almacenada en una única tabla (o colección)? Así, cuando necesitemos de la información, basta con extraerla sin necesidad de cruzar y mezclar diferentes tablas.
Tiene sentido, sin embargo volviendo al ejemplo anterior, cuando tengamos que actualizar la información de un interés, tendremos que actuar sobre todos los registros que incluyan dicho interés. ¿Qué ocurre si se produce un error en mitad de la ejecución de la consulta de actualización? noSQL no se lleva muy bien con las transacciones, lo cual es normal si pensamos que una consulta puede estar actuando en varios servidores simultáneamente y si falla en uno de ellos los demás no tienen forma de saber cuales se han completado con éxito y cuales no. En estos casos será nuestra responsabilidad volver a restaurar la consistencia de los datos implementando algún mecanismo de rollback... y en este punto es cuando poco a poco la eficiencia y versatilidad que hemos conseguido gracias al uso de sistemas noSQL empieza a perder fuelle. ¿Realmente podemos escribir código más eficiente para un proyecto con presupuesto limitado que el que ofrecen los sistemas relacionales que se han ido mejorando desde hace más de 30 años?
Flexibilidad vs información estructurada
Otra de las características propias de los sistemas noSQL es la ausencia de un esquema de datos lo que puede considerarse una ventaja o un inconveniente según el punto de vista. Indudablemente es mucho más flexible, y tiene sentido si pensamos que la información por lo general nunca es tan estructurada como nos imponen los sistemas relaciones. Imaginad que hemos desarrollado un sistema que lleva funcionando unos meses y ahora nos damos cuenta de que necesitamos añadir un campo de dirección a una tabla. No hay problema, al no haber esquema, simplemente los registros anteriores no incluirán esa información pero podemos añadirla en los nuevos registros.No obstante, tanta flexibilidad puede convertirse en una bomba de relojería en proyectos realizados por equipos grandes o cambiantes. Por ejemplo, si retomando el ejemplo de la dirección unos desarrolladores pueden decidir almacenarla como una cadena de texto y otros como un objeto que separe la calle, la ciudad y el código postal. Esto, a la larga, puede ser un problema y requerir dedicar grandes cantidades de tiempo a la refactorización de código.
¿Ha llegado el momento de noSQL?
Son muchas las alternativas que existen actualmente en el mercado con diferentes niveles de madurez, incluso empresas como Oracle han lanzado su propia solución NoSQL, pero ninguna puede competir con la robustez y soporte que existe para los sistemas relacionales. Esto puede resultar determinante para algunas empresas pues las especificaciones de la mayoría de las bases de datos no relaciones disponibles actualmente son cambiantes introduciendo cambios significativos de unas versiones a otras haciendo que sea complicado ofrecer una compatibilidad futura para nuestros desarrollos.Como hemos ido desgranando en este artículo, los sistemas noSQL no son la panacea, si bien es cierto que presentan algunas características que pueden resultar muy atractivas para determinados proyectos, pero no por ello debemos lanzarnos a usarlos de forma masiva en todos nuestros desarrollos. Es nuestra responsabilidad como ingenieros determinar cuando pueden ser beneficiosos o cuando podemos renunciar a las funcionalidades extra que nos ofrecen las bases de datos relacionales.
Termino el post abriendo el debate...
¿Qué opinas sobre los sistemas noSQL?
¿Alguna vez has usado alguno en tus proyectos?
¿Crees que las desventajas que presentan con respecto a los sistemas relacionales son salvables?
No hay comentarios:
Publicar un comentario