Thundering Herd
Qué es
Thundering Herd es la activación casi simultánea de muchos clientes, workers o procesos debido a un mismo evento o condición. Los actores intentan avanzar juntos y concentran demanda sobre un recurso compartido. El fenómeno se caracteriza por sincronización masiva, aunque cada actor siga una política individual razonable y no haya ocurrido ningún reintento.
shared cache entry expires
-> 10,000 clients observe a miss in a short interval
-> many attempt the same backend fetch
-> concentrated demand and contentionUn burst no demuestra por sí solo un herd: puede reflejar muchas intenciones independientes. Para reconocerlo, buscar una condición común que alinea las activaciones. La concentración puede ser breve y absorbible, o suficiente para iniciar overload. Ni «muchos» ni «simultáneo» requieren un umbral universal; importa su escala frente a la capacidad y la ventana temporal del recurso.
Eventos que alinean actores
| Evento compartido | Trabajo concentrado |
|---|---|
| Expiración o invalidación de cache | Consultas para regenerar el mismo dato. |
| Temporizador de retry idéntico | Nuevas tentativas dentro del mismo intervalo. |
| Dependencia disponible otra vez | Reconexiones, adquisiciones y reintroducción de pendientes. |
| Liberación de un lock o notificación masiva | Workers que despiertan y compiten por pocos permisos. |
| Inicio de una tarea programada | Lotes que consultan simultáneamente recursos comunes. |
| Nuevas instancias o recuperación de una flota | Registro, inicialización y calentamiento de caches. |
| Disponibilidad de un líder | Clientes pendientes que vuelven a descubrirlo o invocarlo. |
Estos escenarios no siempre producen una falla. Si el recurso tiene margen y los límites contienen el trabajo, puede atender la concentración. Lo que necesita análisis es la relación entre el evento común, el número de actores, el costo de cada activación y el reparto temporal.
Cache misses y trabajo redundante
Si una clave popular desaparece, varias solicitudes pueden intentar reconstruirla antes de que termine la primera. Cada una ve un miss legítimo, pero ejecutar todas las consultas duplica trabajo equivalente. El backend recibe demanda que la cache normalmente amortiguaba.
El paper Scaling Memcache at Facebook describe leases para arbitrar reconstrucción y reducir thundering herds tras invalidaciones. Su resultado respalda coordinar quién hace el trabajo compartido; no implica que cualquier cache o lease tenga esa misma garantía. Scaling Memcache at Facebook, sección 3.2.1.
AWS describe request coalescing para reducir consultas concurrentes a un recurso no cacheado. Caching challenges and strategies. Coalescer solicitudes equivalentes puede permitir una ejecución y varios observadores. Su scope importa: hacerlo por proceso deja una consulta por cada instancia, no una consulta global. Además necesita una regla si el regenerador falla, límites para los que esperan y una identidad de dato que no mezcle resultados entre tenants.
Servir un valor previo mientras se actualiza puede reducir presión cuando su vigencia es aceptable. No corresponde usar datos stale para cualquier decisión de negocio. Coordinar todo mediante un lock central también agrega un recurso cuyo fallo o latencia puede trasladar el problema.
Temporizadores, reconnects y mass wakeups
Esperar el mismo intervalo después de un error puede alinear una población que antes estaba dispersa. Reiniciar todos los clientes juntos o resetear su backoff puede recrear esa alineación. backoff modifica frecuencia; jitter distribuye instantes y necesita una ventana significativa frente al tamaño de la población.
AWS muestra que exponential backoff sin jitter conserva grupos de llamadas concentradas en su modelo. La variación temporal reduce esa sincronización, sin reemplazar límites de trabajo total. Exponential Backoff and Jitter.
Una notificación que despierta mil workers cuando solo hay un permiso disponible también concentra competencia. El efecto puede ser principalmente local: coordinación, CPU y cambios de contexto, sin mil operaciones remotas exitosas. Despertar selectivamente puede ahorrar trabajo, pero debe preservar progreso y evitar dejar recursos disponibles sin consumidor.
Una recuperación tampoco devuelve inmediatamente capacidad completa. Reconectar implica handshakes, autenticación y estado; una instancia nueva puede necesitar calentarse. Autoscaling o disponibilidad del líder pueden coincidir con backlog acumulado y tráfico normal, generando una demanda inicial mayor que la capacidad recién añadida.
Diferencias con otros fenómenos
Thundering Herd no equivale a retry-storms. El herd se centra en activaciones sincronizadas; la tormenta, en feedback donde repetir mantiene o agrava la degradación. Una expiración de cache puede producir un herd de primeras consultas sin retries. Una tormenta puede persistir con clientes desfasados.
Thundering Herd no equivale a cascading-failures. La cascada propaga degradación entre componentes; la sincronización concentra demanda. Un herd puede sobrecargar una DB y luego iniciar una cascada, pero el paso causal necesita explicarse.
metastable-failures añade persistencia autosostenida tras retirar el trigger. Una ráfaga que termina y permite recuperación normal no demuestra metastabilidad. Estos conceptos pueden describir aspectos diferentes de un mismo incidente sin convertirse en sinónimos.
Contención y prevención
rate-limiting puede regular el paso por una frontera, pero límites por cliente no garantizan una tasa global segura. admission-control puede rechazar o diferir nuevos compromisos según recursos disponibles. flow-control puede acotar tránsito entre participantes y queue-management necesita resolver lo que espera.
Distribuir expiraciones, tareas periódicas o reconexiones reduce coincidencia cuando el contrato admite variación. AWS Builders’ Library analiza jitter también para trabajo periódico, no solo para retries. Timeouts, retries, and backoff with jitter.
La aleatoriedad no crea capacidad ni garantiza fairness. Si se dispersan diez mil consultas sobre una ventana demasiado pequeña, el backend sigue desbordado. Si la tarea tiene un instante de negocio obligatorio, retrasarla indiscriminadamente puede violar su utilidad. Es necesario limitar concurrencia o coordinar trabajo equivalente cuando el tiempo no es flexible.
Recuperación y ejemplo
En Order → Payment, Payment vuelve a estar disponible y miles de callers intentan reconectar y enviar pedidos pendientes. Mantener admisión acotada, distribuir pruebas y ampliar gradualmente la carga permite evaluar capacidad antes de liberar todo. Reconectar a la vez que drenar backlog puede agotar recursos aunque Payment ya no tenga el fallo inicial.
Un circuit-breaker no evita automáticamente ese escenario: varias instancias pueden pasar a pruebas o cerrar juntas. Restaurar la dependencia y retirar todas las protecciones al mismo tiempo convierte recuperación en otro evento sincronizador.
Observar activaciones por intervalo, correlación con expiraciones o eventos comunes, consultas equivalentes, permisos, espera y goodput. Usar el concepto para razonar sobre concentración temporal; no para explicar todo tráfico alto. Las mitigaciones tienen costo de coordinación, demora y complejidad. failure-dynamics conecta esa pregunta con amplificación, propagación y alcance.