En informática , el equilibrio de carga es el proceso de distribuir un conjunto de tareas entre un conjunto de recursos (unidades de cómputo), con el objetivo de hacer que su procesamiento general sea más eficiente. El equilibrio de carga puede optimizar el tiempo de respuesta y evitar sobrecargar de manera desigual algunos nodos de cómputo mientras otros nodos de cómputo permanecen inactivos.
El balanceo de carga es objeto de investigación en el campo de los ordenadores paralelos . Existen dos enfoques principales: los algoritmos estáticos, que no tienen en cuenta el estado de las diferentes máquinas, y los algoritmos dinámicos, que suelen ser más generales y eficientes pero requieren intercambios de información entre las diferentes unidades de computación, con el riesgo de perder eficiencia.
Un algoritmo de balanceo de carga siempre intenta dar respuesta a un problema específico. Entre otras cosas, se deben tener en cuenta la naturaleza de las tareas, la complejidad del algoritmo , la arquitectura de hardware en la que se ejecutarán los algoritmos y la tolerancia a errores requerida. Por lo tanto, se debe encontrar un compromiso para satisfacer mejor los requisitos específicos de la aplicación.
La eficiencia de los algoritmos de balanceo de carga depende fundamentalmente de la naturaleza de las tareas. Por lo tanto, cuanto más información sobre las tareas esté disponible en el momento de la toma de decisiones, mayor será el potencial de optimización.
El conocimiento perfecto del tiempo de ejecución de cada una de las tareas permite alcanzar una distribución óptima de la carga (véase el algoritmo de suma de prefijos ). [1] Desafortunadamente, este es de hecho un caso idealizado. Conocer el tiempo de ejecución exacto de cada tarea es una situación extremadamente rara.
Por este motivo, existen diversas técnicas para hacerse una idea de los distintos tiempos de ejecución. En primer lugar, en el afortunado escenario de tener tareas de tamaño relativamente homogéneo, es posible considerar que cada una de ellas requerirá aproximadamente el tiempo de ejecución medio. Si, por el contrario, el tiempo de ejecución es muy irregular, se deben utilizar técnicas más sofisticadas. Una técnica consiste en añadir unos metadatos a cada tarea. En función del tiempo de ejecución anterior para metadatos similares, es posible hacer inferencias para una tarea futura basándose en estadísticas. [2]
En algunos casos, las tareas dependen unas de otras. Estas interdependencias se pueden ilustrar mediante un gráfico acíclico dirigido . Intuitivamente, algunas tareas no pueden comenzar hasta que se completen otras.
Suponiendo que el tiempo requerido para cada una de las tareas se conoce de antemano, un orden de ejecución óptimo debe conducir a la minimización del tiempo total de ejecución. Aunque este es un problema NP-hard y, por lo tanto, puede ser difícil de resolver con exactitud. Existen algoritmos, como el planificador de tareas , que calculan distribuciones óptimas de tareas mediante métodos metaheurísticos .
Otra característica de las tareas críticas para el diseño de un algoritmo de balanceo de carga es su capacidad de descomponerse en subtareas durante la ejecución. El algoritmo de "computación en forma de árbol" que se presenta más adelante aprovecha en gran medida esta especificidad.
Un algoritmo de balanceo de carga es "estático" cuando no tiene en cuenta el estado del sistema para la distribución de tareas. Por tanto, el estado del sistema incluye medidas como el nivel de carga (y a veces incluso la sobrecarga) de determinados procesadores. En su lugar, se hacen suposiciones de antemano sobre el sistema en su conjunto, como los tiempos de llegada y los requisitos de recursos de las tareas entrantes. Además, se conoce el número de procesadores, su respectiva potencia y velocidades de comunicación. Por tanto, el balanceo de carga estático tiene como objetivo asociar un conjunto conocido de tareas con los procesadores disponibles para minimizar una determinada función de rendimiento. El truco está en el concepto de esta función de rendimiento.
Las técnicas de balanceo de carga estático suelen estar centralizadas alrededor de un enrutador o maestro , que distribuye las cargas y optimiza la función de rendimiento. Esta minimización puede tener en cuenta información relacionada con las tareas a distribuir y derivar un tiempo de ejecución esperado.
La ventaja de los algoritmos estáticos es que son fáciles de configurar y extremadamente eficientes en el caso de tareas relativamente regulares (como procesar solicitudes HTTP de un sitio web). Sin embargo, todavía existe cierta variación estadística en la asignación de tareas que puede provocar la sobrecarga de algunas unidades de procesamiento.
A diferencia de los algoritmos de distribución de carga estática, los algoritmos dinámicos tienen en cuenta la carga actual de cada una de las unidades de cómputo (también llamadas nodos) del sistema. En este enfoque, las tareas se pueden mover dinámicamente de un nodo sobrecargado a un nodo con poca carga para recibir un procesamiento más rápido. Si bien estos algoritmos son mucho más complicados de diseñar, pueden producir excelentes resultados, en particular, cuando el tiempo de ejecución varía mucho de una tarea a otra.
La arquitectura de balanceo de carga dinámico puede ser más modular, ya que no es obligatorio tener un nodo específico dedicado a la distribución del trabajo. Cuando las tareas se asignan de forma única a un procesador según su estado en un momento dado, se trata de una asignación única. Si, por el contrario, las tareas se pueden redistribuir de forma permanente según el estado del sistema y su evolución, se denomina asignación dinámica. [3] Obviamente, un algoritmo de balanceo de carga que requiera demasiada comunicación para alcanzar sus decisiones corre el riesgo de ralentizar la resolución del problema global.
Las infraestructuras de computación paralela suelen estar compuestas por unidades de diferente potencia de cálculo , lo que debe tenerse en cuenta para la distribución de la carga.
Por ejemplo, las unidades de menor potencia pueden recibir solicitudes que requieren una menor cantidad de cálculo o, en el caso de tamaños de solicitud homogéneos o desconocidos, recibir menos solicitudes que las unidades más grandes.
Las computadoras paralelas a menudo se dividen en dos grandes categorías: aquellas en las que todos los procesadores comparten una única memoria común en la que leen y escriben en paralelo ( modelo PRAM ), y aquellas en las que cada unidad de cómputo tiene su propia memoria ( modelo de memoria distribuida ), y donde la información se intercambia mediante mensajes.
En el caso de los ordenadores con memoria compartida , la gestión de conflictos de escritura ralentiza enormemente la velocidad de ejecución individual de cada unidad de cálculo. Sin embargo, pueden funcionar perfectamente bien en paralelo. Por el contrario, en el caso del intercambio de mensajes, cada uno de los procesadores puede trabajar a plena velocidad. Por otro lado, cuando se trata del intercambio colectivo de mensajes, todos los procesadores se ven obligados a esperar a que los procesadores más lentos inicien la fase de comunicación.
En realidad, pocos sistemas encajan exactamente en una de las categorías. En general, los procesadores tienen cada uno una memoria interna para almacenar los datos necesarios para los cálculos siguientes y están organizados en clústeres sucesivos . A menudo, estos elementos de procesamiento se coordinan a través de la memoria distribuida y el paso de mensajes . Por lo tanto, el algoritmo de equilibrio de carga debe adaptarse exclusivamente a una arquitectura paralela. De lo contrario, existe el riesgo de que la eficiencia de la resolución de problemas en paralelo se reduzca considerablemente.
Adaptándose a las estructuras hardware vistas anteriormente, existen dos categorías principales de algoritmos de balanceo de carga. Por un lado, aquel en el que las tareas son asignadas por el “master” y ejecutadas por “workers” que mantienen al master informado del progreso de su trabajo, y el master puede entonces encargarse de asignar o reasignar la carga de trabajo en el caso del algoritmo dinámico. La literatura se refiere a esto como arquitectura “Master-Worker” . Por otro lado, el control puede ser distribuido entre los diferentes nodos. El algoritmo de balanceo de carga se ejecuta entonces en cada uno de ellos y la responsabilidad de asignar tareas (así como reasignar y dividir según corresponda) es compartida. La última categoría supone un algoritmo de balanceo de carga dinámico.
Como el diseño de cada algoritmo de balanceo de carga es único, la distinción anterior debe matizarse. Así, también es posible tener una estrategia intermedia, con, por ejemplo, nodos "maestros" para cada subclúster, que a su vez están sujetos a un "maestro" global. También existen organizaciones multinivel, con una alternancia entre estrategias de control maestro-esclavo y distribuidas. Estas últimas estrategias se vuelven rápidamente complejas y rara vez se encuentran. Los diseñadores prefieren algoritmos que sean más fáciles de controlar.
En el contexto de algoritmos que funcionan a muy largo plazo (servidores, nube...), la arquitectura informática evoluciona con el tiempo. Sin embargo, es preferible no tener que diseñar un nuevo algoritmo cada vez.
Por lo tanto, un parámetro extremadamente importante de un algoritmo de balanceo de carga es su capacidad de adaptarse a una arquitectura de hardware escalable. Esto se denomina escalabilidad del algoritmo. Un algoritmo se considera escalable para un parámetro de entrada cuando su rendimiento permanece relativamente independiente del tamaño de ese parámetro.
Cuando el algoritmo es capaz de adaptarse a un número variable de unidades de cómputo, pero el número de unidades de cómputo debe ser fijo antes de la ejecución, se dice que es moldeable. Si, por otro lado, el algoritmo es capaz de lidiar con una cantidad fluctuante de procesadores durante su ejecución, se dice que el algoritmo es maleable. La mayoría de los algoritmos de equilibrio de carga son al menos moldeables. [4]
Especialmente en clústeres informáticos de gran escala , no es tolerable ejecutar un algoritmo paralelo que no pueda soportar la falla de un solo componente. Por lo tanto, se están desarrollando algoritmos tolerantes a fallas que pueden detectar fallas de procesadores y recuperar el cómputo. [5]
Si las tareas son independientes entre sí, y si su respectivo tiempo de ejecución y las tareas se pueden subdividir, existe un algoritmo simple y óptimo.
Dividiendo las tareas de forma que cada procesador tenga la misma cantidad de cálculos, lo único que queda por hacer es agrupar los resultados. Mediante un algoritmo de suma de prefijos , esta división se puede calcular en tiempo logarítmico con respecto al número de procesadores. [ cita requerida ]
Sin embargo, si las tareas no se pueden subdividir (es decir, son atómicas ), aunque optimizar la asignación de tareas es un problema difícil, aún es posible aproximarse a una distribución relativamente justa de tareas, siempre que el tamaño de cada una de ellas sea mucho menor que el cálculo total realizado por cada uno de los nodos. [1]
La mayoría de las veces, el tiempo de ejecución de una tarea es desconocido y solo se dispone de aproximaciones aproximadas. Este algoritmo, aunque es particularmente eficiente, no es viable para estos escenarios.
Incluso si el tiempo de ejecución no se conoce de antemano, siempre es posible la distribución de carga estática.
En un algoritmo round-robin, la primera solicitud se envía al primer servidor, luego la siguiente al segundo, y así sucesivamente hasta el último. Luego se vuelve a iniciar, asignando la siguiente solicitud al primer servidor, y así sucesivamente.
Este algoritmo se puede ponderar de tal manera que las unidades más potentes reciban la mayor cantidad de solicitudes y las reciban primero.
El balanceo de carga estático aleatorio es simplemente una cuestión de asignar tareas aleatoriamente a los diferentes servidores. Este método funciona bastante bien. Si, por otro lado, se conoce de antemano el número de tareas, es aún más eficiente calcular una permutación aleatoria de antemano. Esto evita los costos de comunicación para cada asignación. Ya no es necesario un maestro de distribución porque cada procesador sabe qué tarea tiene asignada. Incluso si se desconoce el número de tareas, todavía es posible evitar la comunicación con una generación de asignaciones pseudoaleatorias conocida por todos los procesadores.
El rendimiento de esta estrategia (medido en tiempo total de ejecución para un conjunto fijo de tareas) disminuye con el tamaño máximo de las tareas.
Por supuesto, también existen otros métodos de asignación:
Los esquemas maestro-trabajador se encuentran entre los algoritmos de balanceo de carga dinámico más simples. Un maestro distribuye la carga de trabajo a todos los trabajadores (también denominados a veces "esclavos"). Inicialmente, todos los trabajadores están inactivos y se lo informan al maestro. El maestro responde a las solicitudes de los trabajadores y les distribuye las tareas. Cuando no tiene más tareas para asignar, informa a los trabajadores para que dejen de solicitar tareas.
La ventaja de este sistema es que distribuye la carga de forma muy equitativa. De hecho, si no se tiene en cuenta el tiempo necesario para la tarea, el tiempo de ejecución sería comparable a la suma de prefijos que se ha visto anteriormente.
El problema de este algoritmo es que tiene dificultades para adaptarse a un gran número de procesadores debido a la gran cantidad de comunicaciones necesarias. Esta falta de escalabilidad lo hace rápidamente inoperante en servidores muy grandes o en ordenadores paralelos muy grandes. El maestro actúa como un cuello de botella .
Sin embargo, la calidad del algoritmo se puede mejorar mucho si se reemplaza el master por una lista de tareas que puedan utilizar distintos procesadores. Aunque este algoritmo es un poco más difícil de implementar, promete una escalabilidad mucho mejor, aunque todavía insuficiente para centros de computación muy grandes.
Otra técnica para superar los problemas de escalabilidad cuando se desconoce el tiempo necesario para completar una tarea es el robo de trabajo .
El enfoque consiste en asignar a cada procesador un cierto número de tareas de manera aleatoria o predefinida, y luego permitir que los procesadores inactivos "roben" trabajo a los procesadores activos o sobrecargados. Existen varias implementaciones de este concepto, definidas por un modelo de división de tareas y por las reglas que determinan el intercambio entre procesadores. Si bien esta técnica puede ser particularmente efectiva, es difícil de implementar porque es necesario garantizar que la comunicación no se convierta en la ocupación principal de los procesadores en lugar de resolver el problema.
En el caso de tareas atómicas se pueden distinguir dos estrategias principales, aquellas en las que los procesadores con poca carga ofrecen su capacidad de cómputo a los de mayor carga, y aquellas en las que las unidades más cargadas desean aligerar la carga de trabajo que se les asigna. Se ha demostrado [8] que cuando la red está muy cargada es más eficiente que las unidades menos cargadas ofrezcan su disponibilidad y cuando la red está poco cargada son los procesadores sobrecargados los que requieren el apoyo de los más inactivos. Esta regla de oro limita el número de mensajes intercambiados.
En el caso donde se parte de una única gran tarea que no puede ser dividida más allá de un nivel atómico, existe un algoritmo muy eficiente “Tree-Shaped Computation”, [9] donde la tarea padre se distribuye en un árbol de trabajo.
Inicialmente, muchos procesadores tienen una tarea vacía, excepto uno que trabaja secuencialmente sobre ella. Los procesadores inactivos emiten peticiones aleatoriamente a otros procesadores (no necesariamente activos). Si este último es capaz de subdividir la tarea en la que está trabajando, lo hace enviando parte de su trabajo al nodo que realiza la petición. En caso contrario, devuelve una tarea vacía. Esto induce una estructura de árbol . Es entonces necesario enviar una señal de terminación al procesador padre cuando la subtarea se completa para que, a su vez, envíe el mensaje a su padre hasta llegar a la raíz del árbol. Cuando el primer procesador, es decir, la raíz, ha terminado, se puede emitir un mensaje de terminación global. Al final, es necesario ensamblar los resultados volviendo a subir por el árbol.
La eficiencia de un algoritmo de este tipo es cercana a la suma de prefijos cuando el tiempo de corte de trabajo y de comunicación no es demasiado alto en comparación con el trabajo a realizar. Para evitar costos de comunicación demasiado altos, es posible imaginar una lista de trabajos en la memoria compartida . Por lo tanto, una solicitud simplemente lee desde una posición determinada en esta memoria compartida a pedido del procesador maestro.
Además de la resolución eficiente de problemas a través de cálculos paralelos, los algoritmos de equilibrio de carga se utilizan ampliamente en la gestión de solicitudes HTTP , donde un sitio con una gran audiencia debe poder manejar una gran cantidad de solicitudes por segundo.
Una de las aplicaciones más utilizadas del equilibrio de carga es proporcionar un único servicio de Internet desde varios servidores , a veces conocidos como granjas de servidores . Los sistemas con equilibrio de carga más comunes incluyen sitios web populares , grandes redes de Internet Relay Chat , sitios de protocolo de transferencia de archivos (FTP) de gran ancho de banda , servidores de protocolo de transferencia de noticias en red (NNTP), servidores de sistema de nombres de dominio (DNS) y bases de datos.
El DNS round-robin es un método alternativo de equilibrio de carga que no requiere un nodo de hardware o software dedicado. En esta técnica, se asocian varias direcciones IP a un único nombre de dominio ; los clientes reciben la IP de manera round-robin. La IP se asigna a los clientes con un vencimiento corto, de modo que es más probable que el cliente use una IP diferente la próxima vez que acceda al servicio de Internet que se solicita.
Otra técnica más eficaz para equilibrar la carga mediante DNS es delegar www.example.org como subdominio cuya zona esté atendida por cada uno de los mismos servidores que atienden al sitio web. Esta técnica funciona especialmente bien cuando los servidores individuales están distribuidos geográficamente en Internet. Por ejemplo:
Sin embargo, el archivo de zona para www.example.org en cada servidor es diferente, de modo que cada servidor resuelve su propia dirección IP como registro A. [10] En el servidor uno, el archivo de zona para www.example.org informa:
En el servidor dos el mismo archivo de zona contiene:
De esta manera, cuando un servidor está inactivo, su DNS no responderá y el servicio web no recibirá tráfico. Si la línea a un servidor está congestionada, la falta de confiabilidad del DNS garantiza que menos tráfico HTTP llegue a ese servidor. Además, la respuesta DNS más rápida al solucionador es casi siempre la del servidor más cercano de la red, lo que garantiza un equilibrio de carga geosensible [ cita requerida ] . Un TTL corto en el registro A ayuda a garantizar que el tráfico se desvíe rápidamente cuando un servidor deja de funcionar. Se debe tener en cuenta la posibilidad de que esta técnica pueda hacer que los clientes individuales cambien entre servidores individuales en mitad de la sesión.
Otro enfoque para equilibrar la carga es entregar una lista de direcciones IP de servidores al cliente y luego hacer que el cliente seleccione aleatoriamente la IP de la lista en cada conexión. [11] [12] Esto se basa esencialmente en que todos los clientes generen cargas similares y en la Ley de los Grandes Números [12] para lograr una distribución de carga razonablemente plana entre los servidores. Se ha afirmado que el equilibrio de carga aleatorio del lado del cliente tiende a proporcionar una mejor distribución de la carga que el DNS round-robin; esto se ha atribuido a problemas de almacenamiento en caché con el DNS round-robin, que en el caso de grandes servidores de almacenamiento en caché de DNS, tienden a sesgar la distribución para el DNS round-robin, mientras que la selección aleatoria del lado del cliente no se ve afectada independientemente del almacenamiento en caché de DNS. [12]
Con este enfoque, el método de entrega de una lista de direcciones IP al cliente puede variar y puede implementarse como una lista DNS (entregada a todos los clientes sin ningún tipo de operación por turnos) o mediante codificación fija en la lista. Si se utiliza un "cliente inteligente", que detecta que un servidor seleccionado al azar está inactivo y se conecta de nuevo al azar, también proporciona tolerancia a fallos .
En el caso de los servicios de Internet, un equilibrador de carga del lado del servidor suele ser un programa de software que escucha en el puerto en el que los clientes externos se conectan para acceder a los servicios. El equilibrador de carga reenvía las solicitudes a uno de los servidores "de back-end", que normalmente responde al equilibrador de carga. Esto permite que el equilibrador de carga responda al cliente sin que este se entere de la separación interna de funciones. También evita que los clientes se pongan en contacto directamente con los servidores de back-end, lo que puede tener ventajas de seguridad al ocultar la estructura de la red interna y evitar ataques a la pila de red del núcleo o a servicios no relacionados que se ejecutan en otros puertos.
Algunos balanceadores de carga ofrecen un mecanismo para hacer algo especial en caso de que todos los servidores backend no estén disponibles. Esto puede incluir el reenvío a un balanceador de carga de respaldo o mostrar un mensaje sobre la interrupción.
También es importante que el propio balanceador de carga no se convierta en un único punto de fallo . Por lo general, los balanceadores de carga se implementan en pares de alta disponibilidad que también pueden replicar datos de persistencia de sesión si así lo requiere la aplicación específica. [13] Algunas aplicaciones están programadas con inmunidad a este problema, al compensar el punto de equilibrio de carga sobre plataformas de compartición diferencial más allá de la red definida. Los algoritmos secuenciales emparejados con estas funciones se definen mediante parámetros flexibles únicos para la base de datos específica. [14]
Los balanceadores de carga utilizan numerosos algoritmos de programación , también llamados métodos de balanceo de carga, para determinar a qué servidor back-end enviar una solicitud. Los algoritmos simples incluyen la elección aleatoria, round robin o el menor número de conexiones. [15] Los balanceadores de carga más sofisticados pueden tener en cuenta factores adicionales, como la carga informada de un servidor, los tiempos de respuesta mínimos, el estado activo/inactivo (determinado por una encuesta de monitoreo de algún tipo), una cantidad de conexiones activas, la ubicación geográfica, las capacidades o la cantidad de tráfico que se le ha asignado recientemente.
Una cuestión importante al operar un servicio con balanceo de carga es cómo manejar la información que debe mantenerse a lo largo de las múltiples solicitudes en la sesión de un usuario. Si esta información se almacena localmente en un servidor backend, las solicitudes posteriores que se dirijan a diferentes servidores backend no podrán encontrarla. Esta podría ser información almacenada en caché que se puede volver a calcular, en cuyo caso el balanceo de carga de una solicitud a un servidor backend diferente solo introduce un problema de rendimiento. [15]
Lo ideal es que el grupo de servidores detrás del balanceador de carga no tenga en cuenta las sesiones, de modo que si un cliente se conecta a cualquier servidor backend en cualquier momento, la experiencia del usuario no se vea afectada. Esto se suele lograr con una base de datos compartida o una base de datos de sesión en memoria como Memcached .
Una solución básica al problema de los datos de sesión es enviar todas las solicitudes de una sesión de usuario de manera consistente al mismo servidor backend. Esto se conoce como "persistencia" o "persistencia". Una desventaja significativa de esta técnica es su falta de conmutación por error automática : si un servidor backend deja de funcionar, su información por sesión se vuelve inaccesible y se pierden todas las sesiones que dependen de ella. El mismo problema suele ser relevante para los servidores de bases de datos centrales; incluso si los servidores web son "sin estado" y no "persistentes", la base de datos central sí lo es (ver a continuación).
La asignación a un servidor en particular puede basarse en un nombre de usuario, una dirección IP del cliente o ser aleatoria. Debido a los cambios en la dirección percibida del cliente que resultan de DHCP , la traducción de direcciones de red y los servidores proxy web , este método puede no ser confiable. El balanceador de carga debe recordar las asignaciones aleatorias, lo que genera una carga en el almacenamiento. Si el balanceador de carga se reemplaza o falla, esta información puede perderse y es posible que sea necesario eliminar las asignaciones después de un período de tiempo de espera o durante períodos de alta carga para evitar exceder el espacio disponible para la tabla de asignaciones. El método de asignación aleatoria también requiere que los clientes mantengan algún estado, lo que puede ser un problema, por ejemplo, cuando un navegador web ha deshabilitado el almacenamiento de cookies. Los balanceadores de carga sofisticados utilizan múltiples técnicas de persistencia para evitar algunas de las deficiencias de cualquier método.
Otra solución es mantener los datos por sesión en una base de datos . Esto generalmente es malo para el rendimiento porque aumenta la carga en la base de datos: la base de datos se utiliza mejor para almacenar información menos transitoria que los datos por sesión. Para evitar que una base de datos se convierta en un único punto de falla y para mejorar la escalabilidad , la base de datos a menudo se replica en varias máquinas y se utiliza el equilibrio de carga para distribuir la carga de consultas entre esas réplicas. La tecnología ASP.net State Server de Microsoft es un ejemplo de una base de datos de sesión. Todos los servidores de una granja web almacenan sus datos de sesión en State Server y cualquier servidor de la granja puede recuperar los datos.
En el caso muy común en el que el cliente es un navegador web, un enfoque simple pero eficiente es almacenar los datos por sesión en el propio navegador. Una forma de lograr esto es usar una cookie del navegador , debidamente sellada con tiempo y cifrada. Otra es la reescritura de URL . Almacenar datos de sesión en el cliente es generalmente la solución preferida: entonces el balanceador de carga es libre de elegir cualquier servidor backend para manejar una solicitud. Sin embargo, este método de manejo de datos de estado es poco adecuado para algunos escenarios de lógica empresarial complejos, donde la carga útil del estado de la sesión es grande y no es posible volver a calcularla con cada solicitud en un servidor. La reescritura de URL tiene importantes problemas de seguridad porque el usuario final puede alterar fácilmente la URL enviada y, por lo tanto, cambiar los flujos de sesión.
Otra solución para almacenar datos persistentes es asociar un nombre a cada bloque de datos y utilizar una tabla hash distribuida para asignar de forma pseudoaleatoria ese nombre a uno de los servidores disponibles y luego almacenar ese bloque de datos en el servidor asignado.
Los balanceadores de carga de hardware y software pueden tener una variedad de características especiales. La característica fundamental de un balanceador de carga es poder distribuir las solicitudes entrantes entre una cantidad de servidores back-end en el clúster de acuerdo con un algoritmo de programación. La mayoría de las siguientes características son específicas del proveedor:
El equilibrio de carga puede ser útil en aplicaciones con enlaces de comunicaciones redundantes. Por ejemplo, una empresa puede tener varias conexiones a Internet que garanticen el acceso a la red si una de las conexiones falla. Un sistema de conmutación por error implicaría que un enlace se designa para el uso normal, mientras que el segundo enlace se utiliza solo si el enlace principal falla.
Mediante el balanceo de carga, ambos enlaces pueden estar en uso todo el tiempo. Un dispositivo o programa monitorea la disponibilidad de todos los enlaces y selecciona la ruta para enviar paquetes. El uso de múltiples enlaces simultáneamente aumenta el ancho de banda disponible.
TRILL (Interconexión transparente de muchos enlaces) facilita que una Ethernet tenga una topología arbitraria y permite la división de carga por pares de flujo mediante el algoritmo de Dijkstra , sin configuración ni intervención del usuario. El catalizador de TRILL fue un evento en el Centro Médico Beth Israel Deaconess que comenzó el 13 de noviembre de 2002. [16] [17] El concepto de Rbridges [18] [sic] se propuso por primera vez al Instituto de Ingenieros Eléctricos y Electrónicos en el año 2004, [19] quienes en 2005 [20] rechazaron lo que llegó a conocerse como TRILL, y en los años 2006 a 2012 [21] idearon una variación incompatible conocida como Shortest Path Bridging .
El IEEE aprobó el estándar IEEE 802.1aq en mayo de 2012, [22] también conocido como Shortest Path Bridging (SPB). SPB permite que todos los enlaces estén activos a través de múltiples rutas de igual costo, proporciona tiempos de convergencia más rápidos para reducir el tiempo de inactividad y simplifica el uso del equilibrio de carga en topologías de red en malla (parcialmente conectadas y/o completamente conectadas) al permitir que el tráfico comparta la carga entre todas las rutas de una red. [23] [24] SPB está diseñado para eliminar virtualmente el error humano durante la configuración y conserva la naturaleza plug-and-play que estableció a Ethernet como el protocolo de facto en la capa 2. [25]
Muchas empresas de telecomunicaciones tienen múltiples rutas a través de sus redes o hacia redes externas. Utilizan un sofisticado equilibrio de carga para cambiar el tráfico de una ruta a otra para evitar la congestión de la red en cualquier enlace en particular y, a veces, para minimizar el costo de tránsito a través de redes externas o mejorar la confiabilidad de la red .
Otra forma de utilizar el balanceo de carga es en las actividades de monitoreo de red . Los balanceadores de carga se pueden utilizar para dividir flujos de datos enormes en varios subflujos y utilizar varios analizadores de red, cada uno de los cuales lee una parte de los datos originales. Esto es muy útil para monitorear redes rápidas como 10GbE o STM64, donde el procesamiento complejo de los datos puede no ser posible a velocidad de cable . [26]
El equilibrio de carga se utiliza ampliamente en las redes de centros de datos para distribuir el tráfico a través de muchas rutas existentes entre dos servidores. [27] Permite un uso más eficiente del ancho de banda de la red y reduce los costos de aprovisionamiento. En general, el equilibrio de carga en las redes de centros de datos se puede clasificar como estático o dinámico.
El balanceo de carga estático distribuye el tráfico calculando un hash de las direcciones de origen y destino y los números de puerto de los flujos de tráfico y utilizándolo para determinar cómo se asignan los flujos a una de las rutas existentes. El balanceo de carga dinámico asigna los flujos de tráfico a las rutas mediante el monitoreo del uso del ancho de banda en diferentes rutas. Las asignaciones dinámicas también pueden ser proactivas o reactivas. En el primer caso, la asignación es fija una vez realizada, mientras que en el segundo, la lógica de red sigue monitoreando las rutas disponibles y cambia los flujos a través de ellas a medida que cambia la utilización de la red (con la llegada de nuevos flujos o la finalización de los existentes). Se ha puesto a disposición una descripción general completa del balanceo de carga en redes de centros de datos. [27]
El balanceo de carga se utiliza a menudo para implementar la conmutación por error (la continuación del servicio después de la falla de uno o más de sus componentes). Los componentes se monitorean continuamente (por ejemplo, los servidores web pueden monitorearse mediante la obtención de páginas conocidas) y, cuando uno deja de responder, se informa al balanceador de carga y ya no le envía tráfico. Cuando un componente vuelve a estar en línea, el balanceador de carga comienza a redirigir el tráfico hacia él. Para que esto funcione, debe haber al menos un componente que exceda la capacidad del servicio ( redundancia N+1 ). Esto puede ser mucho menos costoso y más flexible que los enfoques de conmutación por error donde cada componente activo se empareja con un solo componente de respaldo que toma el control en caso de una falla ( redundancia modular dual ). Algunos sistemas RAID también pueden utilizar repuesto en caliente para un efecto similar. [28]
Shortest Path Bridging reemplazará a Spanning Tree en la estructura Ethernet.