Simulación de Eventos Discretos · Tema 29

Sistemas con múltiples servidores

Paralelismo, reparto y escala — cuándo el segundo servidor rescata, el tercero pule y la fila única aprovecha cada hueco.

01 · Punto de partida

El segundo rescata, el cuarto decora

Una caja con ρ = 1.8 vive en avalancha. Abrís la segunda y ρ cae a 0.9: la fila respira. Abrís la tercera y ρ cae a 0.6: vuela. Abrís la cuarta y casi no se nota: los tres ya daban abasto. Cada servidor extra rinde menos (Tema 22), pero el salto de 1 a 2 puede ser la diferencia entre colapso y calma.

Ese es el sistema M/M/c: c servidores idénticos en paralelo con fila única hacia el primero libre. Paralelismo da capacidad, reparto la aprovecha, escala decide cuántos pagar.

  • ¿Cuántos servidores hacen falta para ρ < 1 y para Wq aceptable?
  • ¿Fila única o una fila por servidor?
  • ¿Cuánto mejora cada servidor extra y cuándo frenar?
  • ¿Cómo predigo Wq con c > 1 sin simular?

02 · Definición

Paralelismo, reparto y escala

c

Paralelismo

c servidores idénticos atienden a la vez. Capacidad cμ; estado = nº ocupados (0…c) + cola.

→

Reparto

Fila única hacia el primero libre. Sin decisiones por cliente: el hueco manda. (Filas separadas = Tema 22.)

%

Escala

Cada c extra baja Wq con retornos decrecientes. Dimensionar es parar donde el ahorro paga el salario.

Mismo λ = 0.9/min, S = 2 (μ = 0.5): sumar c rescata.
cρ = λ/cμRégimenWq M/M/c
11.80Avalancha∞ (no estabiliza)
20.90Tenso≈ 8 min (rescate)
30.60Ágil≈ 0.9 min (pulido)
40.45Sobra≈ 0.2 min (lujo)

03 · El corazón: pooling

Fila única que aprovecha huecos

llega→¿alguno libre?→primero libre o espera

Con filas separadas, un cliente queda clavado en su fila mientras otra caja se libera (el supermercado clásico). Con fila única, cada liberación toma al primero de la cola: ningún servidor descansa habiendo espera. Esa ganancia se llama pooling: el mismo c rinde más unido que partido. Erlang C la cuantifica: es la probabilidad de esperar C(c,a), que cae fuerte con cada c extra hasta aplanarse.

  1. 1
    Estimar λ y μ.

    Como en c=1. La oferta es a = λ/μ (erlangs): los servidores “ocupados equivalentes”.

  2. 2
    Probar c con ρ.

    ρ = a/c < 1 es el piso: c mínimo = ⌈a⌉ + 1 en la práctica (con ⌈a⌉ apenas respira).

  3. 3
    Predecir con Erlang C.

    Wq = C(c,a)/(cμ − λ). Un renglón para comparar c = 2, 3, 4 (bloque Python).

  4. 4
    Validar con fila única.

    Simular con libre_en[c] y asignar al mínimo: si difiere de Erlang C, el reparto está mal.

Erlang C
P(esperar) en M/M/c: C(c,a) = [ac/(c!(1−ρ))] / [Σk<c ak/k! + ac/(c!(1−ρ))]. Con ella, Lq = C·ρ/(1−ρ).
Pooling
Unir capacidad y cola: c juntos esperan menos que c separados con la misma λ repartida. El lab lo muestra bajando Wq a igual ρ.
Retornos decrecientes
El 2º parte la espera, el 5º la roza. Dimensionar es frenar donde ΔWq ya no paga el servidor.
Heterogéneos
Si difieren (caja rápida/lenta), el estado ya no es un contador: importa cuál está libre y la regla de asignación (Tema 22).

Filas separadas

Huecos desperdiciados

Cada fila es un M/M/1 chico con λ/c. Un servidor ocioso no ayuda a la fila vecina: espera mayor a igual c.

Fila única (pooling)

Cada hueco rinde

Un M/M/c con la λ total. Menor Wq, menor varianza y justicia FIFO global. El cartel “pase al primero libre” es pooling.

04 · Ejemplos

Cuatro c que conocés

  1. 1
    Banco 2 cajas, fila única.

    El cartel “avance al primero libre” es Erlang C en la pared: dos rinden casi como una doble de rápida.

  2. 2
    Call center 8 agentes.

    a = 6 erlangs ⇒ ρ = 0.75. Erlang C dimensiona para “80% atendido en 20 s”.

  3. 3
    Peaje 4 cabinas.

    En pico abre la 4ª: ρ baja de 0.95 a 0.7 y la cola deja la ruta.

  4. 4
    Web 8 workers.

    Requests a memoria compartida: pooling perfecto, sin costo de reparto visible.

05 · Representación en Python

Erlang C en un renglón, reparto en tres

La teoría predice con factoriales; la simulación reparte con min(libre_en). Ambas con fila única.

Python en tu navegador. El primero compara c = 1…4 con Erlang C; el segundo simula el reparto y valida. Cambiá c y mirá el rescate.

# Erlang C y Wq M/M/c: lam=0.9/min, S=2 (mu=0.5)
import math
lam, mu = 0.9, 0.5
a = lam / mu
for c in [1, 2, 3, 4]:
    rho = a / c
    if rho >= 1:
        print(f"c={c} rho={rho:.2f} avalancha"); continue
    s = sum(a**k / math.factorial(k) for k in range(c))
    C = (a**c / (math.factorial(c) * (1 - rho))) / (s + a**c / (math.factorial(c) * (1 - rho)))
    print(f"c={c} rho={rho:.2f} P(espera)={C:.2f} Wq={C/(c*mu-lam):.2f}")
# Reparto fila única: Poisson + Exp, c=2, T=200
import random
random.seed(29)
lam, mu, c, T = 0.9, 0.5, 2, 200.0
t, libres, wqs = 0.0, [0.0]*c, []
while t < T:
    t += random.expovariate(lam)
    k = min(range(c), key=lambda j: libres[j])
    ini = max(t, libres[k])
    libres[k] = ini + random.expovariate(mu)
    wqs.append(ini - t)
print(f"Wq sim={sum(wqs)/len(wqs):.2f} (teoría ~8 con c=2)")

06 · Exploración

Laboratorio: sumar c, domar ρ

Simulamos M/M/c con fila única hasta T = 60 (semilla fija). La escalera es N(t); la línea punteada es c (si N > c, hay cola). Subí c con λ y S fijos: verás la escalera dejar de vivir arriba de c y la Wq derretirse — con retornos decrecientes.

EXPERIMENTO 29

Pooling: cada servidor extra rinde menos

ρ = λS/c · Wq = C(c,a)/(cμ−λ)

Los resultados numéricos aparecen debajo.
ρ = λS/c0
Wq simulada0
Wq teórica M/M/c0
% que espera0%

Sumá c para domar la cola.

Escalera lima = N(t); punteada blanca = c. Por encima de c hay cola; por debajo sobran manos. La Wq teórica usa Erlang C.

Preguntas para explorar

  1. Con λ=0.5, S=2: ¿Wq con c=1 (ρ=1.0) vs c=2 (ρ=0.5)? ¿Qué hizo el segundo?
  2. Con c=2 y λ=0.75, S=2 (ρ=0.75): ¿% que espera? ¿Y con c=3 (ρ=0.5)?
  3. De c=3 a c=4 con ρ ya baja: ¿cuánto baja Wq? ¿Pagarías ese servidor?
Ver respuestas sugeridas
  1. c=1 avalancha (sin teoría); c=2 Wq ≈ 1: el segundo rescata del colapso a la calma.
  2. c=2 espera ~50–60%; c=3 ~25–35%: el tercero pule. (Valores sim con T=60 ± ruido.)
  3. Apenas décimas: pooling ya rindió. Solo se paga si el SLA lo exige o el pico crece.

07 · Comprensión

Confusiones frecuentes

«Doble de servidores, mitad de espera»

No es lineal: de avalancha a calma el salto es gigante; en régimen el 4º apenas mueve Wq. Se dimensiona por curva, no por regla de tres.

«Una fila por servidor es lo mismo»

Es c veces M/M/1 con λ/c: siempre espera más que el M/M/c unido. Fila única o pooling perdido.

«ρ = 0.9 con c=3 es igual que con c=1»

ρ igual, espera distinta: a igual ρ, más c ⇒ menos Wq (más manos absorben rachas). Erlang C lo cuantifica.

«Servidores distintos se promedian»

Promediar μ rápida+lenta inventa un cμ falso: el reparto importa (la lenta frena). Se modelan uno por uno.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: mínimo para estabilizar

λ=0.9/min, S=2. ¿c mínimo con ρ < 1? ¿ρ con ese c?

lam, S = 0.9, 2.0
a = lam * S
c = int(a) + 1
print(f"a={a} c_min={c} rho={a/c:.2f}")  # a=1.8 c=2 rho=0.90
Ver solución razonada

a = 1.8 erlangs ⇒ c = 2 (ρ=0.9, tenso) y c = 3 lo deja en 0.6 (ágil). El mínimo estabiliza; el siguiente humaniza.

Ejercicio 2: leer Erlang C

Con el bloque Python, ¿P(espera) con c=2 y c=3 para λ=0.9, μ=0.5?

# Reutilizá el bloque de Erlang C: con c=2 da ~0.85, con c=3 ~0.35
print("c=2 espera la mayoría; c=3 espera uno de cada tres")
Ver solución

C(2,1.8) ≈ 0.85 y C(3,1.8) ≈ 0.35: el tercer servidor parte la probabilidad de esperar, no solo la media.

Ejercicio 3: fila única vs separadas

λ=0.9 total en 2 filas separadas (0.45 cada una, c=1). ¿ρ y Wq por fila vs M/M/2?

Ver una posible respuesta
lam, mu = 0.45, 0.5
print(f"separadas: rho={lam/mu:.2f} Wq={lam/(mu*(mu-lam)):.1f} vs M/M/2 Wq~8x menos")

Separadas: ρ=0.9, Wq≈18 por fila; unidas M/M/2: Wq≈8 total. Mismo personal, pooling mediante.

09 · Síntesis

Ideas para recordar

  • c en paralelo + fila única: ρ = λ/(cμ), capacidad cμ.
  • Erlang C da P(espera) y Wq: el 2º rescata, el 4º decora.
  • Pooling: unir rinde más que partir (M/M/c vs c×M/M/1).
  • En Python: libre_en[c] al mínimo; teoría con factoriales.
  • A igual ρ, más c espera menos: dimensionar por Wq, no solo por ρ.

En el próximo tema pondremos nombre a todo esto: la notación de Kendall.