Consistencia eventual vs. consistencia fuerte — ¿cuál es el tradeoff real y cómo elegir según el caso de uso?
Todo almacén de datos replicado tiene que prometer algo sobre la obsolescencia — la habilidad no es elegir un modelo para siempre, sino ajustarlo a lo que realmente costaría una lectura obsoleta.
APRENDE HACIENDOPon a prueba tu intuición3 pasos
Consistencia eventual vs. consistencia fuerte — ¿cuál es el tradeoff real y cómo elegir según el caso de uso?
Usa los ejemplos y la explicación de la lección para comprobar tu idea.
Reflexión personal. No se envía a ningún servicio de IA.#Dos promesas que puede hacer un almacén de datos distribuido
Cuando los datos se replican entre varios nodos — algo que cualquier sistema construido para disponibilidad o distribución geográfica tiene que hacer — hay que decidir qué se promete sobre cuándo una escritura se vuelve visible para las lecturas posteriores. La consistencia fuerte (concretamente la linealizabilidad, la forma común más estricta) promete que cada lectura refleja la escritura completada más reciente, como si solo existiera una copia de los datos, sin importar qué réplica responda. La consistencia eventual relaja eso: una escritura se acepta, se replica de forma asíncrona, y eventualmente llegará a todas las réplicas, pero una lectura inmediatamente después de la escritura — sobre todo si la sirve una réplica distinta de la que recibió la escritura — puede devolver datos obsoletos.
Esto no es un defecto que se tolera a regañadientes; es un intercambio deliberado por latencia y disponibilidad. La consistencia fuerte generalmente requiere coordinación entre réplicas antes de confirmar una escritura (un quorum, un protocolo de consenso, o enrutar todas las escrituras y lecturas sensibles a la consistencia a través de un único líder), lo que añade latencia y, durante una partición de red, te obliga a bloquear o rechazar peticiones (el lado "C" del tradeoff de CAP). La consistencia eventual permite que cualquier réplica acepte una escritura localmente y reconcilie después, así que se mantiene disponible y rápida incluso cuando las réplicas no pueden comunicarse en ese momento — el lado "A" de CAP.
#Dónde la consistencia fuerte vale el costo
- Saldos de cuentas y libros contables financieros. Si un usuario transfiere dinero fuera de una cuenta, una lectura de ese saldo un milisegundo después debe reflejar el cargo, o corres el riesgo de doble gasto — alguien lee un saldo obsoleto de "fondos suficientes" desde una réplica rezagada y aprueba un segundo retiro.
- Inventario durante el checkout de un artículo escaso. Vender de más la última unidad de un artículo muy disputado porque dos réplicas creían que estaba disponible es un fallo visible para el cliente, no solo una inconsistencia interna.
- Elección de líder y locks distribuidos. Si dos nodos pueden creer simultáneamente que tienen el lock por culpa de una lectura obsoleta, tienes split-brain — precisamente por eso los servicios de coordinación como ZooKeeper y etcd se construyen sobre protocolos de consenso (Raft/Zab) que garantizan lecturas linealizables del estado del lock.
- Configuración que controla comportamiento crítico para la seguridad — feature flags que activan un kill switch, o cambios de control de acceso (revocar una credencial comprometida) — donde una lectura obsoleta significa que el comportamiento antiguo y peligroso sigue activo en algún sitio.
#Dónde la consistencia eventual no solo es aceptable sino preferible
- Contadores de redes sociales — likes, vistas, seguidores. A nadie le perjudica que un contador de likes esté desfasado por unos pocos durante unos segundos; bloquear cada acción de "like" con una escritura de quorum global sería un impuesto de latencia catastrófico sin ningún beneficio real.
- Datos de catálogo de producto — descripciones, imágenes, precios para navegación (no la comprobación final del precio en el checkout, que puede necesitar una lectura más fuerte). Un retraso de propagación de segundos es invisible para quien navega un catálogo.
- DNS — internet entero funciona con consistencia eventual para la resolución de nombres; los TTL acotan explícitamente la obsolescencia y todo el mundo ha aceptado que eso está bien.
- Contenido del carrito de compra — el propio paper de Dynamo de Amazon usaba el carrito como ejemplo canónico: está bien que una actualización del carrito sea eventualmente visible entre regiones, y las actualizaciones concurrentes en conflicto (añadiste un artículo desde el móvil y desde el portátil al mismo tiempo) se pueden fusionar en lugar de serializar.
- Frescura del índice de búsqueda, dashboards de analítica, feeds de actividad — un retraso de segundos a minutos es una propiedad aceptada, y muchas veces ni siquiera notada, de estos sistemas.
#Casi nunca es una única elección global
Los sistemas reales mezclan ambos modelos dentro de la misma aplicación, a veces dentro de la misma petición. Un patrón común es la consistencia de lectura-de-tus-propias-escrituras: después de que tú escribes, las lecturas posteriores tuyas se enrutan para ver tu propia escritura (mediante tokens de sesión o enrutamiento pegajoso), mientras que otros usuarios pueden seguir viendo el valor antiguo brevemente — un punto intermedio que resuelve la queja más visible sobre la consistencia eventual (publicar un comentario y no verlo aparecer) sin pagar el costo de la linealizabilidad global. Otro patrón habitual es usar un almacén fuertemente consistente para la pequeña porción de datos que realmente lo necesita (saldos de cuenta, reservas de inventario, estado de locks) y uno eventualmente consistente para todo lo demás (catálogo, feed de actividad, modelos de lectura desnormalizados), en lugar de forzar un único modelo de consistencia sobre todo el sistema.
🧠 Check your understanding
0/2 · 0/2 answered1. ¿Por qué un carrito de compra suele encajar bien con la consistencia eventual, mientras que el saldo de una cuenta normalmente no?
2. ¿Qué dice el teorema CAP que un sistema debe sacrificar durante una partición de red real?