Revisando la información sobre el teorema CAP encontré un nuevo teorema llamado PACELC que viene a completar a CAP y que comienza a tenerse en cuenta dentro de sistemas de base de datos como CockroachDB, ¿conoces este nuevo teorema?
El teorema PACELC mantiene las tres primeras letras del teorema CAP aunque desordenadas para darle prioridad a la tolerancia a particiones. De hecho y tal y como escribí en mi anterior artículo sobre CAP, muchos autores determinan la tolerancia a particiones como crucial y no negociable. Si el sistema es distribuido debe tener tolerancia a particiones. Por lo que las tres primeras letras son la tolerancia a (P)articiones, la disponibilidad (A) y la (C)onsistencia.
Leyendo un artículo de Daniel Abadi sobre este tema encontré algo bastante interesante. Hemos estado interpretando siempre mal CAP. Cuando los autores de la comprobación indicaban la elección de dos de tres elementos parece que no enfatizaron el hecho de elegirlos en caso de particiones. Recordemos que este teorema se basa en la distribución de datos. Por lo que debería haberse enunciado como en sistemas distribuidos, en caso de encontrar particiones debemos elegir 2 de estas 3 características: consistencia, disponibilidad o tolerancia a las particiones. Obviamente, si no elegimos tolerancia a las particiones tendremos un gran problema cuando se suceda una partición y por esto mismo muchos autores lo consideran no negociable. Sería el suicidio de los datos en caso de elegir solo Consistencia y Disponibilidad.
El teorema PACELC va más allá tomando la tolerancia a particiones como una variable con dos estados: si existen particiones has elegido priorizar la disponibilidad o la consistencia, pero cuando no existen particiones, ¿qué sucede? El autor menciona este caso como else (E) y dice que cuando no hay particiones el sistema debe elegir entre (L)atencia o (C)onsistencia.
En realidad latencia puede dividirse entre latencia y disponibilidad. Pero es cierto que una latencia elevada puede equipararse a una falta de disponibilidad por lo que la mayoría de autores lo consideran el mismo problema.
En ausencia de particiones elegimos entre latencia o consistencia, ¿por qué? Principalmente por la necesidad de replicar datos. Debemos recordar que en bases de datos distribuidas, la disponibilidad de los datos la conseguimos replicando estos datos y haciendo que estén disponibles incluso aunque una de las máquinas se apague.
Entonces, podemos tener elecciones AP o CP completadas con EL o EC. Es decir, si elegimos tener consistencia en presencia de particiones y consistencia en ausencia de las mismas hemos elegido CP/EC, si elegimos disponibilidad en presencia de particiones y latencia en ausencia de las mismas habremos elegido AP/EL.
Veamos algunos ejemplos con sistemas reales. Puede ser un tópico recurrir a los sistemas gestores de base de datos pero considero estos los más representativos al mantener información y en caso de las configuraciones en clúster, mantener esta información distribuida:
DynamoDB y Riak
Aunque no son estrictamente lo mismo, Riak está basada en DynamoDB y por lo tanto a nivel teórico cumple las mismas premisas. Emplean PA+EL, es decir, durante las particiones priman la disponibilidad y en ausencia de estas la latencia. Podemos esperar respuestas rápidas aunque correctas solo eventualmente.
DynamoDB fue concebido para estar siempre disponible y con consistencia eventual. Esto quiere decir que ante una partición, todos los sistemas se mantienen operativos y cuando la partición se resuelve deben sincronizarse los datos, desechar los incorrectos y mantener una consistencia uniforme de nuevo. Si un cliente estuvo conectándose para cada petición a una parte diferente del clúster durante una partición, notará fallos de consistencia. Pasada la partición igualmente puede notar que los datos vuelven a cambiar, esta vez para reflejar de forma consistente la realidad.
Tanto DynamoDB como Riak emplean un anillo de hash consistente para distribuir la información almacenada en varias máquinas. Para mantener su disponibilidad copian esta información a un número específico de máquinas. Si una máquina cae, la información sigue estando disponible en otros nodos. Sin embargo, si sucede una partición la información queda fuera de sincronía aún estando disponible.
Sin existir particiones, puede sucederse una carga elevada en el sistema que ralentice las réplicas. Como no hay bloqueos porque prima la baja latencia pueden darse situaciones en las que obtenemos un dato antiguo (stale) cuando ha sido modificado un tiempo antes en otra máquina.
Es por ello que estos sistemas se denominan BASE (Basically Available, Soft state, Eventual consistency o Básicamente disponible, estado blando y consistencia eventual) haciendo mención a sus propiedades opuestas a ACID (Atomicity, Consistency, Isolation and Durability). Por eso de que en química los ácidos son opuestos a las bases.
Otras bases de datos empleando también PA+EL son Cassandra y CosmosDB.
Los usos más característicos de estas bases de datos son donde la consistencia no sea importante en un momento dado sino que pueda corregirse al momento siguiente y donde prime más la baja latencia y la disponibilidad de los sistemas como por ejemplo en sistemas de telefonía.
BigTable y HBase
BigTable es el desarrollo realizado por parte de Google para alto volumen de almacenamiento. Esta base de datos emplea diferentes capas para almacenar la información, por un lado almacena la información valiéndose de otro desarrollo anterior de Google llamado GFS (Google File System) que permite almacenar de forma distribuida la información en diferentes máquinas. Sobre esta capa de almacenamiento nos encontramos a Chubby que es un sistema de bloqueo para sistemas distribuidos con acoplamiento flexible. Este servicio garantiza una escritura atómica dentro de GFS. Por último tenemos SSTable (Sorted-String Table) es una representación multidimensional de datos que permiten estructurar la forma de columnas y familia de columnas jerarquizada que emplea BigTable.
El desarrollo de BigTable comenzó en 2005 pero no estuvo disponible públicamente hasta 2015. Apache HBase fue creada en 2008 basada en la publicación de Google Bigtable: A Distributed Storage System for Structured Data. HBase emplea HDFS en lugar de GFS y la comunicación la realizan empleando Thrift en lugar de gRPC. Pero la base sigue siendo similar.
Este sistema de distribución y bloqueo sin replicación indica la elección de CP en presencia de particiones y EC cuando no existen particiones. Esto quiere decir que la información no está disponible nada más que en un punto y por ello pueden producirse cuellos de botella que lleve a momentos de alta latencia en ausencia de particiones y sin embargo, en presencia de particiones, cierta información puede desaparecer o no estar disponible provocando un error al intentar realizar una consulta.
Sin embargo, Google proporciona también un sistema de replicación para su solución Cloud BigQuery. Esta característica no está disponible en HBase. Como hemos visto, el clúster estándar no dispone de esta replicación, entonces ¿en qué modifica el uso de este clúster? Pues en principio, agrega consistencia eventual entre ambos clústers. Mientras estemos conectados únicamente a un clúster podremos encontrar la elección CP+EC pero si balanceamos conexiones entre diferentes clústers podríamos obtener AP+EL con consistencia eventual. No obstante, es muy extraño necesitar conectarse o conectarse simultáneamente a dos regiones diferentes.
VoltDB y H-Store
Basados en la publicación de VLDB: The End of an Architectural Era se crearon los proyectos H-Store y VoltDB. El primero con un enfoque académico buscando explorar e investigar ciertas características avanzadas (como por ejemplo la ejecución especulativa) y el segundo con un enfoque comercial para empresas y para producción enfocado en la robustez y las herramientas para administrar el clúster.
En resumen, ambas implementaciones se basan en la idea de la partición de datos horizontal, una replicación síncrona en combinación con snapshots y anotación (log) de comandos para garantizar la durabilidad (en respuesta a la recuperación en caso de errores).
Como en el caso de BigTable y HBase, tanto VoltDB como H-Store se basan en dar las garantías ACID (Atomicity, Consistency, Isolation, Durability) por encima de la disponibilidad por lo que en presencia de particiones eligen P+C y en ausencia de las mismas E+C. La información es consistente de forma fija y segura aunque no inmediata debido a los bloqueos. En casos de implementaciones financieras mi consejo es abogar por este tipo de soluciones donde prima más la consistencia que la velocidad.
¿Qué sucede con Bases de datos como MySQL o PostgreSQL?
En principio ninguna de estas bases de datos es distribuida per se. Es decir, podemos agregar elementos alrededor como Galera para MySQL o BDR para PostgreSQL que nos permitan distribuir la información pero no están diseñadas desde sus inicios para este cometido.
Conclusiones
Sí, aún podríamos haber hablado de más bases de datos pero creo que con respecto a PACELC se tiene la idea clara de cómo funciona. Si queréis ver el análisis más en detalle de alguna base de datos en concreto, deja tu comentario y podemos ver esta y otras en siguientes artículos.