Be Software Architecture Wise
Be Wise Apps

Read in English · Lire en français · Auf Deutsch lesen

Sección 9.2 de 9.8 · Intermedio · 27 min de lectura

Balanceo de carga, ausencia de estado y sesiones

Videolección

5 min · narrado en inglés, con subtítulos
Solo escuchar (audio)
Leer la transcripción

Te damos la bienvenida a la sección nueve punto dos. El escalado horizontal te da muchas instancias. Esta lección trata de lo que se sitúa delante de ellas y de cómo repartir el trabajo para que los usuarios nunca noten que las instancias van y vienen.

Imagina un supermercado en el que un empleado dirige a los clientes hacia las cajas. Enviar a la gente a cada caja por turno es justo pero ingenuo. Un cliente con un carro para una familia de seis personas bloquea una caja mientras la siguiente está libre. Enviar a cada cliente a la caja con la cola más corta funciona mucho mejor. El empleado también debe saber qué cajas están abiertas y dejar de enviar gente a una caja que está a punto de cerrar, mientras su cola termina. Y funciona mejor si cualquier caja puede atender a cualquier cliente. Ese es el trabajo de un balanceador de carga.

Un balanceador de carga decide qué instancia recibe cada conexión o solicitud. También comprueba qué instancias están sanas, da a los clientes una dirección estable y a menudo termina TLS. Un balanceador de capa 4 solo ve direcciones IP y puertos. Elige un backend una vez por conexión y la reenvía sin mirar dentro. Eso lo hace extremadamente rápido, y funciona con cualquier protocolo. Un proxy de capa 7 entiende HTTP. Lee cada solicitud, así que puede enrutarlas, reintentarlas, limitar su tasa y registrarlas todas. Aquí enruta por ruta: las solicitudes de pedidos al pool de pedidos, las de la carta al pool de la carta y las búsquedas al pool de búsqueda. Esta diferencia pilla desprevenidos a muchos equipos. gRPC envía muchas solicitudes por una sola conexión de larga duración. Un balanceador de capa 4 elige una vez por conexión, así que las instancias nuevas pueden no recibir nada. gRPC necesita un proxy de capa 7 o un balanceo en el cliente.

¿Qué instancia debería recibir la siguiente solicitud? Toma dos instancias, A y B, que gestionan cada una una solicitud a la vez. Llegan ocho solicitudes separadas por diez milisegundos: primero un informe que tarda cien milisegundos y después siete lecturas de la carta que tardan diez. El round robin envía las solicitudes por turno, cueste lo que cueste cada una. Así que tres lecturas de la carta caen en la instancia A, atascadas detrás del informe. Tardan noventa, ochenta y setenta milisegundos. Las lecturas de la carta tardan de media unos cuarenta y un milisegundos, y la peor, noventa. Mientras tanto, la instancia B está inactiva la mitad del tiempo. Menos conexiones envía cada solicitud a la instancia con menos solicitudes en curso. El informe va a A y, como B siempre vuelve a estar libre a tiempo, todas las lecturas de la carta van a B. Ahora cada lectura de la carta tarda diez milisegundos, y la media de las ocho baja de unos cuarenta y nueve a unos veintiuno. El round robin cuenta solicitudes. Menos conexiones cuenta el trabajo en curso, así que las solicitudes nuevas se alejan automáticamente de una instancia ocupada o lenta.

¿Por qué no elegir siempre la instancia menos cargada del pool? Porque en un sistema grande, decenas de balanceadores ven cada uno solo sus propias solicitudes, o un informe de carga de hace unos segundos. Si todos eligen la instancia que parecía menos cargada, todos eligen la misma. Se ve desbordada, y la manada pasa a la siguiente. Michael Mitzenmacher analizó una alternativa sorprendentemente sencilla: elegir dos instancias al azar y enviar la solicitud a la menos cargada. El azar evita el efecto manada y la comparación evita las peores instancias. Hoy es una opción estándar en proxies como Envoy, y una buena opción predeterminada allí donde haya muchos balanceadores.

Un balanceador debe saber qué instancias pueden recibir tráfico. Una comprobación de actividad pregunta si el proceso está atascado sin posibilidad de recuperarse. Una comprobación de preparación pregunta si debe recibir tráfico en este momento. El error clásico es llamar a la base de datos desde las comprobaciones de actividad. Una breve caída de la base de datos hace fallar todas las comprobaciones, todas las instancias se reinician a la vez y la tormenta de reinicios prolonga la caída. Mantén la comprobación de actividad local y mínima.

Las instancias salen del pool con cada despliegue y cada reducción. El drenaje de conexiones hace que eso no tenga consecuencias. Primero, la instancia recibe una señal de apagado. Su comprobación de preparación falla, así que el balanceador de carga deja de enviarle solicitudes nuevas. Las solicitudes que ya están en curso terminan con normalidad. Las conexiones keep-alive inactivas se cierran, así que los clientes se vuelven a conectar en otro sitio. Después, el proceso termina limpiamente, antes de que se agote su periodo de gracia.

Las aplicaciones más antiguas guardaban la sesión de cada usuario en la memoria de un servidor, así que los balanceadores ofrecían sesiones persistentes. Pero la carga se vuelve desigual y, cuando esa instancia falla, los carritos desaparecen y las personas ven cerrada su sesión. El remedio es sacar el estado de sesión de la instancia. Un token firmado de corta duración puede llevar la identidad del usuario con cada solicitud. Un almacén de sesiones compartido admite un estado más grande y el cierre de sesión inmediato, a costa de una llamada de red por solicitud. Y el estado que debe sobrevivir, como un carrito que el usuario espera encontrar mañana, va en la base de datos. Así, cualquier instancia puede atender cualquier solicitud.

La sección completa trata también el hashing y el balanceo de carga global con DNS y anycast. A continuación, en la sección nueve punto tres, veremos qué ocurre cuando el trabajo llega más deprisa de lo que se puede hacer. Nos vemos allí.

Lo que necesitas saber

Qué hace un balanceador de carga

Un balanceador de carga se sitúa entre los clientes y un pool de instancias intercambiables y decide, para cada conexión o solicitud, qué instancia la recibe. Repartir es solo una parte del trabajo. Un balanceador de carga también comprueba qué instancias están sanas y deja de enviar tráfico a las que no lo están; da a los clientes una dirección estable mientras las instancias van y vienen con los despliegues y el autoescalado; a menudo termina TLS, de modo que los certificados se gestionan en un solo sitio; y en la capa 7 puede enrutar, reintentar, limitar la tasa y registrar cada solicitud. Es, por tanto, el componente que hace que el escalado horizontal sea invisible para los clientes.

El balanceo de carga aparece en varios niveles. En el borde suele haber un balanceador de carga gestionado en la nube o un par de proxies como HAProxy, NGINX o Envoy. Entre servicios, el balanceo se hace cada vez más en el lado del cliente: una biblioteca cliente de gRPC o un proxy sidecar de una service mesh (Sección 6.3) mantiene la lista de instancias sanas obtenida del descubrimiento de servicios y elige una por sí mismo, lo que elimina un salto de red y un componente central. Sea cual sea la forma, se repiten las mismas decisiones: qué puede ver el balanceador, qué algoritmo usa, cómo decide que una instancia está sana y cómo salen las instancias sin perder trabajo.

Balanceo de carga de capa 4 y de capa 7

Los números de capa proceden del modelo de red OSI. Un balanceador de carga de capa 4 trabaja en la capa de transporte: ve direcciones IP y puertos TCP o UDP, elige un backend cuando se abre una conexión y después reenvía los paquetes de esa conexión sin mirar dentro de ellos. Como hace tan poco, es extremadamente rápido y funciona con cualquier protocolo, incluidas las bases de datos, los intermediarios de mensajes y el tráfico cifrado que no puede leer. Maglev, de Google, y los balanceadores de carga de red de las principales nubes son diseños de capa 4 que gestionan millones de paquetes por segundo.

Un balanceador de carga de capa 7 es un proxy inverso que entiende el protocolo de aplicación, casi siempre HTTP. Termina la conexión del cliente (y normalmente TLS), lee cada solicitud y abre o reutiliza sus propias conexiones con los backends. Eso le permite enrutar por ruta, host, cabecera o cookie (/orders/* al pool de pedidos, /menus/* al pool de la carta), balancear cada solicitud en lugar de cada conexión, reintentar una solicitud fallida en otra instancia, aplicar límites de tasa, añadir cabeceras de trazado y registrar cada solicitud con su estado y su latencia. El costo es más procesamiento por solicitud, un componente que debe guardar las claves TLS y un sitio más en el que hay que configurar los timeouts y los reintentos de forma coherente con el resto del sistema (Sección 9.4).

Hay una diferencia que pilla desprevenidos a muchos equipos. HTTP/2 y gRPC multiplexan muchas solicitudes sobre una sola conexión de larga duración. Un balanceador de capa 4 elige un backend una vez por conexión, así que un cliente que abre una conexión envía todas sus solicitudes a una sola instancia, por muchas instancias que existan: las instancias nuevas que añade el autoescalado no reciben nada hasta que los clientes se vuelven a conectar. Por eso, balancear el tráfico gRPC exige un proxy de capa 7 o un balanceo en el lado del cliente por solicitud.

Una disposición típica en dos niveles

Los clientes se conectan a un balanceador de carga de capa 4 que reparte las conexiones TCP entre proxies de capa 7, que terminan TLS y enrutan cada solicitud HTTP por ruta al pool de instancias adecuadoClientesLB capa 4elige un backendpor conexiónTCPProxies capa 7terminan TLSleen HTTPenrutan solicitudesreintentan, limitanPool API pedidosruta /orders/*Pool API cartaruta /menus/*Pool búsquedaruta /searchve: direcciones IP, puertosveloz, ignora protocolove: método, ruta,cabeceras, cookies
Un nivel de capa 4 reparte las conexiones a bajo costo; un nivel de capa 7 lee cada solicitud y la enruta por ruta al pool adecuado.

Algoritmos de balanceo de carga

El algoritmo decide qué instancia sana recibe la siguiente conexión o solicitud. Los sencillos ignoran lo ocupadas que están las instancias; los mejores usan alguna medida de la carga; los basados en hash envían deliberadamente las solicitudes relacionadas al mismo sitio. La tabla resume las opciones habituales.

Algoritmos de balanceo de carga habituales

AlgoritmoCómo eligeVentajasPuntos débiles
Round robinCada instancia por turnoSencillo, predecible, sin estado sobre la cargaCiego al costo de las solicitudes y a las instancias lentas
Round robin ponderadoPor turno, en proporción a pesos configuradosMezcla tamaños de instancia; aumenta gradualmente el tráfico de las versiones nuevas (canarios)Los pesos son estimaciones estáticas; sigue siendo ciego a la carga real
AleatorioAl azar, de forma uniformeNo necesita estado compartido, así que muchos balanceadores pueden usarlo de forma independienteDesigual por azar, sobre todo con pocas solicitudes
Menos conexiones (least connections) (menos solicitudes pendientes)La instancia con menos solicitudes en cursoSe adapta a costos de solicitud desiguales y a instancias lentasNecesita recuentos precisos; cada uno de muchos balanceadores solo ve los suyos; las instancias nuevas pueden verse inundadas
Ponderado por latencia (por ejemplo, EWMA del tiempo de respuesta)La instancia con la mejor latencia reciente, a menudo combinada con la cargaSe aparta enseguida de las instancias degradadasPuede oscilar; una instancia que falla deprisa parece atractiva salvo que se penalicen los errores
Hash (IP de origen, cabecera, hashing consistente)La misma clave va siempre a la misma instanciaAfinidad para cachés y sesiones; el hashing consistente mueve pocas claves cuando cambia el poolLas claves calientes sobrecargan una instancia; distribución desigual de las claves
Poder de dos elecciones aleatorias (power of two choices)Elige dos instancias al azar y envía a la menos cargadaCasi tan bueno como menos conexiones, sin efecto manada, con poca coordinaciónAlgo peor que una elección global perfecta con información perfecta

Ejemplo práctico

Ejemplo práctico: por qué menos conexiones supera al round robin cuando los costos de las solicitudes difieren

Dos instancias, A y B, procesan cada una una solicitud a la vez (las instancias reales tienen más hilos, pero el efecto es el mismo a mayor escala). Llegan ocho solicitudes separadas por 10 ms. La primera es un informe de ventas de un restaurante que cuesta 100 ms; las otras siete son lecturas de la carta que cuestan 10 ms cada una.

Round robin: asignaciónA recibe las solicitudes 1, 3, 5 y 7; B recibe la 2, 4, 6 y 8, sea cual sea su costo
Round robin en AR1 se ejecuta de 0 a 100 ms. R3 (llegó en 20) espera y termina en 110: 90 ms. R5 (40) termina en 120: 80 ms. R7 (60) termina en 130: 70 ms
Round robin en BR2, R4, R6 y R8 terminan cada una 10 ms después de llegar; B está inactiva la mitad del tiempo
Resultado del round robinLecturas de la carta: 90, 80, 70, 10, 10, 10, 10 ms, media 290 ÷ 7 ≈ 41 ms, peor caso 90 ms. Las ocho solicitudes: media (100 + 290) ÷ 8 ≈ 49 ms
Menos conexiones: asignaciónR1 va a A (ambas inactivas). A los 10 ms, A tiene 1 solicitud en curso y B tiene 0, así que R2 va a B; B siempre vuelve a estar libre antes de la siguiente llegada, así que de R3 a R8 van todas a B
Resultado de menos conexionesCada lectura de la carta tarda 10 ms; el informe tarda 100 ms. Media (100 + 70) ÷ 8 ≈ 21 ms, peor lectura de la carta 10 ms
Por quéEl round robin cuenta solicitudes, no trabajo. Menos conexiones cuenta el trabajo en curso, que, según la ley de Little (en curso = tasa × tiempo), crece en la instancia que sea más lenta o esté más ocupada, así que las solicitudes nuevas se alejan de ella automáticamente

El mismo efecto aparece siempre que los costos de las solicitudes varían mucho (búsquedas frente a consultas puntuales, exportaciones frente a lecturas) o que una instancia es más lenta que sus pares por un vecino ruidoso, una pausa de recolección de basura o una caché fría.

Menos conexiones necesita un recuento significativo. Con HTTP/2 o gRPC muchas solicitudes comparten una conexión, así que los balanceadores cuentan en su lugar las solicitudes pendientes; con conexiones WebSocket de larga duración, el recuento mide sesiones, no carga.

Una instancia recién arrancada tiene cero conexiones y puede verse inundada antes de que sus cachés estén calientes; muchos balanceadores ofrecen un periodo de arranque lento (slow start) que aumenta su parte gradualmente durante un minuto más o menos.

El poder de dos elecciones aleatorias

Si menos conexiones funciona tan bien, ¿por qué no elegir siempre la instancia menos cargada a nivel global? Porque en un sistema grande no existe una visión única y actual de la carga. Decenas de balanceadores de carga o miles de balanceadores en el lado del cliente ven cada uno solo sus propias solicitudes, o un informe de carga de hace unos segundos. Si todos eligen la instancia que parecía menos cargada, todos eligen la misma, que enseguida se ve desbordada, y luego todos pasan a la siguiente: una manada que persigue la carga por todo el pool.

La tesis doctoral de Michael Mitzenmacher (1996), publicada como The Power of Two Choices in Randomized Load Balancing (IEEE Transactions on Parallel and Distributed Systems, 2001) y basada en trabajos anteriores de Azar, Broder, Karlin y Upfal, analizó una alternativa sorprendentemente sencilla: elegir dos instancias al azar y enviar la solicitud a la menos cargada de las dos. En el modelo clásico de bolas en urnas, colocar n solicitudes en n servidores al azar da un servidor más cargado con unas log n ÷ log log n solicitudes; con dos elecciones aleatorias esto baja a unas log log n ÷ log 2, una mejora exponencial, mientras que una tercera elección añade muy poco más. El azar evita el efecto manada y la comparación evita las peores instancias.

El poder de dos elecciones aleatorias (power of two choices) es hoy la opción predeterminada o una opción estándar en proxies muy utilizados: el balanceador least-request de Envoy compara de forma predeterminada dos hosts elegidos al azar, y NGINX ofrece random two least_conn. Es una buena opción predeterminada para el balanceo en el lado del cliente en cualquier sistema con muchos balanceadores.

Hashing y afinidad

A veces lo que se busca es enviar las solicitudes relacionadas a la misma instancia: a un nodo de caché que ya tiene la carta de un restaurante, o a la instancia que mantiene una sesión WebSocket. Aplicar un hash a una clave (identificador del restaurante, identificador del usuario, IP de origen) para asignarla a una instancia lo consigue. Un simple hash mod N reasigna la mayoría de las claves cada vez que cambia N, lo que vacía todas las cachés en el peor momento, durante un escalado horizontal. El hashing consistente (presentado en la Sección 7.4) mueve solo alrededor de 1 ÷ N de las claves cuando una instancia entra o sale. Su punto débil son las claves calientes: el restaurante más popular a la hora del almuerzo cae en una sola instancia. Variantes como el hashing consistente con cargas acotadas limitan la parte de cada instancia y desvían el exceso a la siguiente instancia del anillo.

Comprobaciones de estado: actividad y preparación

Un balanceador de carga debe saber qué instancias pueden recibir tráfico. Una comprobación de estado (health check) activa sondea cada instancia periódicamente, por ejemplo GET /healthz cada cinco segundos, y la marca como caída tras unos cuantos fallos consecutivos y de nuevo como disponible tras unos cuantos éxitos. Las comprobaciones pasivas, a menudo llamadas detección de valores atípicos (outlier detection), observan el tráfico real y expulsan una instancia que devuelve, por ejemplo, cinco errores de servidor consecutivos. Las dos se complementan: las comprobaciones activas encuentran instancias que no reciben tráfico, y las pasivas reaccionan a fallos que una sonda trivial no ejercita.

Kubernetes hizo explícita una distinción importante. Una sonda de actividad (liveness probe) pregunta si el proceso está atascado sin posibilidad de recuperarse (en un interbloqueo, sin memoria en un bucle); si falla, la instancia se reinicia. Una sonda de preparación (readiness probe) pregunta si la instancia debe recibir tráfico en este momento; si falla, la instancia se retira del balanceador de carga pero sigue en ejecución, por ejemplo mientras calienta sus cachés al arrancar o mientras descarta carga. Una tercera, la sonda de arranque (startup probe), mantiene en suspenso las otras dos mientras arranca una aplicación lenta.

El error clásico es comprobar las dependencias compartidas en estas sondas. Si la sonda de actividad de cada instancia llama a la base de datos, una breve caída de la base de datos hace que fallen todas las sondas, el orquestador reinicia todas las instancias a la vez y la tormenta de reinicios (cachés frías, miles de conexiones nuevas) prolonga la caída mucho después de que la base de datos haya vuelto. Las comprobaciones de preparación que incluyen una dependencia compartida pueden igualmente marcar toda la flota como no preparada, convirtiendo errores parciales en una caída total. Mantén la sonda de actividad local y mínima; deja que la de preparación refleje la capacidad de la propia instancia para atender; y gestiona los fallos de las dependencias con los patrones de la Sección 9.4. Los balanceadores de carga se protegen del caso extremo fallando en abierto: un AWS Application Load Balancer enruta a todos los destinos si todos fallan sus comprobaciones de estado, y Envoy ignora el estado de salud cuando la proporción de hosts sanos cae por debajo de un umbral de pánico (50% de forma predeterminada), con el razonamiento de que enviar tráfico a instancias dudosas es mejor que no enviarlo a ninguna parte.

Drenaje de conexiones y apagado elegante

Las instancias salen del pool constantemente: cada despliegue las sustituye, el autoescalado las retira y la plataforma las mueve durante el mantenimiento. Si una instancia simplemente se mata, todas las solicitudes que estaba procesando fallan, y los clientes ven errores durante lo que debería ser un lanzamiento rutinario. El drenaje de conexiones (connection draining) (llamado deregistration delay en AWS) retira la instancia de la rotación del balanceador para que no reciba solicitudes nuevas, espera a que terminen las solicitudes que ya están en curso y solo entonces la deja detenerse.

La instancia debe colaborar. Al recibir su señal de apagado, debe fallar su comprobación de preparación, seguir atendiendo las solicitudes en curso, indicar a los clientes con conexiones keep-alive que vayan a otro sitio (una cabecera Connection: close en HTTP/1.1, una trama GOAWAY en HTTP/2), terminar o devolver el trabajo en segundo plano y salir antes de que acabe el periodo de gracia. En Kubernetes, retirar un pod del balanceador de carga y enviarle SIGTERM ocurren a la vez, así que todavía puede llegar una solicitud justo después de la señal; una breve espera previa a la parada (pre-stop) de unos segundos cubre esa carrera. El periodo de gracia predeterminado es de 30 segundos, después de los cuales se mata el proceso. Las solicitudes de larga duración (subidas grandes, respuestas en streaming, WebSockets) necesitan un periodo de gracia más largo o un protocolo con el que los clientes se vuelvan a conectar en otro sitio sin perder trabajo.

Apagado elegante en cinco pasos

Cronología de un apagado elegante: la instancia se retira del balanceador y falla readiness, termina sus solicitudes en curso, cierra las conexiones inactivas y solo entonces saleperiodo de drenaje, acotado por un periodo de gracia (p. ej. 30 s)tiempo1 señal deparada (SIGTERM)o baja del registro2 falla readiness;el LB no envía mássolicitudes3 solicitudesen curso acabansin cortes4 cierre conexioneskeep-alive inactivas(HTTP/2 GOAWAY)5 procesoterminaen orden
El drenaje convierte la retirada de una instancia, que antes era una fuente de errores, en algo sin consecuencias: no llega trabajo nuevo, el trabajo existente se completa y después el proceso sale.

Las sesiones persistentes y sus problemas

Las aplicaciones web más antiguas guardaban la sesión de cada usuario (quién ha iniciado sesión, qué hay en el carrito) en la memoria del servidor que la había creado. Detrás de un balanceador de carga, esto solo funciona si todas las solicitudes de un usuario vuelven a ese servidor, así que los balanceadores ofrecen sesiones persistentes (sticky sessions) (afinidad de sesión), normalmente mediante una cookie que identifica la instancia. La persistencia es una forma rápida de poner una aplicación con estado detrás de un balanceador, y tiene un uso legítimo como pista de rendimiento, por ejemplo para mantener a un usuario en una instancia cuya caché local ya contiene sus datos.

Como mecanismo de corrección, causa problemas. La carga se vuelve desigual, porque unos pocos usuarios intensivos o una gran oficina detrás de una sola dirección IP se quedan fijados a una instancia sea cual sea su carga. Cuando una instancia falla, sus usuarios pierden sus sesiones: los carritos desaparecen y las personas ven cerrada su sesión. Las reducciones y cada despliegue hacen lo mismo salvo que se drenen las sesiones, lo que puede tardar tanto como la sesión más larga. Las instancias nuevas que añade el autoescalado solo reciben usuarios nuevos, así que alivian despacio a las instancias sobrecargadas. Y el sistema ya no es sin estado en el sentido de la Sección 9.1, así que todos estos problemas reaparecen en el failover entre zonas o regiones.

Externalizar el estado de sesión

El remedio es sacar el estado de sesión de la instancia, para que cualquier instancia pueda atender cualquier solicitud. Hay tres opciones principales, que a menudo se combinan. Un token en el lado del cliente lleva el estado con cada solicitud: una cookie firmada (y, si hace falta, cifrada) o un token como un JWT que contiene la identidad del usuario y algunos datos. Los servidores no necesitan ningún almacén, pero los tokens deben ser pequeños, no se pueden revocar fácilmente antes de que caduquen y deben protegerse contra la manipulación y el robo (Sección 8.3). Un almacén de sesiones compartido, normalmente Redis o Memcached, guarda las sesiones en un almacén externo rápido, indexadas por un identificador de sesión que va en la cookie; admite un estado más grande y el cierre de sesión inmediato, a costa de una llamada de red por solicitud y de una dependencia que a su vez debe tener alta disponibilidad. Una base de datos es adecuada para el estado que debe sobrevivir a cualquier cosa, como un carrito que el usuario espera encontrar mañana, que en realidad son datos de negocio y no datos de sesión.

Un reparto práctico para la plataforma de reparto de comida: la identidad, en un token firmado de corta duración; el carrito, en la base de datos del servicio de pedidos (los usuarios pasan del teléfono a la computadora portátil); y el estado transitorio de la interfaz, en el cliente. Ninguna instancia guarda nada que necesite una solicitud posterior, así que el balanceador de carga puede usar un balanceo por menos solicitudes sin afinidad, y las instancias se pueden añadir, retirar y sustituir a voluntad.

Balanceo de carga global: DNS y anycast

Cuando un sistema se ejecuta en varias regiones, algo debe enviar a cada usuario a una región adecuada: la región sana más cercana o la región que tiene sus datos. El balanceo de carga global suele hacerse de una de dos formas, que a menudo se combinan.

El balanceo global de servidores basado en DNS usa un servidor de nombres autoritativo que responde al mismo nombre con direcciones distintas según el origen de la consulta, la salud de cada región y unos pesos configurados: a un usuario de Lisboa se le da la dirección de la región de la UE, y a uno de Ohio, la de la región de EE. UU. No necesita ninguna red especial, pero es tosco y lento en reaccionar. Los resolutores guardan las respuestas en caché durante al menos el tiempo de vida (TTL) del registro (a menudo de 30 a 300 segundos) y a veces más, así que, después de que falle una región, algunos usuarios siguen llegando a ella durante minutos. El servidor de nombres ve la ubicación del resolutor y no la del usuario, aunque la extensión EDNS Client Subnet (RFC 7871) permite que los resolutores transmitan parte de la dirección del cliente.

Con anycast, la misma dirección IP se anuncia desde muchos sitios mediante el protocolo de enrutamiento de internet (BGP), y los paquetes de cada usuario se entregan al sitio que esté más cerca en términos de enrutamiento. El failover consiste en retirar el anuncio de un sitio que ha fallado, lo que surte efecto enseguida sin esperar a las cachés de DNS. Anycast se usa desde hace mucho en los servicios raíz y de resolución de DNS; las CDN y los balanceadores de carga globales de los grandes proveedores de nube lo usan para llevar a los usuarios a un sitio de borde cercano, donde proxies de capa 7 terminan la conexión y reenvían las solicitudes por la red del proveedor a una región sana. El diseño multirregión, la ubicación de los datos y el failover son el tema de la Sección 10.6.

Balanceo de carga global basado en DNS y con anycast

Dos tipos de balanceo de carga global: basado en DNS, donde el servidor de nombres devuelve la dirección de una región sana cercana, y anycast, donde una dirección se anuncia desde muchos sitios de borde y el enrutamiento lleva a cada usuario al más cercanoPor DNSUsuario (Lisboa)ResolutorServidorDNS GSLB1 consultaresponde según lugary salud; TTL 30 sRegión UERegión EEUU2 conecta a ladirección UEAnycastUsuario (Lisboa)Usuario (Ohio)Borde Madrid203.0.113.10Borde Chicago203.0.113.10misma IP desdetodos los sitios;BGP: el más cercanoRegión UERegión EEUU
El DNS dirige a los usuarios respondiendo con direcciones distintas; anycast da a todos la misma dirección y deja que el enrutamiento de internet los lleve al sitio más cercano.

Comprueba lo que has entendido

¿Por qué un servidor gRPC recién añadido detrás de un balanceador de carga de capa 4 podría no recibir tráfico?

El balanceo de capa 4 elige un backend por conexión, y los clientes gRPC mantienen una sola conexión HTTP/2 de larga duración, así que los clientes existentes nunca le envían solicitudes hasta que se vuelven a conectar.

¿Qué diferencia de efecto hay entre fallar una sonda de actividad y fallar una sonda de preparación?

Fallar la de actividad hace que el orquestador reinicie la instancia; fallar la de preparación solo la retira del balanceador de carga hasta que vuelva a superarla.

¿Por qué funcionan mal muchos balanceadores de carga independientes que eligen la instancia menos cargada?

Actúan sobre la misma visión desfasada y todos eligen la misma instancia, que se sobrecarga por turnos; elegir la mejor de dos instancias aleatorias evita este efecto manada.

Da dos problemas que causa guardar las sesiones en la memoria de la instancia con sesiones persistentes.

Los usuarios pierden sus sesiones cuando la instancia falla o se sustituye, y la carga se vuelve desigual porque los usuarios intensivos se quedan fijados a una instancia.

Siguiente · 9.3Colas y back pressureCómo las colas convierten los picos en trabajo acumulado (backlog), los consumidores competidores, cómo dimensionar las colas con la ley de Little, el back pressure, el descarte de carga y la priorización, los limitadores de tasa token bucket y otros, HTTP 429 con Retry-After, y las colas de mensajes fallidos (dead-letter queues).Continuar →

Fuentes y lecturas recomendadas

¿Tienes una pregunta sobre esta sección? ArchitectBot, el asistente de estudio con IA del curso, responde primero a partir del curso.

Pregunta: “Ejecutamos ocho instancias detrás de un balanceador de carga con sesiones persistentes y perdemos los carritos de los usuarios en cada despliegue. ¿Cómo pasamos a instancias sin estado de forma segura?”