02 - Componentes Clave de Infraestructura¶
Tabla de Contenidos¶
Balanceadores de Carga¶
Un balanceador de carga distribuye el tráfico entrante entre múltiples servidores backend para optimizar el uso de recursos, maximizar el throughput y garantizar alta disponibilidad.
Capas de Balanceo¶
graph TB
Client[Cliente] --> DNS[DNS Round Robin<br/>Capa 3]
DNS --> L4[L4 Load Balancer<br/>TCP/UDP - Capa 4]
L4 --> L7a[L7 Load Balancer<br/>HTTP - Capa 7]
L4 --> L7b[L7 Load Balancer<br/>HTTP - Capa 7]
L7a --> S1[App Server 1]
L7a --> S2[App Server 2]
L7b --> S3[App Server 3]
L7b --> S4[App Server 4]
Layer 4 vs Layer 7¶
| Característica | L4 (Transporte) | L7 (Aplicación) |
|---|---|---|
| Opera en | TCP/UDP | HTTP/HTTPS/gRPC |
| Inspecciona | IP + Puerto | Headers, cookies, URL, body |
| Velocidad | Muy rápido (no parsea contenido) | Más lento (parseo completo) |
| Funcionalidad | Básica | Routing por path, A/B testing, rate limiting |
| SSL Termination | No (pass-through) | Sí |
| Ejemplo | AWS NLB, HAProxy (modo TCP) | Nginx, AWS ALB, Envoy |
Algoritmos de Balanceo¶
1. Round Robin¶
Distribuye requests secuencialmente. Simple pero no considera la carga actual.
Request 1 → Server A
Request 2 → Server B
Request 3 → Server C
Request 4 → Server A (vuelta al inicio)
2. Weighted Round Robin¶
Servidores con más capacidad reciben más tráfico.
Server A (peso 5): recibe 5 de cada 8 requests
Server B (peso 2): recibe 2 de cada 8 requests
Server C (peso 1): recibe 1 de cada 8 requests
3. Least Connections¶
Envía al servidor con menos conexiones activas. Ideal cuando los requests tienen duración variable.
4. IP Hash¶
Hash de la IP del cliente para asignar siempre al mismo servidor. Útil para sticky sessions sin cookies.
5. Consistent Hashing¶
Distribuye carga en un anillo hash. Minimiza redistribución cuando se añaden/remueven servidores. Usado en CDNs y caches distribuidos.
graph TD
subgraph "Consistent Hash Ring"
direction TB
A((Server A<br/>pos: 0°))
B((Server B<br/>pos: 120°))
C((Server C<br/>pos: 240°))
end
K1[Key 1: 45°] -->|Siguiente en anillo| B
K2[Key 2: 200°] -->|Siguiente en anillo| C
K3[Key 3: 350°] -->|Siguiente en anillo| A
Health Checks¶
El balanceador debe verificar que los backend estén saludables:
- Activo: El LB envía requests periódicos (GET /health) y remueve servidores que no responden
- Pasivo: El LB monitorea las respuestas reales y detecta patrones de error (5xx consecutivos)
Alta Disponibilidad del Propio Load Balancer¶
El LB es un SPOF. Solución: par activo-pasivo con IP flotante (VRRP/keepalived).
graph TD
VIP[IP Virtual / Flotante] --> LB1[LB Primario - Activo]
VIP -.->|Failover| LB2[LB Secundario - Pasivo]
LB1 <-->|Heartbeat| LB2
LB1 --> Backend[Pool de Servidores]
LB2 -.-> Backend
Estrategias de Caching¶
El caching almacena copias de datos frecuentemente accedidos en una capa más rápida para reducir latencia y carga en el origen.
Niveles de Cache¶
graph LR
A[Cliente] --> B[Browser Cache]
B --> C[CDN Cache]
C --> D[API Gateway Cache]
D --> E[Application Cache<br/>Redis/Memcached]
E --> F[Database Cache<br/>Query Cache / Buffer Pool]
F --> G[Disco]
Patrones de Caching¶
1. Cache-Aside (Lazy Loading)¶
La aplicación gestiona el cache manualmente. Patrón más común.
sequenceDiagram
participant App
participant Cache
participant DB
App->>Cache: GET user:123
alt Cache HIT
Cache-->>App: Datos del usuario
else Cache MISS
Cache-->>App: null
App->>DB: SELECT * FROM users WHERE id=123
DB-->>App: Datos del usuario
App->>Cache: SET user:123 (con TTL)
end
Ventajas: Solo se cachea lo que se usa. Resiliente (si el cache cae, el sistema sigue funcionando. Desventajas: Cache miss = 3 viajes (check cache + query DB + write cache). Datos potencialmente stale.
2. Write-Through¶
Cada escritura va al cache Y a la DB simultáneamente.
sequenceDiagram
participant App
participant Cache
participant DB
App->>Cache: SET user:123
Cache->>DB: INSERT/UPDATE user:123
DB-->>Cache: OK
Cache-->>App: OK
Ventajas: Cache siempre consistente con DB. Desventajas: Mayor latencia en escrituras. Se cachean datos que quizá nunca se leen.
3. Write-Behind (Write-Back)¶
Las escrituras van solo al cache. El cache escribe a la DB de forma asíncrona.
Ventajas: Escrituras ultra rápidas. Batch writes a la DB. Desventajas: Riesgo de pérdida de datos si el cache falla antes de persistir.
4. Read-Through¶
Similar a cache-aside pero el cache se encarga de ir a la DB. La aplicación solo habla con el cache.
Redis vs Memcached¶
| Característica | Redis | Memcached |
|---|---|---|
| Estructuras de datos | Strings, Lists, Sets, Hashes, Sorted Sets, Streams | Solo strings (key-value) |
| Persistencia | RDB snapshots + AOF | No |
| Replicación | Sí (Redis Sentinel / Cluster) | No nativa |
| Pub/Sub | Sí | No |
| Lua scripting | Sí | No |
| Multi-thread | Single-thread (I/O threads desde v6) | Multi-thread |
| Memoria | Menos eficiente (overhead por estructuras) | Más eficiente para simple K/V |
| Caso de uso ideal | Sessions, leaderboards, queues, rate limiting | Cache simple de objetos/queries |
Políticas de Evicción¶
Cuando el cache se llena, se debe decidir qué descartar:
| Política | Descripción | Cuándo Usarla |
|---|---|---|
| LRU (Least Recently Used) | Elimina lo que no se accedió hace más tiempo | Uso general, buen default |
| LFU (Least Frequently Used) | Elimina lo que se accede con menos frecuencia | Workloads con hot keys estables |
| TTL (Time To Live) | Expira después de un tiempo fijo | Datos que cambian periódicamente |
| FIFO | Elimina el más antiguo | Raro en producción |
| Random | Elimina uno al azar | Sorprendentemente efectivo en algunos casos |
Cache Stampede (Thundering Herd)¶
Cuando una key popular expira y cientos de requests van simultáneamente a la DB.
Soluciones: 1. Locking: Solo un request reconstruye el cache, los demás esperan 2. Probabilistic early expiration: Renovar el cache antes de que expire 3. Stale-while-revalidate: Servir el valor expirado mientras se actualiza en background
Content Delivery Network (CDN)¶
Red de servidores distribuidos geográficamente que cachean contenido cerca del usuario final.
Arquitectura¶
graph TD
subgraph "Usuarios"
U1[Usuario Tokyo]
U2[Usuario NYC]
U3[Usuario London]
end
subgraph "Edge Servers (PoP)"
E1[PoP Tokyo]
E2[PoP NYC]
E3[PoP London]
end
subgraph "Origen"
O[Origin Server<br/>São Paulo]
end
U1 --> E1
U2 --> E2
U3 --> E3
E1 -->|Cache MISS| O
E2 -->|Cache MISS| O
E3 -->|Cache MISS| O
Pull CDN vs Push CDN¶
| Tipo | Funcionamiento | Cuándo Usarlo |
|---|---|---|
| Pull | El CDN obtiene el contenido del origen cuando se solicita por primera vez | Sitios con mucho contenido, tráfico moderado |
| Push | Tú subes el contenido al CDN proactivamente | Contenido que cambia con poca frecuencia, archivos grandes |
Headers de Cache Relevantes¶
# Cache en CDN y browser por 1 hora
Cache-Control: public, max-age=3600
# Cache solo en browser, no en CDN
Cache-Control: private, max-age=3600
# No cachear
Cache-Control: no-store
# Servir stale mientras revalida en background
Cache-Control: public, max-age=60, stale-while-revalidate=300
Invalidación de Cache en CDN¶
El mayor desafío de un CDN. Estrategias:
- Purge manual: API call para invalidar URLs específicas
- Cache busting: Incluir hash en el nombre del archivo (
app.a1b2c3.js) - TTL corto + stale-while-revalidate: Balance entre frescura y performance
- Versionado de URL:
/v2/api/resourceen vez de invalidar/v1/api/resource
CDNs Populares¶
| CDN | Fortaleza | Nota |
|---|---|---|
| CloudFlare | Workers (edge computing), DDoS protection | Free tier generoso |
| AWS CloudFront | Integración con S3/Lambda@Edge | Pay-per-use |
| Fastly | Purge instantáneo (~150ms), VCL | Ideal para contenido dinámico |
| Akamai | Red más grande (>300K servidores) | Enterprise |
Recursos Recomendados¶
- Libro: Web Scalability for Startup Engineers - Artur Ejsmont (Capítulos 3-5)
- Blog: Cloudflare Learning Center - "What is a CDN?"
- Paper: "Consistent Hashing and Random Trees" - Karger et al.
- Documentación: Redis University (redis.io/university) - Curso gratuito
- Video: ByteByteGo - "System Design: Load Balancer"
- Herramienta: wrk / k6 para benchmarking de throughput y latencia