La alta disponibilidad (HA, High Availability) es la propiedad de un sistema que sigue prestando servicio aunque fallen algunos de sus componentes. En el mundo real el hardware se rompe, las redes se cortan y el software tiene errores: la pregunta no es si algo fallará, sino cuándo. Un sistema bien diseñado asume el fallo como algo normal y se prepara para sobrevivir a él. En esta lección aprenderás a medir la disponibilidad con SLA, SLO y SLI, entenderás qué significan "los nueves" de disponibilidad, y verás las técnicas que hacen posible que un sistema resista fallos: redundancia, failover automático, degradación elegante y comprobaciones de salud (health checks).
Contenido
- SLA, SLO y SLI: el lenguaje de la disponibilidad
- Los nueves de disponibilidad
- Redundancia: eliminar los puntos únicos de fallo
- Failover: conmutación automática ante fallos
- Degradación elegante (graceful degradation)
- Health checks: detectar que algo va mal
- Errores comunes y consejos
- Ejercicios
- SLA, SLO y SLI: el lenguaje de la disponibilidad
Para hablar de disponibilidad con rigor necesitamos tres conceptos que suelen confundirse:
| Término | Qué es | Quién lo fija | Ejemplo |
|---|---|---|---|
| SLI (Indicator) | La métrica que mides | Equipo técnico | % de peticiones con respuesta < 300 ms |
| SLO (Objective) | El objetivo interno sobre el SLI | Equipo/Producto | "99,9% de peticiones OK al mes" |
| SLA (Agreement) | El compromiso contractual con el cliente | Negocio/Legal | "99,5% o devolvemos dinero" |
La relación es jerárquica: el SLI es la medición cruda, el SLO es la meta que te pones internamente, y el SLA es la promesa formal al cliente (con penalizaciones si se incumple). Por prudencia, el SLA siempre se fija por debajo del SLO: si tu objetivo interno es 99,9% pero prometes 99,5%, tienes margen de seguridad.
De aquí nace un concepto clave: el presupuesto de error (error budget). Si tu SLO es 99,9% mensual, te "permites" un 0,1% de fallos. Ese 0,1% es presupuesto que puedes gastar en desplegar cambios arriesgados. Si lo agotas, congelas los despliegues y te centras en estabilidad.
Presupuesto de error mensual con SLO = 99,9% Tiempo total del mes: 30 días = 43.200 minutos Disponibilidad exigida: 99,9% Tiempo de caída permitido: 0,1% de 43.200 = 43,2 minutos/mes
Es decir, con un SLO de 99,9% puedes estar caído como máximo 43 minutos al mes sin incumplir tu objetivo.
- Los nueves de disponibilidad
La disponibilidad se expresa como porcentaje de tiempo en servicio, y coloquialmente se cuenta por "nueves". Cada nueve adicional reduce drásticamente el tiempo de caída permitido y multiplica el coste.
| Disponibilidad | "Nueves" | Caída al año | Caída al mes | Caída a la semana |
|---|---|---|---|---|
| 90% | un nueve | 36,5 días | 72 horas | 16,8 horas |
| 99% | dos nueves | 3,65 días | 7,2 horas | 1,68 horas |
| 99,9% | tres nueves | 8,76 horas | 43,2 min | 10,1 min |
| 99,99% | cuatro nueves | 52,6 min | 4,32 min | 1,01 min |
| 99,999% | cinco nueves | 5,26 min | 25,9 seg | 6,05 seg |
Los cinco nueves (99,999%) son legendarios en telecomunicaciones, pero exigen una inversión enorme: redundancia total, varios centros de datos, automatización completa. La pregunta de arquitectura no es "¿cuántos nueves puedo conseguir?" sino "¿cuántos nueves necesita realmente el negocio y está dispuesto a pagar?". Pasar de 99,9% a 99,99% puede multiplicar el coste por diez para ahorrar unas pocas horas al año.
- Redundancia: eliminar los puntos únicos de fallo
Un punto único de fallo (SPOF, Single Point Of Failure) es cualquier componente cuya caída tumba todo el sistema. La base de la alta disponibilidad es eliminar los SPOF mediante redundancia: tener más de una copia de cada componente crítico.
Existen dos modelos de redundancia:
| Modelo | Descripción | Ventaja | Inconveniente |
|---|---|---|---|
| Activo-Pasivo | Una réplica activa y otra en espera | Sencillo, sin conflictos | La réplica pasiva está ociosa |
| Activo-Activo | Todas las réplicas atienden tráfico | Aprovecha todos los recursos | Más complejo (sincronización) |
graph TD
LB[Balanceador] --> A[Nodo A - activo]
LB -.standby.-> B[Nodo B - pasivo]
A --> DBp[(BD Primaria)]
DBp -.replicación.-> DBs[(BD Réplica)]En este esquema activo-pasivo, el nodo B solo entra en juego si A cae, y la base de datos réplica recibe una copia continua de los datos para poder sustituir a la primaria. La regla práctica: identifica cada componente y pregúntate "¿qué pasa si esto cae?". Si la respuesta es "se cae todo", tienes un SPOF que debes replicar.
- Failover: conmutación automática ante fallos
Tener redundancia no sirve de nada si nadie la activa cuando hace falta. El failover es el proceso de detectar el fallo de un componente y conmutar automáticamente a su réplica. Dos métricas definen su calidad:
- RTO (Recovery Time Objective): cuánto tiempo tardamos en recuperar el servicio. ¿Segundos? ¿Minutos?
- RPO (Recovery Point Objective): cuántos datos podemos permitirnos perder, medido en tiempo. ¿La última transacción? ¿Los últimos 5 minutos?
Fallo
|
----[ datos a salvo ]----X----[ servicio caído ]----[ servicio recuperado ]----
<----- RPO -----> <-------- RTO -------->
(datos perdidos) (tiempo sin servicio)Un RPO de cero significa "no perder ningún dato" (requiere replicación síncrona, más lenta). Un RTO de segundos requiere failover totalmente automatizado.
# Ejemplo: failover gestionado por health checks en un balanceador (HAProxy) backend servidores_web option httpchk GET /health # Comprueba salud con GET /health default-server inter 2s fall 3 rise 2 server web1 10.0.0.1:8080 check # Comprobado activamente server web2 10.0.0.2:8080 check backup # Solo se usa si web1 cae
Explicación: option httpchk GET /health indica que HAProxy llamará periódicamente al endpoint /health de cada servidor. inter 2s comprueba cada 2 segundos; fall 3 marca el servidor como caído tras 3 fallos seguidos; rise 2 lo reactiva tras 2 éxitos. El web2 ... backup solo recibe tráfico cuando web1 está caído: esto es failover automático activo-pasivo.
- Degradación elegante (graceful degradation)
A veces no se puede mantener todo el servicio, pero sí una parte. La degradación elegante consiste en seguir ofreciendo la funcionalidad esencial aunque se pierdan funciones secundarias, en lugar de caer por completo. Es preferible un servicio "a medio gas" que una pantalla de error.
Ejemplo: si el servicio de recomendaciones de una tienda cae, la web debe seguir vendiendo, simplemente sin mostrar recomendaciones.
// Patrón de degradación con un valor de reserva (fallback)
public List<Producto> obtenerRecomendaciones(String userId) {
try {
// Intentamos llamar al servicio de recomendaciones
return servicioRecomendaciones.recomendar(userId);
} catch (ServicioNoDisponibleException e) {
// Si falla, NO rompemos la página: devolvemos los más vendidos.
log.warn("Recomendaciones no disponibles, usando fallback", e);
return catalogo.masVendidos();
}
}Aquí, si el servicio de recomendaciones no responde, capturamos la excepción y devolvemos una lista alternativa (los más vendidos) en lugar de propagar el error al usuario. La página sigue funcionando, solo que con una experiencia ligeramente reducida.
Este patrón se combina a menudo con el Circuit Breaker (cortacircuitos): si un servicio falla repetidamente, el cortacircuitos "se abre" y deja de llamarlo durante un tiempo, devolviendo directamente el fallback. Así se evita saturar un servicio ya enfermo y se acelera la respuesta.
- Health checks: detectar que algo va mal
No puedes reaccionar a un fallo que no detectas. Los health checks (comprobaciones de salud) son endpoints que informan del estado de una instancia. Se distinguen dos tipos esenciales en orquestadores como Kubernetes:
| Tipo | Pregunta que responde | Qué pasa si falla |
|---|---|---|
| Liveness | ¿Está vivo el proceso? | Se reinicia el contenedor |
| Readiness | ¿Está listo para recibir tráfico? | Se le deja de enviar tráfico (sin reiniciar) |
La distinción es crucial: una instancia puede estar viva pero no lista (por ejemplo, arrancando o reconectando a la base de datos). En ese caso no queremos reiniciarla (liveness OK), pero sí dejar de mandarle peticiones (readiness KO).
# Sondas de salud en un Pod de Kubernetes
livenessProbe:
httpGet:
path: /health/live # ¿El proceso sigue vivo?
port: 8080
initialDelaySeconds: 10 # Espera 10s tras arrancar antes de la 1ª sonda
periodSeconds: 5 # Comprueba cada 5 segundos
readinessProbe:
httpGet:
path: /health/ready # ¿Puede atender peticiones?
port: 8080
periodSeconds: 5Línea a línea: la livenessProbe llama a /health/live; si falla, Kubernetes reinicia el contenedor. El initialDelaySeconds: 10 evita reinicios prematuros mientras la app arranca. La readinessProbe llama a /health/ready; si falla, Kubernetes retira ese Pod del balanceo pero lo deja vivo para que se recupere. Un buen /health/ready debe comprobar las dependencias críticas (base de datos, colas) y no limitarse a devolver "OK" siempre.
Errores Comunes y Consejos
- Confundir SLA, SLO y SLI. Recuerda: SLI mides, SLO te propones, SLA prometes. El SLA va siempre por debajo del SLO.
- Perseguir nueves innecesarios. Cada nueve adicional cuesta muchísimo más. Ajusta la disponibilidad a la necesidad real del negocio.
- Redundancia que comparte SPOF oculto. Dos nodos en el mismo rack, con la misma fuente de alimentación o el mismo proveedor cloud comparten un punto de fallo. La verdadera redundancia distribuye los riesgos.
- Health check trivial. Un
/healthque siempre devuelve 200 es inútil: debe comprobar de verdad las dependencias críticas. - No probar nunca el failover. Un mecanismo de failover que no se ensaya periódicamente probablemente no funcionará el día real. Practica con simulacros (Chaos Engineering).
- Consejo: asume que todo fallará y diseña para ello. La fiabilidad se construye, no se espera.
Ejercicios
-
Cálculo de disponibilidad. Tu sistema estuvo caído 4 horas en un año. ¿Qué disponibilidad porcentual ofreciste y a cuántos "nueves" equivale aproximadamente?
-
Diseño de health checks. Un servicio se reinicia en bucle continuamente. Al investigar, ves que su
livenessProbeapunta a un endpoint que comprueba la conexión a una base de datos lenta que tarda en arrancar. ¿Qué está mal y cómo lo arreglarías? -
Estrategia de continuidad. Define un RTO y un RPO razonables para (a) un blog corporativo y (b) un sistema de pagos bancario, justificando la diferencia.
Soluciones
-
Hay 8.760 horas en un año. Disponibilidad = (8.760 - 4) / 8.760 = 8.756 / 8.760 = 99,954%. Eso supera los tres nueves (99,9% permitía 8,76 h) pero no llega a cuatro nueves (99,99% solo permitía 52,6 min). Está, por tanto, entre tres y cuatro nueves.
-
El error es que la liveness probe comprueba una dependencia externa lenta. Mientras la base de datos arranca, la sonda falla, Kubernetes cree que el proceso está muerto y lo reinicia, entrando en bucle. Solución: la liveness solo debe comprobar que el proceso responde (algo trivial y rápido); la comprobación de la base de datos pertenece a la readiness probe, que retira el Pod del tráfico sin reiniciarlo. Conviene además ajustar
initialDelaySeconds. -
(a) Blog corporativo: RTO de horas y RPO de horas (incluso un día) son aceptables; perder el último artículo o estar caído un rato no es crítico, prima el bajo coste. (b) Pagos bancario: RTO de segundos/minutos y RPO de cero; no se puede perder ninguna transacción ni dejar de operar, lo que justifica replicación síncrona y failover automático aunque sea caro. La diferencia refleja el impacto de negocio de cada caída.
Conclusión
Has aprendido a medir la disponibilidad (SLI/SLO/SLA y los nueves), a entender su coste creciente, y a aplicar las técnicas que hacen un sistema resistente: redundancia para eliminar SPOF, failover para conmutar automáticamente, degradación elegante para no caer del todo, y health checks para detectar los problemas a tiempo. La alta disponibilidad es, en esencia, asumir que el fallo es inevitable y diseñar para que el usuario apenas lo note.
Un sistema disponible pero inseguro es un sistema vulnerable. En la siguiente lección, Seguridad por Diseño y Autenticación/Autorización, veremos cómo proteger la aplicación frente a ataques desde el primer momento del diseño.
Curso de Arquitectura de Aplicaciones
Módulo 1: Fundamentos de la Arquitectura de Aplicaciones
- ¿Qué es la Arquitectura de Aplicaciones?
- El Rol del Arquitecto de Software
- Atributos de Calidad y Requisitos No Funcionales
- Decisiones Arquitectónicas y Compromisos (Trade-offs)
- Documentación de Arquitectura: Vistas y el Modelo C4
Módulo 2: Principios y Tácticas de Diseño
- Acoplamiento, Cohesión y Separación de Responsabilidades
- Principios SOLID Aplicados a la Arquitectura
- DRY, KISS, YAGNI y Otros Principios de Diseño
- Tácticas Arquitectónicas para los Atributos de Calidad
- Gestión de la Deuda Técnica
Módulo 3: Estilos y Patrones Arquitectónicos
- Arquitectura Monolítica
- Arquitectura en Capas (N-Tier)
- Arquitectura Cliente-Servidor
- Arquitectura Hexagonal (Puertos y Adaptadores)
- Arquitectura Limpia y Cebolla (Clean & Onion)
Módulo 4: Arquitecturas Distribuidas y Microservicios
- Introducción a los Sistemas Distribuidos
- Arquitectura de Microservicios
- Descomposición de Servicios y Bounded Contexts
- API Gateway, Service Discovery y Comunicación entre Servicios
- Patrones de Resiliencia: Circuit Breaker, Retry y Bulkhead
- El Teorema CAP y la Consistencia de Datos
Módulo 5: Arquitecturas Dirigidas por Eventos y Mensajería
- Fundamentos de la Arquitectura Orientada a Eventos
- Mensajería Asíncrona: Colas y Brokers
- Patrones de Eventos: Event Sourcing y CQRS
- Gestión de Transacciones Distribuidas: Patrón Saga
- Streaming de Datos en Tiempo Real
Módulo 6: Diseño Dirigido por el Dominio (DDD)
- Conceptos Fundamentales del DDD
- Diseño Estratégico: Bounded Contexts y Lenguaje Ubicuo
- Diseño Táctico: Entidades, Agregados y Repositorios
- Mapeo de Contextos (Context Mapping)
Módulo 7: Datos y Persistencia
- Estrategias de Persistencia: SQL vs NoSQL
- Patrones de Acceso a Datos: Repository, Unit of Work y DAO
- Base de Datos por Servicio y Gestión de Datos Distribuidos
- Caché y Estrategias de Invalidación
Módulo 8: Arquitectura en la Nube y Despliegue
- Fundamentos del Cloud Computing (IaaS, PaaS, SaaS)
- Contenedores y Orquestación con Docker y Kubernetes
- Arquitectura Serverless
- Patrones de Diseño Cloud-Native
- Infraestructura como Código (IaC)
Módulo 9: Calidad, Seguridad y Observabilidad
- Escalabilidad: Horizontal vs Vertical y Balanceo de Carga
- Alta Disponibilidad y Tolerancia a Fallos
- Seguridad por Diseño y Autenticación/Autorización
- Observabilidad: Logging, Métricas y Trazabilidad
- Rendimiento y Pruebas de Carga
