Mejores prácticas de equilibrio de carga para la persistencia

8

Ejecutamos una aplicación web que sirve API web para un número creciente de clientes. Para comenzar, los clientes eran generalmente redes domésticas, de oficina u otras redes inalámbricas que enviaban cargas http fragmentadas a nuestra API. Ahora nos hemos diversificado para manejar más clientes móviles. Los archivos van desde unos pocos k hasta varios conciertos, desglosados ​​en trozos más pequeños y reensamblados en nuestra API.

Nuestro equilibrio de carga actual se realiza en dos capas, primero utilizamos DNS round robin para anunciar múltiples registros A para nuestra dirección api.company.com. En cada IP, alojamos un LVS de Linux: http://www.linuxvirtualserver.org/ , equilibrador de carga que analiza la dirección IP de origen de una solicitud para determinar a qué servidor API debe transferir la conexión. Estas cajas LVS están configuradas con heartbeatd para hacerse cargo de los VIP externos y las IP de las puertas de enlace internas entre sí.

Últimamente, hemos visto dos nuevas condiciones de error.

El primer error es cuando los clientes están oscilando o migrando de un LVS a otro, a mitad de carga. Esto a su vez hace que nuestros equilibradores de carga pierdan el rastro de la conexión persistente y envíen el tráfico a un nuevo servidor API, rompiendo así la carga fragmentada en dos o más servidores. Nuestra intención era que el valor Round TTL DNS TTL para nuestra api.company.com (que hemos establecido en 1 hora) sea honrado por los servidores de nombres de almacenamiento en caché posteriores, las capas de almacenamiento en caché del sistema operativo y las capas de aplicación del cliente. Este error ocurre para aproximadamente el 15% de nuestras cargas.

El segundo error que hemos visto con mucha menos frecuencia. Un cliente iniciará el tráfico a un cuadro LVS y se enrutará al servidor real A detrás de él. A partir de entonces, el cliente ingresará a través de una nueva dirección IP de origen, que el cuadro LVS no reconoce, por lo que enruta el tráfico en curso al servidor real B también detrás de ese LVS.

Dada nuestra arquitectura como se describe en la parte anterior, me gustaría saber cuáles son las experiencias de las personas con un mejor enfoque que nos permitirá manejar cada uno de los casos de error anteriores con más gracia.

Edición 3/5/2010:

Esto se parece a lo que necesitamos. Hashing de GSLB ponderado en la dirección IP de origen.

http://www.brocade.com/support/Product_Manuals/ServerIron_ADXGlobalServer_LoadBalancingGuide/gslb.2.11.html#271674

dmourati
fuente
Su pregunta no es realmente específica para dispositivos móviles en este momento. ¿Quizás considerarías revisarlo y simplificarlo?
Jesper M

Respuestas:

11

La solución canónica a esto es no confiar en la dirección IP del usuario final, sino utilizar un equilibrador de carga de Capa 7 (HTTP / HTTPS) con "Sesiones fijas" a través de una cookie.

Sesiones fijas significa que el equilibrador de carga siempre dirigirá un cliente determinado al mismo servidor de fondo. Vía cookie significa que el equilibrador de carga (que en sí mismo es un dispositivo HTTP totalmente capaz) inserta una cookie (que el equilibrador de carga crea y gestiona automáticamente) para recordar qué servidor de fondo debe usar una conexión HTTP determinada.

La desventaja principal de las sesiones fijas es que la carga del servidor puede ser algo desigual. El equilibrador de carga solo puede distribuir la carga de manera justa cuando se realizan nuevas conexiones, pero dado que las conexiones existentes pueden ser de larga duración en su escenario, entonces, en algunos períodos de tiempo, la carga no se distribuirá de manera completamente justa.

Casi todos los equilibradores de carga de Capa 7 deberían poder hacer esto. En Unix / Linux, algunos ejemplos comunes son nginx, HAProxy, Apsis Pound, Apache 2.2 con mod_proxy y muchos más. En Windows 2008+ hay enrutamiento de solicitud de aplicación de Microsoft. Como electrodomésticos, Coyote Point, loadbalancer.org, Kemp y Barracuda son comunes en el espacio de gama baja; y F5, Citrix NetScaler y otros de gama alta.

Willy Tarreau, el autor de HAProxy, tiene una buena descripción de las técnicas de equilibrio de carga aquí .

Sobre el DNS Round Robin:

Nuestra intención era que el valor Round TTL DNS TTL para nuestra api.company.com (que hemos establecido en 1 hora) sea honrado por los servidores de nombres de almacenamiento en caché posteriores, las capas de almacenamiento en caché del sistema operativo y las capas de aplicación del cliente.

No sera . Y DNS Round Robin no es una buena opción para el equilibrio de carga . Y si nada más lo convence, tenga en cuenta que los clientes modernos pueden preferir un host sobre todos los demás debido a la fijación de coincidencia de prefijo más larga , por lo que si el cliente móvil cambia la dirección IP, puede optar por cambiar a otro host RR.

Básicamente, está bien usar DNS round robin como una distribución de carga de grano grueso, apuntando 2 o más registros RR a direcciones IP de alta disponibilidad, manejadas por equilibradores de carga reales en HA activa / pasiva o activa / activa. Y si eso es lo que está haciendo, entonces también podría servir esos registros RR de DNS con valores de tiempo de vida largos, ya que las direcciones IP asociadas ya están altamente disponibles.

Jesper M
fuente
Gracias. Estamos en modo activo / activo con LVS. Las IP están altamente disponibles y tenemos mucho control sobre los clientes, ya que los escribimos nosotros mismos y confían en nuestro servidor API, que no es totalmente apátrida como se describió anteriormente. Probé el problema de almacenamiento en caché a nivel del sistema operativo en mi Linux box en el trabajo (no tiene activado el almacenamiento en caché), así como en mi computadora portátil Mac OSX en casa (se almacena en caché en la capa del sistema operativo, que "fija" la IP a un resultado u otro )
dmourati
Terminé escribiendo mi propio servidor DNS personalizado para solucionar el problema del round robin. Mira la dirección IP de origen y utiliza un hash para responder con un registro consistente. Parece estar funcionando y redujo nuestro problema de "interruptor de pop" en un factor de 10.
dmourati
4

Para responder a su pregunta sobre alternativas: Puede obtener un equilibrio de carga de capa 7 sólido a través de HAProxy .

En cuanto a solucionar los problemas de afinidad de LVS, estoy un poco seco con ideas sólidas. Podría ser tan simple como un tiempo de espera o desbordamiento. Algunos clientes móviles cambiarán las direcciones IP mientras estén conectados a la red; tal vez esto puede ser la fuente de tus problemas? Sugeriría, como mínimo, que difunda la granularidad de afinidad al menos a una clase C.

Hippy
fuente
HAProxy definitivamente estaba en mi mira. Leí un artículo bastante interesante sobre el equilibrio de carga L4 v L7. blog.loadbalancer.org/why-layer-7-sucks Mi opinión: me gustaría dejar esto en manos de la aplicación. Cualquier "inteligencia" adicional que agregue a la capa LB solo tendrá que parchearse / modificarse a medida que cambiemos nuestra aplicación. Resolver el problema en la aplicación en sí significa que podemos optimizar y ajustar las cosas en el LB sin dejar de estar seguros de que, incluso si hay un paso en falso de LB, aún obtendremos los datos.
dmourati
@dmourati: Lo siento, pero esa publicación de blog está llena de suposiciones inexactas. No lo sigas ciegamente. Es absolutamente cierto que una arquitectura de "nada compartido" para los servidores de aplicaciones web es "mejor". En ese caso, debe usar Round Robin o Balanceo de carga aleatorio. Pero, siempre que tenga cargas HTTP de varios GB, tendrá conversaciones HTTP de larga duración, y un equilibrador de carga HTTP está mejor posicionado para comprender este largo intercambio HTTP y actuar correctamente. El uso de un equilibrador HTTP no impide hacer que el código de la aplicación de fondo sea "más inteligente", aún puede hacerlo en cualquier momento.
Jesper M