Toda aplicación desarrollada como servicio en Internet suele necesitar una base de datos, cualquier aplicación distribuida suele delegar la persistencia de sus datos en una base de datos e incluso muchas de las aplicaciones que ejecutamos en nuestros dispositivos móviles emplean bases de datos y estas pueden sincronizarse con una base de datos en la nube que se replica en otros muchos otros dispositivos, ¿sabías que muchas de estas están hechas en Erlang?
El control de la concurrencia se hace muy simple en lenguajes creados para ello. No es de extrañar ver en estos días sistemas de bases de datos distribuidas creados directamente en lenguajes como Erlang o Go. Estos lenguajes eliminan muchas fricciones a la hora de crear estos sistemas y permiten a sus creadores centrarse en nuevos problemas y desafíos y no en problemas típicos de concurrencia y distribución, resueltos en estos lenguajes desde su concepción.
En este artículo voy a comentar una serie de bases de datos distribuidas y creadas en Erlang que además, permiten distribuir su información a los dispositivos móviles.
Bases de Datos Distribuidas
Las bases de datos distribuidas son bases de datos divididas en diferentes elementos dentro de su sistema, conectados para el intercambio de información y que pueden estar distribuidas de diferentes formas. Estas pueden ser:
- Distribución por fila. Esto quiere decir que los elementos se sitúan en un nodo o en otro dependiendo de su clave o algún hash calculado a partir de su contenido.
- Distribución por columna. Tiene sentido en bases de datos que almacenan tablas, al estilo de las bases de datos relacionales. Estas almacenan el mismo registro en diferentes nodos pero solo las columnas específicas dentro de cada uno, por lo que tenemos la información de una misma fila dividida en varios nodos.
También por sus propiedades a la hora de replicar información podemos decir que las bases de datos son:
- Sin réplicas y completamente distribuidas. Este esquema no mantiene copias de los elementos, distribuye los datos en diferentes nodos pero sin copias. Si un nodo cae, parte de la información queda sin disponibilidad pero el nivel de consistencia es muy alto.
- Réplicadas no distribuidas. Este modelo indica que cada nodo tiene toda la copia íntegra de los datos. Si un nodo cae, no importa porque los datos están disponibles en el resto, pero deben tener protocolos para asegurar la consistencia de los datos ya sea por todo o nada, por quorum o usando métodos de consistencia eventual.
- Replicadas y distribuidas. Este modelo hace responsable a un nodo de una porción específica de los datos y replica datos de uno o más nodos. La ventaja con respecto al anterior es disminuir la latencia en las tareas de replicación y el espacio para almacenar toda la base de datos. La desventaja es que la cantidad de réplicas totales disponibles marca la disponibilidad. Si tenemos replicación a 2 nodos, tan solo un nodo puede caer al mismo tiempo para no perder disponibilidad.
A todo esto, hay que mencionar también los conceptos de:
- Tolerancia a particiones. Si la comunicación entre nodos se interrumpe, ¿pueden seguir operando las bases de datos? En modelos sin réplicas o réplicas distribuidas podemos mandar que sigan operando pero solo sobre los datos que les petenecen, aunque esto puedan marcar una falta de disponibilidad sobre los datos de los nodos no accesibles. También se puede optar por un quorum que decida si un nodo debe tomar el control de una copia y marcar al propietario como no válido al momento de estar disponible para realizar una réplica de datos con esa copia. Depende si nos podemos permitir consistencia eventual o no.
- Disponibilidad. Lo comentamos en varias opciones anteriores. Si un nodo cae hay posibilidad de tener nuestros datos no disponibles. Si se pierde la conexión con el clúster también podemos perder esta conectividad y dejar datos inaccesibles. Debemos tomar la decisión de si prima la disponibilidad o la consistencia para nuestros datos.
- Consistencia. La habilidad de mantener un único dato consistente es deseable en bases de datos donde manejamos datos muy sensibles, como el caso de transferencias monetarias. Sin embargo, puede ser secundario para otras bases de datos donde almacenamos datos temporales o que pueden recuperarse más tarde como los datos de las centrales de telefonía indicando si in móvil está disponible o no.
Si quieres saber más acerca de estos términos, te recomiendo leer este artículo sobre PACELC.
Datos y Dispostivos Móviles
Las bases de datos distribuidas han sido muy empleadas en servidores, principalmente, donde muchas máquinas mantienen el registro de los datos distribuidos entre los nodos que conforman el servicio de base de datos configurado de la forma necesaria. No obstante, útlimamente y por simplificar, en lugar de mantener los datos desde el origen auténtico (del inglés más conocido como source of truth), se han desarrollado muchos protocolos y APIs para permitir acceder al dato cuando es necesario.
Sin embargo, esto tiene un coste. Los dispositivos móviles no disponen todo el tiempo de una conexión estable o de calidad y por tanto, estas peticiones pueden tomar mucho tiempo para ser completadas o puede perderse parte de la comunicación. Finalmente, una solución a estos problemas pasa por tener una copia de los datos necesarios en local, en el dispositivo y siempre que sea posible.
Por ejemplo, imagina la típica aplicación de mensajería. Es obvio que los mensajes recibidos y los mensajes enviados deben recibirse y enviarse al servidor respectivamente para tener su acción, pero la información mostrada cuando entramos en cada conversación y al perfil de cada uno de nuestros contactos no tiene porqué necesitar de una conexión con el servidor.
Ahí es donde las siguientes bases de datos que voy a comentar entran en juego. No obstante, también hay desventajas. La desventaja mayor es la imposibilidad de actualizar la estructura de datos compartida entre el servidor y los móviles a placer. Es decir, si una nueva versión de nuestra aplicación requiere de un cambio muy grande en nuestro almacen de datos compartido, este cambio realizado en el servidor pueden dejar sin acceso a los dispositivos al no encontrar los datos con el formato necesario y forzarlos a realizar la actualización en ese momento.
Obviamente, hay muchas formas de paliar este problema, como puede ser el tratamiento de la base de datos compartida como una transformación de la base de datos real a nivel de servidor y el mantenimiento de tantas bases de datos como versiones de la aplicación necesitemos tener operativas.
Veamos las bases de datos que nos proporcionan estas características a día de hoy.
CouchBase Mobile
La historia de CouchBase es bastante peculiar, quizás entremos en ella en otro momento, por el momento diremos que se trata de una base de datos de documentos donde podemos localizar los elementos a través de una clave, proporcionar algunos índices secundarios para realizar búsquedas un poco más finas e incluso disponemos de un lenguaje de consulta conocido como N1QL (pronunciado como níquel).
Esta base de datos, además, tiene un producto específico para dispositivos móviles llamado Couchbase Mobile. Esta librería (o SDK) nos permite indicar qué datos queremos tener en nuestro dispositivo e ir sincronizando con el servidor. Esto quiere decir que los datos tendrán consistencia eventual pero estarán disponibles tanto en el servidor como en el dispositivo o dispositivos y nos permitirá desarrollar aplicaciones con un tiempo de latencia bajo gracias al acceso inmediato a la información ya disponible en la base de datos local.
A nivel local, pueden emplear SQL y por tanto las librerías normales que empleen para acceder a las bases de datos de sus dispositivos.
Como hemos dicho en la sección anterior, cada cambio realizado en la base de datos local es enviado al servidor a modo de evento y al mismo tiempo el servidor genera eventos para todas las bases de datos que necesiten esos cambios realizados.
ElectricSQL
Recientemente en una CodeBEAM descubrí ElectricSQL, esta base de datos se basa en los principios de una base de datos distribuida y a la vez, con respuesta como si se tratara de una base de datos local para los desarrolladores de aplciaciones móviles. Como su nombre indica tiene una implementación de SQL y por tanto simplifica de esta forma la consulta de los datos pudiendo emplear las librerías que necesitemos sobre los drivers disponibles. Como nota negativa, no he encontrado drivers nada más que para JavaScript, Cordova o React Native.
Un término nuevo que emplea ElectricSQL para solventar el problema de las migraciones, cuando necesitamos modificar, agregar o eliminar alguna parte de la estructura de nuestras bases de datos es la consistencia causal, este termino se refiere a agregar como parte de las modificaciones en los datos, las modificaciones en la estructura, de modo que los datos subsiguientes a la modificación de la estructura marcan dependencia de ese cambio y no podrán aplicarse hasta haberse completado esa modificación.
Esta base de datos, por tanto, supone un buen ejemplo de base de datos distribuida para dispositivos que nos permite eliminar nuestra preocupación acerca de cómo se propagan los datos e incluso eliminar la necesidad de diseñar un servicio web para según qué casos.
BarrelDB
Otra de las bases de datos que también descubrí en CodeBEAM fue BarrelDB, desarrollada por Benoît Chesneau, tiene una interfaz HTTP para comunicación con el servidor y va agregando los cambios en modo append-only (solo anexar) de modo que sea difícil perder información y pueda recrearse toda la fuente de datos de forma fácil y rápida.
La base de datos no ha tenido muchos cambios en los últimos años pero en su repositorio hay documentación para saber de qué se trata y cómo utilizarla. La documentación muestra la base de datos como una base de datos de documentos y tiene muchos drivers para JavaScript, PHP, Python y Elixir entre otros. Quizás ayudando y apoyando un poco el proyecto pueda remontar y seguir avanzando.
Conclusiones
Espero que este recorrido por las bases de datos distribuidas y replicables en cliente te ayude a tener una opción más a la hora de construir tus proyectos, no son una herramienta para todo pero sí pueden ayudar mucho en proyectos donde una información genérica y no muy extensa deba ser compartida. No tiene tampoco porqué ser la única base de datos del proyecto.
Recuerda que si quieres saber más sobre Erlang puedes adquirir el libro de Un Mundo Concurrente o si quieres saber más acerca de construir sistemas como estos, puedes echarle un vistazo a Las bases de OTP.
No olvides que puedes dejarnos tus comentarios y gracias por leer.