Los sistemas distribuidos modernos se basan en concesiones. El rendimiento, la fiabilidad, la escalabilidad y la coherencia no son gratuitos: siempre hay que pagar un precio. Ahí es donde entra en juego el teorema CAP: es el punto de partida para comprender los compromisos inevitables en el diseño distribuido.
¿Por qué es cierto el teorema CAP? ¿Qué explica realmente? Y, lo más importante, ¿es suficiente? En este artículo, exploraremos el teorema CAP, sus limitaciones, las críticas que ha enfrentado y cómo las ideas más nuevas como PACELC están impulsando el debate. Profundicemos.
La primera versión del teorema CAP comenzó como un debate entre ACID y BASE . Pero con el tiempo evolucionó, obtuvo una prueba formal y se convirtió en el teorema CAP tal como lo conocemos hoy.
El teorema CAP establece que un sistema distribuido puede satisfacer como máximo dos de tres propiedades simultáneamente :
Esta limitación obliga a los ingenieros a hacer concesiones difíciles en función de los objetivos del sistema y las realidades de sus entornos distribuidos.
La consistencia en CAP no es lo mismo que la consistencia en las transacciones ACID . En el teorema CAP se refiere a linealización o consistencia fuerte . Significa que todos los nodos en un sistema distribuido deben presentar siempre una vista única y actualizada de los datos , independientemente de qué nodo procese la solicitud. Esto significa que cada operación de lectura refleja la escritura más reciente, sin importar qué nodo consulte.
💡 Por otro lado, la coherencia en ACID se centra en garantizar que una transacción lleve la base de datos de un estado válido a otro estado válido, siguiendo las reglas definidas por el esquema de la base de datos. Se trata más bien de aplicar restricciones de integridad (como claves externas, restricciones únicas, etc.) y garantizar que la base de datos no quede en un estado no válido, incluso en caso de fallos.
La disponibilidad en CAP significa que cada nodo que no falla debe devolver una respuesta para cada solicitud que recibe, independientemente de las particiones de la red . En otras palabras, si un nodo en buen estado recibe una solicitud, debe procesarla y responderla. Sin embargo, CAP no garantiza que la respuesta siempre sea "correcta" o esté actualizada ; solo garantiza que el nodo no falle de manera silenciosa (por ejemplo, en un sistema AP , los nodos pueden responder con datos obsoletos durante una partición para garantizar la disponibilidad).
💡 Eric Brewer (el autor original de CAP) describió originalmente esta propiedad de forma un poco más flexible: "casi todas las consultas deberían obtener una respuesta". Sin embargo, en la prueba formal de CAP, la disponibilidad se hizo más estricta y se requirió que "todas las consultas reciban una respuesta siempre que el nodo que las maneja esté en buen estado".
En la práctica, sin embargo, la disponibilidad no es una garantía absoluta; a menudo depende de restricciones específicas del sistema, como el tiempo que está dispuesto a esperar para recibir una respuesta. En los sistemas del mundo real, el tiempo de respuesta (o los tiempos de espera) desempeña un papel fundamental a la hora de determinar el SLA (acuerdo de nivel de servicio), aunque el CAP en sí no tenga en cuenta directamente la latencia. Más información al respecto en esta publicación del blog .
La tolerancia a las particiones tiene que ver con la supervivencia ante fallas de red. Si los nodos no pueden comunicarse debido a una división de la red (partición), el sistema debe cumplir con sus garantías de consistencia o disponibilidad, según sus opciones de diseño. Una partición se produce cuando los nodos no pueden comunicarse debido a paquetes perdidos, tiempos de espera agotados o divisiones de la red.
Los sistemas distribuidos no viven en un mundo de cuento de hadas con redes perfectas. Los paquetes se descartan, se agotan los tiempos de espera y los picos de latencia son inevitables. Por este motivo, la tolerancia a las particiones no es negociable en ningún sistema distribuido : las particiones se producirán tarde o temprano, por lo que no se puede "elegir" ignorarlas, por muy tentador que pueda parecer.
En CAP, la tolerancia a particiones no significa que el sistema siga funcionando como si nada hubiera pasado, sino que el sistema debe decidir si priorizar la disponibilidad (AP) o la consistencia (CP) durante una partición. Si ignorara la tolerancia a particiones, básicamente estaría construyendo un sistema monolítico no distribuido.
La forma más sencilla de entender el CAP es considerar una partición de red , una situación en la que dos partes de un sistema distribuido no pueden comunicarse entre sí. En tal escenario, el sistema se enfrenta a tres posibles resultados:
Por lo tanto, durante una partición , el sistema solo puede satisfacer dos de las tres propiedades (C, A o P) . Una vez que se resuelve la partición (es decir, los nodos vuelven a interactuar), el sistema puede recuperar las tres propiedades, pero durante la partición en sí , las compensaciones son inevitables.
Una consecuencia del teorema para sistemas asincrónicos es que solo son posibles tres combinaciones de consistencia, disponibilidad y tolerancia de partición:
Los sistemas de este tipo responden a las consultas, pero los datos devueltos pueden no estar siempre actualizados, con actualizaciones más lentas de los datos pero "siempre" disponibles. Ejemplos de este tipo de sistemas son DNS, DynamoDB y Cassandra.
Los sistemas de este tipo siempre devuelven datos actualizados, pero algunos nodos del sistema, o incluso todos, pueden no responder si se dividen en particiones. Ofrece actualizaciones atómicas, pero puede provocar tiempos de espera agotados. Las bases de datos NoSQL, como Google BigTable, MongoDB, HBase y Redis, son todas sistemas de este tipo.
Los sistemas de este tipo siempre devuelven datos actualizados cuando no hay particiones. Debido a esta última limitación, normalmente, estos sistemas se utilizan solo en una máquina. Un ejemplo son las bases de datos relacionales clásicas.
En realidad, elegimos entre CP y AP porque CA es básicamente un monolito sin particiones. Para sistemas de gran escala, los diseñadores no pueden abandonar P y, por lo tanto, tienen una elección difícil entre C y A.
En CA, la falla de un nodo significa la indisponibilidad total del servicio. Pero esto no deshabilita la escalabilidad, ya que podemos clonar monolitos independientes y distribuir la carga entre ellos.
El teorema CAP ha sido un concepto fundamental en los sistemas distribuidos, pero no está exento de limitaciones. A pesar de su claridad a la hora de presentar la idea de las compensaciones, el teorema CAP ha sido criticado a menudo por simplificar en exceso realidades complejas, lo que ha dado lugar a malentendidos y aplicaciones incorrectas.
Una de las críticas más comunes es que las disyuntivas del teorema CAP (elegir entre consistencia (C) y disponibilidad (A)) solo se aplican cuando realmente se produce una partición de la red (P) . En un funcionamiento normal, cuando la red es estable y no existen particiones, no existe una disyuntiva inherente entre consistencia y disponibilidad.
Además, estas compensaciones no son universales en todo el sistema. Dentro del mismo sistema distribuido:
Este matiz a menudo se pierde en los debates de alto nivel sobre CAP, lo que lleva a clasificaciones demasiado simplificadas de los sistemas como "CP" o "AP" en general.
Otra crítica importante es que el teorema CAP no tiene en cuenta la latencia , aunque en la práctica la latencia y la partición están profundamente conectadas. Por ejemplo:
En sistemas distribuidos del mundo real, cuando se produce una partición o una latencia alta, el sistema debe tomar una decisión dentro de un período de tiempo de espera : priorizar la disponibilidad devolviendo un resultado posiblemente obsoleto, o priorizar la consistencia esperando más tiempo (y posiblemente no respondiendo). La vista binaria de CAP no captura la complejidad de estas decisiones.
El teorema CAP presenta la consistencia, la disponibilidad y la tolerancia a la partición como propiedades binarias: se tienen o no se tienen. Pero en la práctica, las tres propiedades existen en un espectro :
Esta naturaleza continua de las propiedades hace que CAP sea demasiado simplista para modelar las complejidades de los sistemas distribuidos modernos.
Si bien el CAP revolucionó nuestra comprensión de las compensaciones en los sistemas distribuidos, no es la última palabra sobre el tema. El teorema PACELC descrito por Daniel J. Abadi se considera un enfoque alternativo para el diseño de sistemas distribuidos. Se basa en el modelo CAP, pero además de la consistencia, la disponibilidad y la tolerancia a las particiones, también incluye la latencia y la exclusión lógica entre combinaciones de estos conceptos.
PACELC introduce dos modos de funcionamiento distintos para sistemas distribuidos:
Si bien las particiones son inevitables en los sistemas distribuidos, son poco frecuentes en comparación con los desafíos que surgen durante el funcionamiento normal. En los sistemas distribuidos modernos, la latencia suele ser un cuello de botella más grande que las particiones de red, en particular para aplicaciones a escala global. Aquí es donde se centra PACELC : abordando las desventajas que se producen cuando el sistema funciona sin particiones. A diferencia de CAP, que se centra únicamente en el comportamiento durante escenarios de falla, PACELC enfatiza las decisiones que los arquitectos deben tomar todos los días para equilibrar la latencia (L) y la consistencia (C) :
Al ampliar la conversación más allá de las particiones para incluir el funcionamiento normal, PACELC garantiza que el rendimiento diario de los sistemas distribuidos se trate con la importancia que merece.
La formulación del teorema CAP ha sido un acontecimiento significativo en la comunidad, y los estudios sobre su impacto en el diseño de sistemas distribuidos han demostrado que los diseñadores de sistemas distribuidos no deben limitar el sistema a dos propiedades, sino que deben esforzarse por maximizar las garantías requeridas en cada caso particular. Para ello, es razonable dividir el sistema en segmentos, cada uno de los cuales tiene sus propios requisitos, y diseñar el sistema en función de los requisitos de cada uno de los segmentos.
El teorema CAP ha sido una piedra angular del pensamiento de sistemas distribuidos durante décadas. Nos brindó un marco para razonar sobre las compensaciones inherentes de la consistencia, la disponibilidad y la tolerancia a las particiones. Pero, en muchos sentidos, es una simplificación de la realidad, que supone opciones binarias e ignora factores críticos como la latencia.
PACELC se basa en el CAP, reconociendo que:
Tanto CAP como PACELC son herramientas valiosas, pero ninguna de ellas es una receta paso a paso para construir sistemas. En cambio, proporcionan modelos mentales para evaluar las ventajas y desventajas y comprender los límites de las arquitecturas distribuidas.
¡Gracias por leer!
¿Tienes curiosidad sobre algo o tienes ideas para compartir? ¡Deja tu comentario a continuación! Echa un vistazo a mi blog o sígueme a través de LinkedIn , Substack o Telegram .