8 puntos por GN⁺ 2026-02-25 | Aún no hay comentarios. | Compartir por WhatsApp
  • Uber construyó un Global Rate Limiter (GRL) para establecer un sistema unificado de protección contra sobrecargas en un entorno de miles de microservicios que procesan cientos de millones de RPC por segundo
  • GRL utiliza una arquitectura de bucle de retroalimentación de 3 niveles compuesta por cliente, agregador y controlador, que permite decidir localmente sobre las solicitudes y aun así coordinarse globalmente en cuestión de segundos
  • Al pasar del enfoque inicial de token bucket a un modelo probabilístico de descarte, resolvió problemas de equidad y escalabilidad y minimizó la latencia en la ruta crítica
  • En comparación con limitadores basados en Redis, la latencia P99.5 mejoró hasta en 90%, y también absorbió aumentos de tráfico de 15x y ataques DDoS sin degradación del servicio
  • Rate Limit Configurator (RLC) analiza patrones históricos de tráfico y actualiza automáticamente los límites, haciendo evolucionar el sistema desde configuraciones estáticas hacia uno autoajustable

Problemas del rate limiting tradicional

  • En el entorno inicial de microservicios de Uber, cada equipo implementaba su propio throttling mediante lógica de negocio, middleware personalizado o contadores basados en Redis
  • Esto generaba problemas como configuraciones inconsistentes, latencia adicional por Redis, necesidad de redeplegar servidores al cambiar límites y dificultad para responder a incidentes debido a limitadores no documentados
  • Una parte importante de los servicios pequeños operaba sin rate limiting, y cada limitador reportaba métricas y errores de forma distinta, lo que impedía una observabilidad unificada
  • Usar Redis como contador centralizado provocaba latencias inaceptables y problemas de consistencia entre regiones en un entorno con cientos de miles de hosts, cientos de millones de solicitudes por segundo y múltiples regiones
    • Incluso con sharding y replicación, se habrían necesitado cientos de clústeres de Redis, además de introducir nuevos modos de falla
  • El enfoque de sincronización periódica de contadores reducía la sobrecarga de red, pero se descartó por la falta de frescura de los datos y la demora para responder a picos repentinos de tráfico
  • Finalmente, Uber concluyó que solo una arquitectura totalmente distribuida, donde el proxy local decide con base en la carga agregada, podía lograr al mismo tiempo baja latencia y escalabilidad global

Visión de un limitador unificado a nivel de infraestructura

  • La solución fue integrar el rate limiting en el service mesh de Uber, la capa de infraestructura para el tráfico RPC entre servicios
  • Al incrustar el limitador en esta capa, era posible inspeccionar y evaluar todas las solicitudes sin importar el lenguaje o framework del llamador, antes de que llegaran al destino
  • Objetivo: ofrecer un servicio unificado de rate limiting que permitiera a los equipos configurar cuotas por llamador y por procedimiento sin cambios de código
  • Era necesario escalar con mínima latencia adicional a cientos de millones de solicitudes por segundo, decenas de miles de pares de servicios y flotas de hosts en múltiples regiones geográficas

Arquitectura de GRL: bucle de retroalimentación de 3 niveles

  • El núcleo de GRL es una estructura de bucle de retroalimentación de 3 niveles
    • Cliente de rate limit (data plane del service mesh): decide localmente sobre cada solicitud según las instrucciones recibidas del agregador y reporta al agregador a nivel de zona el número de solicitudes por segundo por host
    • Agregador (por zona): recopila métricas de todos los clientes de la misma zona, calcula el uso a nivel de zona y lo envía al controlador
    • Controlador (por región, global): agrega los datos de las zonas para determinar la utilización global y propaga de regreso a agregadores y clientes instrucciones actualizadas de drop ratio
  • Esta agregación jerárquica mantiene la baja latencia en la ruta crítica (la decisión es local) y al mismo tiempo permite coordinación global en pocos segundos
  • Si falla el control plane, los clientes operan en modo fail-open, dejando pasar el tráfico para evitar fallas autoinfligidas

Evolución de la lógica de rate limiting

  • Enfoque inicial con token bucket

    • Al principio se aplicó el algoritmo de token bucket en cada proxy del data plane de red
    • Cada proxy seguía el conteo local de solicitudes y reponía tokens con el tiempo, permitiendo o rechazando solicitudes según la cantidad de tokens disponibles
    • La tasa de reposición de tokens se calculaba como la proporción entre la carga local del proxy y el límite global: ratio × limitRPS
    • Para responder a tráfico en ráfaga, los tokens no utilizados se guardaban en un buffer circular, retenidos por defecto durante 10 segundos (configurable hasta 20 segundos)
    • En producción surgieron problemas de equidad y escalabilidad: cuando el número de llamadores excedía el límite, no era posible repartir la capacidad de manera justa, y las ráfagas en hosts individuales causaban descartes prematuros incluso si seguían por debajo del límite global
  • Introducción de Drop-by-Ratio

    • Cuando la carga global agregada superaba el límite configurado, los clientes descartaban probabilísticamente un porcentaje de las solicitudes
    • Ejemplo: si el RPS agregado de un llamador era 1.5 veces el límite, se descartaba cerca de 33% en todas las instancias, con la fórmula: drop_ratio = (actual_rps - limit_rps) / actual_rps
    • Mediante una señal global de descarte actualizada por el control plane cada pocos segundos, el tráfico excedente se estrangulaba de manera uniforme entre todas las instancias del llamador
    • Resultó especialmente eficaz en grandes servicios tipo gateway con cientos o miles de instancias llamadoras
  • Transición a un modelo probabilístico unificado

    • A medida que GRL maduró, Uber eliminó por completo el token bucket y unificó todo bajo un modelo probabilístico de descarte basado en control plane
    • Operar ambos algoritmos al mismo tiempo aumentaba la complejidad de configuración y la sobrecarga de red
    • Al consolidarlo en un solo modelo, se simplificó la configuración, se redujo el ancho de banda del control plane y se unificaron todas las decisiones de rate limiting bajo un mecanismo global coherente
    • Compensación: al depender de datos agregados globales actualizados cada segundo, se produce una latencia de aplicación de 2 a 3 segundos
      • En la práctica, esto es despreciable para la mayoría de las cargas de trabajo y solo afecta ráfagas muy cortas y extremas
  • Diseño final: descarte probabilístico guiado por el control plane

    • En el GRL actual, la aplicación ocurre por completo en la capa cliente del data plane de red
    • Flujo de procesamiento al llegar una solicitud:
      • La solicitud se hace coincidir con el bucket configurado, definido por llamador, procedimiento o ambos
      • Si ese bucket tiene una instrucción activa de drop ratio, se realiza un descarte probabilístico con esa proporción
      • Si no hay instrucción de descarte, la solicitud se reenvía normalmente
    • La ruta crítica es extremadamente ligera: no se requieren cálculos locales de tokens ni comunicación con el control plane por cada solicitud, solo muestreo probabilístico simple dentro del proceso
    • El agregador y el controlador realizan fuera del forwarding plane los cálculos complejos cada segundo, como agregación de solicitudes, comparación con umbrales y cálculo de nuevas proporciones de descarte
    • Este diseño permite escalar a cientos de millones de solicitudes por segundo manteniendo precisión de aplicación global en cuestión de segundos

Configuración de límites

  • Los propietarios de servicios definen buckets de rate limiting en un archivo de configuración
    • Scope: global, por región o por zona
    • Reglas de coincidencia: nombre del llamador, procedimiento o ambos
    • Comportamiento: deny (aplicado) o allow (modo shadow para pruebas)
  • Se aplica de manera transparente al servicio de destino sin cambios de código

Resultados operativos

  • Reducción de latencia y eliminación de sobrecarga

    • Antes de GRL, muchos servicios usaban limitadores basados en Redis que requerían un viaje de red por cada solicitud
    • Al pasar a evaluación local en el data plane del service mesh, se eliminaron hops adicionales y la latencia se redujo significativamente
    • La latencia P50 bajó cerca de 1 ms, la P90 bajó varias decenas de ms, y la P99.5 cayó de varios cientos de ms a varias decenas de ms, con una mejora de hasta 90%
  • Simplificación operativa y eficiencia de recursos

    • Centralizar el rate limiting dentro del data plane del service mesh simplificó la infraestructura
    • Ya no se necesitaban almacenes de datos ni capas de caché separadas para aplicar cuotas
    • Se liberó una cantidad considerable de instancias de Redis que antes estaban dedicadas exclusivamente al rate limiting, logrando una eficiencia computacional relevante
  • Mejor estabilidad y respuesta a incidentes

    • Desde su despliegue, GRL ha evitado repetidamente sobrecargas durante picos, failover y tormentas de reintentos
    • Al descartar probabilísticamente tráfico excedente en el service mesh, mantuvo tiempos de respuesta consistentes incluso ante aumentos bruscos de carga entrante
    • Un servicio crítico soportó sin degradación un aumento de tráfico de 15x, pasando de 22K a 367K RPS
    • También absorbió ataques DDoS antes de que alcanzaran los sistemas internos
    • Durante la respuesta a incidentes, el equipo de ingeniería de producción pudo aplicar con GRL rate limits dirigidos a llamadores o procedimientos específicos de alto tráfico, y como las actualizaciones del control plane se propagan cada segundo, la sobrecarga pudo mitigarse en pocos segundos
    • Fue posible hacer throttling de patrones de tráfico específicos de forma rápida y segura sin redeplegar servicios
    • Escala total: alrededor de 80 millones por segundo, con cuotas dinámicas aplicadas en más de 1,100 servicios

Automatización del rate limiting: Rate Limit Configurator (RLC)

  • Límites de la configuración manual

    • Aunque GRL unificó la aplicación, la configuración de límites seguía requiriendo trabajo manual
    • Los propietarios de servicios definían cuotas por llamador y procedimiento en archivos YAML y las ajustaban cada vez que cambiaban los patrones de tráfico
    • En un entorno con cientos de microservicios en evolución constante, las configuraciones estáticas se volvían rápidamente obsoletas
      • Si eran demasiado estrictas, se producía throttling incluso en picos normales de tráfico
      • Si eran demasiado laxas, la protección resultaba mínima frente a la capacidad real
      • Los cambios dependían del análisis en dashboards y del ajuste manual
  • Cómo funciona RLC

    • RLC (Rate Limit Configurator) mantiene automáticamente actualizada la configuración de GRL
    • En un horario fijo o inmediatamente después de cambios de configuración, ejecuta el siguiente ciclo:
      • Recopila métricas de las últimas semanas desde la plataforma de observabilidad de Uber
      • Calcula límites seguros por llamador y procedimiento usando picos históricos y margen de buffer
      • Escribe la configuración actualizada en un repositorio compartido de configuración
      • Envía los nuevos límites a GRL a través del control plane existente
    • Con este proceso de ciclo cerrado, los límites evolucionan junto con el tráfico real y se minimiza la intervención manual
  • Diseño escalable

    • RLC fue diseñado desde el principio para admitir múltiples estrategias de cálculo de rate limiting
    • La política predeterminada se basa en datos históricos de RPS, pero se pueden agregar nuevos tipos de política de forma modular
    • Servicios como los de mapas o datos de ubicación usan modelos predictivos que incorporan pronósticos de tráfico y capacidad planificada, prediciendo carga futura en lugar de depender de tendencias pasadas
    • También se admite la asignación de cuotas fijas según acuerdos contractuales u operativos predefinidos
    • Gracias a una interfaz modular, cada dominio de servicio puede elegir la lógica de cálculo más adecuada entre patrones de tráfico casi en tiempo real, predicciones o cuotas estáticas
  • Modo shadow y validación

    • Por seguridad, los límites pueden generarse y monitorearse en modo shadow sin aplicarse
    • Los propietarios de servicios observan en producción cómo se comportaría el rate limiting antes de activarlo
    • Dashboards y alertas dedicados visualizan el tráfico observado y los descartes virtuales para generar confianza antes del rollout
  • Efecto de la automatización

    • Miles de reglas de rate limiting se actualizan automáticamente sin edición manual
    • Se generan políticas consistentes en todos los servicios usando la misma fórmula y las mismas fuentes de datos
    • Los distintos tipos de política permiten a los equipos elegir y ampliar la lógica de cálculo más adecuada para su carga de trabajo
    • El modo shadow garantiza la precisión antes de la aplicación

Próxima dirección

  • Incluso después de introducir RLC, Uber sigue avanzando en mayor ajuste de buffers, la incorporación de rate limiting por región para reducir el alcance de los cambios de configuración y mayor frecuencia de actualización para mejorar la respuesta al tráfico en vivo
  • La capa de throttler de Uber aporta protección adicional contra sobrecargas más cerca de la aplicación
  • Actualmente, GRL es un componente central del stack de estabilidad multicapa de Uber y ayuda a mantener la estabilidad y la equidad de la plataforma incluso bajo cargas extremas

Aún no hay comentarios.

Aún no hay comentarios.