← 🗄️ NoSQL
intermedio

2.3 · El teorema CAP: consistencia, disponibilidad y particiones

⏱ 25 minMódulo 2: Almacenamiento Distribuido y NoSQL

El problema: coordinar réplicas en una red imperfecta

En la lección anterior vimos que los sistemas NoSQL distribuyen y replican datos entre muchos nodos. Pero replicar plantea una pregunta incómoda: si escribo un dato en el nodo A y al mismo tiempo alguien lo lee del nodo B, ¿qué valor ve?

El teorema CAP, formulado por Eric Brewer (2000) y demostrado por Gilbert y Lynch (2002), establece que un sistema de datos distribuido no puede garantizar simultáneamente más de dos de estas tres propiedades:

PropiedadSignificado
C — ConsistenciaToda lectura recibe la escritura más reciente (o un error). Todos los nodos ven el mismo dato al mismo tiempo.
A — DisponibilidadToda petición recibe una respuesta (aunque no sea el dato más reciente). El sistema nunca rechaza operaciones.
P — Tolerancia a particionesEl sistema sigue funcionando aunque la red se parta y los nodos no puedan comunicarse entre sí.
graph TD
C["C — Consistencia"]
A["A — Disponibilidad"]
P["P — Tolerancia a particiones"]
C --- A
A --- P
P --- C
C -.-> CP["Sistemas CP<br/>HBase, MongoDB<br/>(por defecto)"]
P -.-> CP
A -.-> AP["Sistemas AP<br/>Cassandra, CouchDB"]
P -.-> AP
C -.-> CA["CA (teórico)<br/>RDBMS en un solo nodo"]
A -.-> CA
El triángulo CAP: solo dos vértices a la vez. Los sistemas CP y AP sacrifican un vértice; CA solo existe sin particiones.

El matiz clave: la partición no es opcional

El teorema suele malentenderse como “elige dos de tres y olvida la tercera”. En realidad, en un sistema distribuido de verdad, las particiones de red van a ocurrir (cables, switches, congestión, regiones de nube que se aíslan). Renunciar a P significaría renunciar a distribuir.

Por tanto, la decisión real es: cuando ocurre una partición, ¿qué sacrificas: C o A?

  • CP (consistencia sobre disponibilidad): si un nodo no puede confirmar que tiene el dato más reciente, rechaza la operación o se pone en modo solo-lectura hasta que la red se recupere. Ejemplos: HBase, MongoDB con escritura mayoritaria, ZooKeeper.
  • AP (disponibilidad sobre consistencia): cada lado de la partición sigue aceptando escrituras aunque se desincronicen; al sanar la red hay que reconciliar las versiones. Ejemplos: Cassandra, CouchDB, DynamoDB.
graph TD
subgraph Antes["Red sana"]
  N1["Nodo A<br/>x = 1"] <-->|"replicación"| N2["Nodo B<br/>x = 1"]
end
subgraph Particion["¡Partición de red!"]
  N3["Nodo A<br/>x = 2 (escritura local)"] -.-|"enlace cortado"| N4["Nodo B<br/>x = 1 (dato viejo)"]
end
Particion --> Decision{"¿Qué hace el Nodo B?"}
Decision -->|"CP: rechaza lecturas<br/>hasta reconectarse"| Resp1["Error / timeout"]
Decision -->|"AP: responde con<br/>lo que tiene"| Resp2["x = 1 (inconsistente)"]
Ante una partición, un nodo aislado debe elegir: rechazar peticiones (CP) o responder con datos posiblemente desactualizados (AP).

Consistencia eventual

Los sistemas AP no abandonan la consistencia: la posponen. Con consistencia eventual, si dejan de llegar escrituras, todas las réplicas terminan convergiendo al mismo valor mediante procesos en segundo plano (anti-entropy, read repair, hinted handoff en Cassandra).

El problema es decidir qué versión gana cuando dos réplicas divergen:

  • Last-write-wins (LWW): gana la escritura con la marca de tiempo más reciente. Simple, pero pierde datos si dos escrituras fueron realmente concurrentes.
  • Relojes vectoriales / versiones: detectan conflictos reales y los exponen a la aplicación para que los resuelva (DynamoDB clásico, Riak).
  • CRDTs: estructuras de datos diseñadas para fusionarse sin conflicto (contadores, conjuntos).

La consistencia eventual no es “inconsistencia para siempre”: en la práctica la ventana de divergencia suele ser de milisegundos. Pero durante una partición puede durar horas, y la aplicación debe estar preparada para leer datos viejos.

Quórum: consistencia ajustable con R + W > N

Muchos sistemas (Cassandra, DynamoDB) no son CP ni AP de forma absoluta: permiten ajustar la consistencia por operación mediante quórum. Si un dato tiene N réplicas:

  • W: en cuántas réplicas debe confirmarse una escritura antes de responder al cliente.
  • R: de cuántas réplicas se lee antes de responder.

La regla fundamental:

Si R + W > N, la lectura toca al menos una réplica que vio la escritura: hay consistencia fuerte (sin contar fallos de reloj y reparaciones pendientes).

Ejemplos con N = 3:

ConfiguraciónGarantíaPerfil
W=3, R=1R+W=4 > 3: fuerteEscrituras lentas, lecturas rápidas
W=1, R=3R+W=4 > 3: fuerteEscrituras rápidas, lecturas lentas
W=2, R=2R+W=4 > 3: fuerteEquilibrio (quórum clásico)
W=1, R=1R+W=2 ≤ 3: eventualMáxima velocidad y disponibilidad

¿Qué elegir en la práctica?

  • CP cuando un dato incorrecto es peor que un error temporal: saldos bancarios, inventario, configuración de clúster, líderes distribuidos.
  • AP cuando responder siempre es lo crítico y el dato tolera converger: carritos de compra, likes, telemetría, feeds.
  • Recuerda: fuera de una partición, los sistemas AP suelen comportarse de forma consistente. CAP solo muerde durante fallos de red.

Ejercicio: simula consistencia eventual

🧪 Ejercicio

Réplicas que convergen

Simula 3 réplicas de un contador. Implementa una clase `Replica` con un diccionario de valores y una marca de tiempo por clave, un método `escribir(clave, valor, ts)` y un método `sincronizar(otra)` que fusiona dos réplicas quedándose, por clave, con el valor de mayor marca de tiempo (last-write-wins). Escribe valores distintos en réplicas distintas (simulando una partición), luego sincroniza todas y muestra que convergen.

Comprueba lo aprendido

Comprueba que lo pillaste

Durante una partición de red, un sistema CP como HBase recibe una escritura en un nodo que no puede contactar a la mayoría. ¿Qué hace?

Comprueba que lo pillaste

Con N = 5 réplicas, ¿cuál de estas configuraciones de quórum NO garantiza consistencia fuerte (R + W > N)?

Comprueba que lo pillaste

¿Por qué se dice que, en la práctica, la elección del teorema CAP es entre C y A, y no entre tres opciones?

Resumen

  • El teorema CAP: un sistema distribuido solo puede garantizar 2 de 3 entre Consistencia, Disponibilidad y Tolerancia a particiones.
  • Como las particiones son inevitables, la decisión real es CP vs AP durante una partición: rechazar operaciones o aceptar divergencia temporal.
  • Los sistemas AP usan consistencia eventual: las réplicas convergen con mecanismos como read repair y resolución de conflictos (LWW, relojes vectoriales, CRDTs).
  • El quórum permite ajustar la consistencia: con N réplicas, R + W > N garantiza que la lectura vea la última escritura.
  • No hay respuesta única: datos financieros tienden a CP, feeds y telemetría a AP, y muchos sistemas permiten elegir por operación.

📚 Lecturas y fuentes

RecursoTipoPor qué leerlo
Teorema CAP (Wikipedia en español)ArtículoRepaso corto en español del enunciado y de la clasificación CP/AP. Léelo entero, son pocos párrafos.
CAP Twelve Years Later: How the “Rules” Have Changed — Eric Brewer (InfoQ)ArtículoEl propio autor del teorema explica que “2 de 3” es engañoso. Fíjate en la sección “Why ‘2 of 3’ is Misleading” (en inglés).
Please stop calling databases CP or AP — Martin KleppmannArtículoEntrada de blog de 10 minutos: por qué etiquetar una base como CP o AP suele ser incorrecto. El antídoto contra memorizar el triángulo (en inglés).
Designing Data-Intensive Applications (Martin Kleppmann)LibroCap. 9 “Consistency and Consensus”, sección “Linearizability” y su apartado “The Cost of Linearizability”; y del cap. 5, “Quorums for reading and writing” para la regla R + W mayor que N (en inglés).