Algoritmos de balanceo de carga: round robin, least connections y más

El algoritmo de balanceo es la regla que elige qué servidor recibe la siguiente petición. Round robin reparte por turnos, least connections prefiere el menos ocupado e IP hash fija cada cliente a un servidor.

Actualizado el 6 min de lectura

Objetivos de aprendizaje

Después de leer este artículo podrás:

  • Entender cómo round robin, least connections, IP hash y hash consistente eligen el servidor
  • Elegir el algoritmo correcto para el tipo de tráfico de tu aplicación
  • Configurar cada algoritmo en nginx y simular la elección en código
En esta página

Tener varios servidores detrás de un load balancer resuelve solo la mitad del problema. La otra mitad es decidir, en cada petición, a cuál de ellos va. Esa decisión es el algoritmo de balanceo, y cambia la latencia que siente el usuario, cuánto trabaja cada servidor y si una sesión en memoria sobrevive.

Cada algoritmo de abajo viene con su regla de elección, el caso en que falla y su configuración en nginx. Al final, un script corto en Python simula la lógica para que la pruebes.

peticionesIP del cliente1A2B3A4C5A6BRound robinapp-114app-225app-336Weighted round robinapp-11236peso 3app-24peso 1app-35peso 1Least connectionsapp-16app-2135app-324IP hashapp-126IP Bapp-2135IP Aapp-34IP Cconexiones ya activasmisma IP, mismo servidor
La misma cola cae en servidores distintos según el algoritmo: por turno, por peso, por la carga activa o por la IP del cliente.

¿Cuáles son los principales algoritmos de balanceo?#

Algoritmo Cómo elige Punto fuerte Punto débil
Round robin Por turnos en orden: 1, 2, 3, 1, 2, 3 Simple y predecible Ignora la carga real de cada servidor
Weighted round robin Por turnos en proporción al peso Servidores de tamaños distintos Los pesos son fijos, los ajustas a mano
Least connections El servidor con menos conexiones activas Absorbe peticiones de duración variada Necesita contar conexiones en tiempo real
IP hash Hash de la IP del cliente Mismo cliente, mismo servidor Reparto desigual detrás de un NAT
Hash consistente Hash de una clave (URL, cookie, IP) Pocas claves cambian de servidor cuando cambia la lista Más configuración
Random con dos opciones Sortea dos servidores y usa el menos ocupado Funciona bien con varios balanceadores Menos intuitivo

¿Cómo funciona el round robin?#

El round robin es el más simple: el balanceador mantiene un puntero en la lista de servidores y avanza uno en cada petición. Con tres servidores, el orden es 1, 2, 3, 1, 2, 3. No guarda estado sobre los servidores, por eso es barato y no da sorpresas.

Funciona bien cuando los servidores tienen el mismo tamaño y las peticiones cuestan algo parecido. Falla cuando una petición ocupa un servidor durante mucho tiempo: el round robin le sigue mandando trabajo nuevo, porque solo cuenta turnos, no carga.

En nginx es el comportamiento por defecto. La documentación de nginx lo describe como round robin con pesos, y cada servidor tiene peso 1 si no indicas otra cosa.

¿Cómo trata el weighted round robin a servidores distintos?#

Si un servidor tiene el doble de memoria, debería recibir más tráfico. El parámetro weight hace eso. Con pesos 3, 1 y 1, de cada 5 peticiones nuevas, 3 van al primer servidor y 1 a cada uno de los otros:

nginx
upstream app {
    server 10.0.0.11:3000 weight=3;
    server 10.0.0.12:3000;
    server 10.0.0.13:3000;
}

Los servidores sin weight quedan con el peso por defecto, 1. Es el mismo ejemplo de la documentación de nginx.

¿Cómo elige el servidor el least connections?#

El balanceador lleva la cuenta de cuántas conexiones activas tiene cada servidor y manda la siguiente petición al que tiene menos. Si hay empate, lo resuelve por turnos. En nginx, la directiva tiene en cuenta los pesos de los servidores.

Es la mejor opción cuando la duración de las peticiones varía: subidas de archivos, informes pesados, WebSockets o llamadas a APIs lentas. Un servidor atascado en una petición larga acumula conexiones y deja de recibir nuevas, mientras los demás absorben la cola. Cuando todas las peticiones son cortas e iguales, la ganancia frente al round robin suele ser pequeña.

nginx
upstream app {
    least_conn;
    server 10.0.0.11:3000;
    server 10.0.0.12:3000;
    server 10.0.0.13:3000;
}

¿Cuándo usar IP hash o hash consistente?#

En estos algoritmos la elección depende de una clave, no de la carga. El mismo valor de clave lleva siempre al mismo servidor. Eso sirve para sesiones en memoria, caché local o conexiones que tienen que volver al mismo lugar.

El ip_hash de nginx usa los tres primeros octetos de la IPv4 del cliente (o la IPv6 completa) como clave:

nginx
upstream app {
    ip_hash;
    server 10.0.0.11:3000;
    server 10.0.0.12:3000;
    server 10.0.0.13:3000 down;
}

Hay dos límites. El primero: como solo los tres primeros octetos entran en el hash, los clientes de la misma red /24, y todos los que pasan por el mismo NAT, caen en el mismo servidor, lo que desequilibra la carga. El segundo: si quitas un servidor, el hash se recalcula y muchos clientes cambian de destino. Por eso la documentación indica marcar el servidor retirado temporalmente con down, lo que conserva el mapeo actual.

Para elegir otra clave, como la URL o una cookie, usa hash con consistent. El hash consistente (ketama) garantiza que, al añadir o quitar un servidor, solo una pequeña parte de las claves cambia de destino. Es la opción habitual para cachés, donde reasignarlo todo vaciaría la caché de golpe:

nginx
upstream cache {
    hash $request_uri consistent;
    server 10.0.0.21:8080;
    server 10.0.0.22:8080;
    server 10.0.0.23:8080;
}

¿Existen otros algoritmos?#

Sí. nginx también ofrece random, que sortea un servidor respetando los pesos. La variante random two least_conn sortea dos servidores y se queda con el que tiene menos conexiones activas. Así evita que varios balanceadores independientes manden todo al mismo servidor ocioso al mismo tiempo.

Existe además least_time, que prefiere el servidor con menor tiempo medio de respuesta y menos conexiones. Según la documentación, antes de la versión 1.31.0 era exclusivo de la suscripción comercial (NGINX Plus). Revisa tu versión antes de depender de él.

¿Cómo simular los algoritmos en código?#

Este script en Python 3 implementa round robin, round robin con pesos, least connections y hash por IP. Guárdalo como lb.py y ejecútalo con python lb.py:

python
import hashlib
import itertools

SERVERS = ["app-1", "app-2", "app-3"]


def round_robin():
    return itertools.cycle(SERVERS)


def weighted_round_robin(weights):
    # {"app-1": 3, "app-2": 1} se convierte en app-1, app-1, app-1, app-2
    return itertools.cycle([s for s, w in weights.items() for _ in range(w)])


def least_connections(active):
    # active: conexiones abiertas por servidor; el empate va al primero de la lista
    return min(SERVERS, key=lambda s: active[s])


def ip_hash(client_ip):
    digest = hashlib.sha256(client_ip.encode()).digest()
    return SERVERS[int.from_bytes(digest[:4], "big") % len(SERVERS)]


rr = round_robin()
print([next(rr) for _ in range(6)])
wrr = weighted_round_robin({"app-1": 3, "app-2": 1, "app-3": 1})
print([next(wrr) for _ in range(5)])
print(least_connections({"app-1": 12, "app-2": 3, "app-3": 7}))
print(ip_hash("203.0.113.7") == ip_hash("203.0.113.7"))

La salida es ['app-1', 'app-2', 'app-3', 'app-1', 'app-2', 'app-3'], luego ['app-1', 'app-1', 'app-1', 'app-2', 'app-3'], luego app-2 (el menos ocupado) y True (misma IP, mismo servidor). Añade un cuarto servidor a SERVERS y vuelve a ejecutarlo: el ip_hash con módulo reasigna buena parte de los clientes, y eso es justo lo que el hash consistente evita. El weighted round robin de este script manda las tres peticiones seguidas al primer servidor; un balanceador real puede intercalar las elecciones.

¿Cómo elegir el algoritmo correcto?#

  • Servidores iguales, peticiones cortas y parecidas: round robin.
  • Servidores de tamaños distintos: weighted round robin.
  • Peticiones largas o de duración impredecible: least connections.
  • Estado en la memoria del servidor que no puedes mover: IP hash. Pero la mejor solución es sacar el estado de la memoria, guardar la sesión en Redis o en una base de datos, y volver a un algoritmo que no dependa de una clave.
  • Caché distribuida: hash consistente.

En todos los casos, el balanceo solo funciona si los servidores son intercambiables y el balanceador saca de la rotación a los que fallan. El proxy inverso que está delante de ellos es quien aplica la regla.

Cómo hacerlo en Square Cloud#

En Square Cloud, el balanceo es por dominio. Subes el mismo código a varias aplicaciones y asocias el mismo dominio personalizado a todas; el subdominio squareweb.app no entra en el balanceo. Configuras el dominio creando en tu registrador los registros DNS que muestra el panel (mira cómo usar un dominio personalizado).

El tráfico del dominio se reparte en round robin entre las aplicaciones, con failover pasivo (sin health check activo) si una de ellas deja de estar disponible. No hay cobro por petición. El dominio personalizado empieza en el plan Standard, que permite hasta 2 aplicaciones por dominio. El Pro permite hasta 5 y el Enterprise, hasta 10.

Como el algoritmo es round robin y no hay sticky session, cada petición puede caer en una aplicación distinta, y cada una tiene su propio disco. Guarda las sesiones en una base de datos o en Redis, no en la memoria del proceso. Mira el paso a paso en balanceo de carga.

Red

Dominio propio, TLS automático y CDN global para tu app

Más información

Preguntas frecuentes

¿Cuál es el mejor algoritmo de balanceo de carga?

No hay uno mejor para todos los casos. Round robin sirve cuando los servidores y las peticiones son parecidos, least connections cuando la duración de las peticiones varía mucho, e IP hash o hash consistente cuando el mismo cliente tiene que volver al mismo servidor.

¿Qué algoritmo usa nginx por defecto?

Round robin con pesos. Si no declaras ningún método en el bloque upstream, nginx reparte por turnos entre los servidores, y cada uno tiene peso 1 por defecto.

¿Round robin y weighted round robin son distintos?

Sí. En el weighted round robin cada servidor recibe una parte proporcional a su peso. Con pesos 3, 1 y 1, de cada 5 peticiones 3 van al primer servidor.

¿IP hash garantiza una sesión fija?

Casi. La misma IP cae en el mismo servidor mientras la lista de servidores no cambie. Si un servidor entra o sale, parte de los clientes se reasigna, y los clientes detrás del mismo NAT comparten el mismo destino.

Siguiente artículoTimeouts y errores de load balancer: 502, 503 y 504 explicadosUn 504 significa que el load balancer dejó de esperar a tu app; un 502, que recibió una respuesta inválida. Conoce cada timeout, cómo diagnosticarlo y corregirlo.

Más en Redes y dominios

Ver los 27 artículos