Hace un tiempo cubrimos la inauguración de la comunidad NoSQL, un movimiento para pensar alternativas a las bases de datos relacionales que tan acostumbrados nos tienen. En este artículo, Debasish Ghosh reflexiona sobre el futuro del movimiento y las diferentes alternativas que tenemos hoy en día.
Hoy en día somos testigos de muchas noticias alrededor de NoSQL. Llámese NoSQL (~SQL) o NOSQL (Not Only SQL - No solo SQL), el movimiento tiene una misión. No todas las aplicaciones necesitan almacenar y procesar datos de la misma manera, y por lo tanto la arquitectura de almacenamiento debería pensarse de forma acorde. Hasta hoy estuvimos forzados a usar el mismo martillo para pegarle a todos los clavos. Sin importar cómo procesáramos los datos de nuestra aplicación, los solemos almacenar como filas y columnas en bases de datos relacionales.
Cuando estamos tratando con grandes aplicaciones de escritura escalables, las bases relacionales apestan. La normalización de datos, los joins, y las transacciones ACID son anti-patrones para la escritura escalable. Quizás piensen que el sharding solucione los problemas, dividiendo los datos en porciones más pequeñas. En realidad, el mayor problema del sharding es que las bases de datos relacionales nunca fueron diseñadas para eso. El sharding quita muchos de los beneficios de las bases relacionales. El sharding no puede ser "algo para pensar después", ya que se entromete en la lógica del negocio de la aplicación, y hacer joins de múltiples shards puede resultar un esfuerzo no trivial. Mientras podamos escalar de forma vertical nuestro modelo de datos aumentando la capacidad del hardware, seguramente sea la opción más sana para adoptar. Pero según Moore... incluso aunque podamos escalar verticalmente, traten de migrar una base MySQL realmente grande. Les va a llevar horas, quizás días. Este es uno de los motivos por los cuales algunas empresas están migrando a bases de datos sin esquemas, cuando las aplicaciones así lo permiten.
Y si para escalar horizontalmente sacrificamos la normalización, los joins y las transacciones ACID, ¿por qué usar motores de bases de datos relacionales? No se necesitan... Digg está migrando de MySQL hacia Cassandra. Todo depende de la aplicación y del tipo de escalabilidad de escrituras que necesitemos lograr para procesar los datos. Para escalar la lectura, podemos usar esclavos de sólo-lectura que replican todo lo que llega a la base de datos maestra en tiempo real, y configurar un proxy inteligente entre los clientes y la base de datos.
El mayor entusiasmo que creó el movimiento NoSQL es por los enfoques divergentes que prometen cada uno de sus productos. Y esto es muy diferente al movimiento de motores de bases de datos relacionales, que comenzó como un único martillo llamado SQL que es capaz de manipular filas y columnas de tipos de datos sobre la teoría matemática de un conjunto de operaciones. Y cada aplicación adoptó la misma arquitectura de almacenamiento sin portar de cómo procesara los datos dentro de la aplicación. Una cosa llevó a la otra, las personas creyeron poder resolver el problema con otra capa de indirección... y así apareció esa cosa extraña llamada Mapeador Objeto-Relacional (ORM).
Finalmente, con el boom del procesamiento de datos en la Web, nos dimos cuenta que no todos los datos se procesan igual. El almacenamiento que funcionó tan bien para las aplicaciones de escritorio tradicionales, fracasa estrepitosamente con las aplicaciones sociales donde se necesitan procesar datos enlazados, que tienen la forma de grafos. La comunidad NoSQL respondió con Neo4J, una base de datos de grafos que brinda almacenamiento sencillo y recorrido de estructuras de grafos.
Si quieren escalar a lo grande la escritura, la única forma es la descentralización y la consistencia eventual. Aparece el teorema de CAP, en donde necesitamos comprometer la consistencia, la disponibilidad o la tolerancia a la partición de la red (elijan uno). Riak y Cassandra ofrecen almacenamiento descentralizado de datos que pueden escalar indefinidamente en la teoría. Si tu aplicación necesita más estructura que una base de datos clave-valor, pueden optar por Cassandra, el sistema de almacenamiento orientado a columnas, distribuido y peer-to-peer. Pueden mirar este artículo de Digg donde se compara su casos de uso entre el almacenamiento relacional y el almacenamiento por columnas que ofrece Cassandra. Si quieren una base de datos orientada a documentos con todos los beneficios de REST y JSON, prueben Riak. Riak también ofrece Map/Reduce enlazado con la opción de almacenar elementos enlazados de datos, muy parecido a la forma en que funciona la web. Riak realmente es un sistema de almacenamiento con la forma de la web.
CouchDB ofrece otra interesante propuesta para el ecosistema de NoSQL. La mayoría de las aplicaciones son básicamente offline y necesitan facilidades de replicación transparentes. CouchDB usa una estructura de almacenamiento de Árbol-B, operaciones de sólo agregado con un control de concurrencia basado en el modelo MVCC, operaciones sin bloqueos, API REST y operaciones incrementales Map/Reduce. Chris Anderson, uno de los desarrolladores líderes de CouchDB, resume el valor de CouchDB en el mundo web de hoy:
Las aplicaciones CouchApps son el producto de un navegador HTML5 y una instancia CouchDB. La ventaja clave es la portabilidad, basada en la plataforma HTML5. Las características como los Web Workers y el XHR cross-domain hacen una diferencia enorme en la arquitectura de la web. La disponibilidad en todas las plataformas es clave para el futuro de la web.
Al igual que CouchDB, MongoDB también ofrece almacenamiento de documentos. No brinda soporte REST, pero se basa en un almacenamiento JSON. También tiene Map/Reduce, y ofrece un poderoso conjunto de APIs de consulta muy parecido a SQL. Este es un punto clave de MongoDB, que le resulta muy cómodo a personas que tienen conocimientos de SQL. MongoDB también ofrece replicación maestro-esclavo, y están trabajando en escalabilidad basada en autosharding y en tolerancia a fallos.
Hay varios más sistemas de almacenamientos que ofrecen soluciones a problemas de todos los días. Caché, consumidores de colas que requieren operaciones push/pop atómicas, procesamiento de flujos de actividad, log de datos, etc. Redis y Tokyo Cabinet funcionan bien para estos casos. Redis es como caché en memoria con una base de datos persistente de clave-valor. Es un único hilo, utiliza IO no-bloqueante y es súper rápido. Redis, además de ofrece almacenamiento de clave-valor, también ofrece la posibilidad de almacenar listas y colecciones con operaciones atómicas.
Otro aspecto interesante es la interoperabilidad entre los sistemas de almacenamiento. Riak, por ejemplo, ofrece la posibilidad de usar distintos backends para los datos - podríamos usar CouchDB como backend para Riak. Posiblemente también veamos un backend Cassandra para Neo4J. Sin dudas es interesante ver como estas comunidades tienen este sentido de cooperaciones para hacer que todo el ecosistema sea más útil y crezca más