Disponibilidad, resiliencia y recuperación en System Design | Nicolás Garzón
Un sistema resiliente no evita todos los fallos: limita su alcance, mantiene funciones esenciales y recupera un estado correcto con evidencia.
Disponibilidad mide si una capacidad puede utilizarse. Resiliencia describe cómo el sistema absorbe y aísla fallos. Recuperación define cómo restablece servicio y datos después de una interrupción.
En sistemas distribuidos, una dependencia puede estar lenta, responder parcialmente o fallar mientras otras continúan sanas. Sin límites, retries, pools compartidos y colas crecientes convierten un fallo local en una caída general.
Texto
Copiar fallo esperado
→ detectar
→ limitar propagación
→ degradar o fallar rápido
→ conservar estado recuperable
→ restaurar
→ verificar y aprenderNo todo el sistema tiene la misma criticidad. Puede ser válido que recomendaciones fallen mientras checkout sigue operativo.
Qué significa éxito.
Horario de servicio.
Dependencias.
Degradación aceptable.
Objetivo de disponibilidad.
Recuperación y datos tolerables.
Una llamada remota puede:
Rechazar inmediatamente.
Exceder timeout.
Responder parcialmente.
Confirmar el efecto y perder la respuesta.
Devolver datos obsoletos.
Recuperarse mientras el cliente sigue reintentando.
Diseñar solo “éxito o excepción” ignora estados reales.
Toda operación remota necesita límite. Un timeout debe considerar:
Presupuesto total de latencia.
Tiempo de conexión.
Lectura y escritura.
Variabilidad histórica.
Criticidad del flujo.
Posibilidad de cancelar trabajo downstream.
Un timeout demasiado alto consume recursos; uno demasiado bajo genera falsos fallos y retries.
Reintenta solo errores transitorios y cuando la operación es segura o idempotente.
Backoff exponencial.
Jitter.
Máximo de intentos.
Presupuesto global.
Respeto de Retry-After.
Observabilidad.
No reintentes validaciones, permisos o errores permanentes.
Una dependencia lenta provoca timeouts. Cada cliente reintenta y multiplica la carga, reduciendo aún más la capacidad.
Límites de retries.
Jitter.
Circuit breaker.
Load shedding.
Colas controladas.
Presupuestos compartidos.
Closed: permite tráfico y observa fallos.
Open: rechaza temporalmente para proteger recursos.
Half-open: deja pasar una muestra para comprobar recuperación.
No sustituye timeout, fallback ni monitoreo. Un breaker global puede ocultar que solo una operación o tenant falla.
Aíslan recursos para que un flujo no consuma todo:
Pools de conexiones separados.
Límites de concurrencia por proveedor.
Colas por prioridad.
Workers dedicados.
Presupuestos por tenant.
La separación añade capacidad reservada y configuración, pero evita cascadas.
Cuando el sistema está saturado, rechaza trabajo menos prioritario antes de colapsar.
Desactivar recomendaciones.
Limitar exportaciones.
Rechazar requests sin capacidad con respuesta clara.
Priorizar operaciones de escritura crítica.
Es preferible un rechazo controlado a mantener miles de solicitudes bloqueadas.
Una función alternativa debe preservar la intención principal.
Texto
Copiar recomendaciones caídas
→ mostrar productos populares cacheadosUn fallback incorrecto puede ser peor que fallar, especialmente en pagos, precios o permisos.
Tener varias instancias ayuda solo si no comparten el mismo punto de fallo. Revisa:
Zona.
Base de datos.
Red.
Configuración.
Credenciales.
Proveedor.
Pipeline de despliegue.
Dos réplicas en el mismo host no protegen contra fallo del host.
Tiempo objetivo para restaurar una capacidad.
Cantidad máxima de datos que puede perderse medida en tiempo.
Texto
Copiar RTO = 1 hora
RPO = 15 minutosEstos objetivos condicionan backups, replicación, runbooks y coste. No se definen de forma genérica para todo el sistema.
Réplica: copia cambios para lectura o failover; puede copiar corrupción.
Backup: permite recuperar un estado anterior.
Alta disponibilidad: reduce interrupción ante fallos previstos.
Disaster recovery: restaura servicio ante pérdida amplia de entorno.
Son controles complementarios.
Un backup solo es útil si puede restaurarse dentro del RTO y producir datos íntegros.
Cobertura.
Cifrado y acceso.
Retención.
Restauración automatizada.
Validación funcional.
Dependencias como secretos, archivos y configuraciones.
Procedimiento de promoción.
Qué detecta el fallo.
Quién promueve la réplica.
Cómo cambia routing.
Qué ocurre con escrituras inciertas.
Cómo se evita split brain.
Cómo se reincorpora el nodo anterior.
Qué datos pueden faltar.
Failover automático no siempre es mejor; una detección incorrecta puede causar dos primarios o pérdida.
Después de un fallo, el sistema suele repetir operaciones. Claves de idempotencia, versiones y registros de procesamiento permiten recuperar sin duplicar cobros, pedidos o movimientos.
Cuando no se conoce el resultado de un sistema externo:
Texto
Copiar payment = unknown
→ consultar proveedor
→ comparar con estado local
→ confirmar, compensar o escalarLos estados inciertos deben existir en el modelo; esconderlos como error genérico impide recuperación.
Inventario.
Pagos.
Pedidos.
Notificaciones.
Timeout por dependencia dentro del presupuesto.
Reserva idempotente.
Pago con clave de idempotencia.
Pedido con estado pending_payment o payment_unknown cuando corresponda.
Notificación asíncrona, no bloqueante.
Reconciliación de pagos inciertos.
Circuit breaker aislado para recomendaciones, no para todo checkout.
Reduce impacto de una zona. Requiere que datos, balanceo y dependencias también toleren la pérdida.
Puede mejorar recuperación regional o latencia, pero añade replicación, routing, consistencia, operación y coste. Debe justificarse por RTO/RPO o negocio.
Threads o conexiones quedan bloqueados.
Retries multiplican carga.
Health checks causan reinicios.
Una cola consume toda la memoria.
Un proveedor compartido falla.
Un fallback consulta otra dependencia saturada.
El diseño debe modelar capacidad y límites durante fallo, no solo durante estado sano.
Prueba hipótesis de manera controlada:
Matar instancias.
Añadir latencia.
Cortar red.
Saturar pools.
Duplicar mensajes.
Restaurar backups.
Ejecutar failover.
Empieza en entornos seguros y con criterios de abortar. El objetivo es aprender, no causar caos por espectáculo.
Síntoma y alcance.
Cómo confirmar.
Acciones seguras.
Decisiones y responsables.
Rollback.
Validación posterior.
Escalamiento.
Debe probarse y mantenerse, no existir solo como documento.
Puede agotar recursos más rápido que un error inmediato.
La compensación también necesita retry e idempotencia.
Base recuperada, pero objetos o eventos faltan. Verifica el sistema completo.
Failover puede perder escrituras recientes según RPO.
Dos nodos aceptan escrituras y divergen. Requiere fencing y coordinación.
Código, esquema y eventos deben ser compatibles con el punto restaurado.
Retries sin límites.
No usar timeouts.
Circuit breaker como solución universal.
Réplicas confundidas con backup.
RTO/RPO inventados sin prueba.
Fallback que devuelve información incorrecta.
Health checks demasiado agresivos.
Runbook no ejecutado.
Alta disponibilidad dibujada pero no probada.
Ignorar estados inciertos.
Enumera dependencias y modos de fallo.
Define comportamiento por capacidad.
Calcula presupuestos de timeout y retry.
Prueba saturación y aislamiento.
Ejecuta restore y failover.
Verifica RTO/RPO reales.
Simula respuestas perdidas y duplicados.
Comprueba degradación y mensajes al usuario.
Revisa observabilidad y runbooks.
Realiza postmortems sin culpa y convierte hallazgos en cambios.
Mayor disponibilidad suele aumentar coste, complejidad y operación. No todas las funciones necesitan la misma redundancia. Una arquitectura más simple y bien recuperable puede ser mejor que una topología altamente distribuida que el equipo no puede operar.
Fallar lento puede ser peor que fallar rápido.
Retries necesitan idempotencia y presupuesto.
Aislar recursos limita cascadas.
Réplica, backup y DR son diferentes.
Estados inciertos requieren reconciliación.
RTO y RPO deben probarse.
¿Por qué una dependencia lenta puede ser más peligrosa que una caída?
¿Qué diferencia existe entre RTO y RPO?
¿Por qué un fallback puede ser inseguro?
¿Qué evita split brain durante failover?
Ver respuestas
Mantiene recursos ocupados y puede saturar toda la aplicación.
RTO limita tiempo de recuperación; RPO limita pérdida de datos.
Puede devolver precios, permisos o decisiones incorrectas.
Coordinación, fencing y una única autoridad de escritura.
Observabilidad y operación define las señales necesarias para detectar impacto, diagnosticar causas y ejecutar recuperación.