Episodio 5

El cajero sin conexión

lectura · 14 mindominio · BCPS Bankoperación · retirada en cajero sin conexión

Un sábado en el pueblo

Ana se ha ido de fin de semana a un pueblo de montaña. Hay un solo cajero, y una tormenta ha cortado la línea que lo une con el banco. Ana mete la tarjeta y pide 100 €. El cajero tiene los billetes; lo que no tiene es forma de preguntar si en la cuenta de gastos hay saldo. ¿Se los da?

Si dice que no, Ana se queda sin dinero todo el fin de semana, aunque tenga de sobra. Si dice que sí, puede que el saldo ya no exista: Luis, en la ciudad, podría estar sacándolo en ese mismo momento. No hay una respuesta técnica correcta. Hay que elegir, y el teorema más citado de los sistemas distribuidos dice exactamente eso: que hay que elegir.

En la serie de resiliencia, Tarjetas autorizaba pagos de hasta 50 € cuando Antifraude no contestaba. Quedó dicho que esa decisión tenía nombre. Es este.

Cortar la red

La cuenta de gastos tiene 400 €. A la izquierda, un cajero que sin conexión no entrega dinero; a la derecha, uno que entrega hasta un límite y apunta lo que ha dado. Corta la red y haz que Ana saque; luego, que Luis vacíe la cuenta desde la ciudad, y que vuelva la conexión. Después cambia la situación a «sin corte»: ya no hay tormenta, pero Cuentas tiene una réplica en otra ciudad, y la app de Luis lee de ella.

Qué ha pasado

CAP: cuando la red se parte

El teorema CAP dice que un sistema repartido en varios sitios no puede garantizar a la vez tres cosas: consistencia (todos ven el mismo dato, el último), disponibilidad (todo el que pregunta recibe respuesta) y tolerancia a particiones (seguir funcionando cuando la red entre los sitios se corta). Y como las particiones pasan, quieras o no, la elección real es la que aparece cuando pasan: consistencia o disponibilidad.

El cajero de la izquierda elige consistencia (CP):probar en el laboratorio sin preguntar al banco no puede saber el saldo, así que espera, no recibe respuesta y no entrega nada. El de la derecha elige disponibilidad (AP): entrega el dinero y apunta la retirada para mandarla cuando vuelva la red. Ojo: la «consistencia» de CAP no es la C de ACID del episodio 1. Aquí significa que todos los sitios ven el mismo valor.

La doble retirada y el riesgo acotado

Mientras el cajero del pueblo no puede avisar, Luis saca 400 € en la ciudad, donde sí hay conexión.probar en el laboratorio El banco central le deja, porque para él la cuenta tiene 400 €: no sabe nada de los 100 € de Ana. Cuando vuelve la red, llegan los apuntes del pueblo, y la cuenta queda en −100 €. Las dos réplicas del saldo, la del cajero y la del banco, se separaron durante el corte, y al juntarse no cuadran.

No es un fallo: es lo que el banco ha decidido asumir. El límite de 150 € por tarjeta mientras dure el corte es el riesgo acotado: el peor caso es un descubierto de 150 €, que se concilia con un movimiento y, si hace falta, se reclama. Es el mismo razonamiento que el stand-in de Tarjetas en resiliencia, y el que usan las redes de cajeros de verdad.

Por eso el límite no lo decide un ingeniero.probar en el laboratorio Con 500 € sin conexión, el fin de semana de Ana es más cómodo y el descubierto posible, mucho mayor. Cuánto riesgo es aceptable depende del fraude, de los clientes y de cuánto cuesta un cliente enfadado. Y fíjate en lo que es en realidad «AP con límite»: AP por debajo del límite y CP por encima. El banco no elige un extremo; elige por importe.

PACELC: cuando la red funciona

CAP solo habla de lo que pasa durante un corte, que es poco tiempo. PACELC completa la frase: si hay partición (P), disponibilidad o consistencia (A o C); si no (E, de else), latencia o consistencia (L o C). Porque aunque no haya ninguna tormenta, copiar un dato a otro sitio lleva tiempo.

Sin corte, Cuentas tiene una réplica en otra ciudad por si el centro de datos principal se cae.probar en el laboratorio A la izquierda (EC), el COMMIT de cada retirada espera a que la réplica confirme: la réplica siempre está al día, y cada retirada paga el viaje de ida y vuelta. A la derecha (EL), el COMMIT responde enseguida y la réplica se entera después: más rápido, pero durante un rato va por detrás. Si la app de Luis lee de ella justo entonces, ve un saldo que ya no existe. Con la réplica en otro continente,probar en el laboratorio esperar deja de ser barato.

Qué ve Luis: los modelos de consistencia

«Consistente» o «no consistente» se queda corto. Entre los dos extremos hay un espectro, y cada punto promete algo concreto:

Hay más puntos en el espectro (lecturas monótonas, consistencia causal), y retraso de réplica, lecturas que «vuelven atrás» y CDC dan para una serie entera: la de separar lecturas y escrituras, que viene después.

Criterio

Cuando…Elegir consistenciaElegir disponibilidad o latencia
Hay particiónCP: rechazar (el cajero no entrega)AP: aceptar y conciliar después, con un límite
No la hayEC: esperar a las réplicasEL: responder ya; las réplicas van detrás
CuestaClientes sin servicio; latencia en cada escrituraDescubiertos y conflictos que hay que conciliar; lecturas viejas
  1. ¿Se puede deshacer o compensar el error después, y el peor caso está acotado?Un descubierto de 150 € se concilia; entregar 10.000 € sin saldo, no.
    AP con un límite
  2. ¿Alguien va a decidir algo importante con lo que lee?Luis va a sacar dinero según el saldo que ve en la app.
    leer del primario, o read-your-writes como mínimo
  3. ¿Las copias están lejos y se escribe mucho?
    EL, y asumir el retraso donde no importe

Lo que no vale es no elegir: un sistema que no ha decidido qué hacer durante un corte lo decide igual, por accidente, el día que llega. Y la alternativa de coordinar a todos los sitios antes de confirmar nada, el commit en dos fases, es el camino que el banco no toma entre sistemas distintos: si el coordinador cae a mitad, todos se quedan esperando. Para eso está la saga del episodio 4 de la serie de eventos.

En el mundo real

Los cajeros y las redes de tarjetas funcionan así de verdad: cuando el emisor no responde, la red o el propio terminal autorizan por debajo de un límite (stand-in processing, floor limits) y las operaciones se liquidan después. Los descubiertos que salen de ahí son un coste conocido del negocio.

CAP lo formuló Eric Brewer en el año 2000 y lo demostraron Gilbert y Lynch en 2002; PACELC lo propuso Daniel Abadi en 2010. Según Abadi, Dynamo, Cassandra y Riak son PA/EL por defecto, y los sistemas totalmente consistentes, como VoltDB o Megastore, PC/EC. PostgreSQL y MySQL dejan elegir por transacción o por sesión si esperar a las réplicas (synchronous_commit, replicación semisíncrona).

MongoDB y Cassandra exponen la elección en cada operación, con write concern y read concern o niveles de consistencia (ONE, QUORUM, ALL): cuántas réplicas tienen que confirmar una escritura y cuántas se consultan al leer. Es la misma decisión de este episodio, tomada petición a petición.

Final de la serie

Hemos ido de lo más pequeño a lo más grande. Una transacción que hace todo o nada. Dos que se pisan si nadie las aísla, y los niveles que deciden cuánto. Bloquear o reintentar. Versiones para que leer no espere. Y, fuera de la base de datos, la red que se corta y la réplica que va por detrás. En cada paso, la misma idea: cada garantía se paga, en espera, en reintentos o en disponibilidad, y el diseño consiste en decidir dónde se compra cuánta.

Queda una pregunta abierta: ¿qué pasa con los datos que salen de Cuentas hacia Reporting, el extracto mensual y los informes? Réplicas de lectura, retraso, change data capture y la distancia entre la base de datos operacional y la de análisis. Es otra serie.

Siguiente serie · Separar lecturas y escrituras El día de cobro Réplicas de lectura, síncrona o asíncrona, retraso de réplica, CDC y OLTP frente a OLAP.

← Todos los episodios · Cuentas en el mapa de BCPS Bank