2009-11-04 16 views
5

Tengo que mover una aplicación multiproceso de Windows (que utiliza variables globales y un RDBMS para el almacenamiento) a un NLB (es decir, equilibrador de carga de red) cluster Los problemas de arquitectura comunes que vienen a la mente sonProblemas comunes en el desarrollo de aplicaciones empresariales no basadas en web conscientes del clúster

  • Las variables globales (que son a la vez leído/escrito) tendrá que ser trasladado a un almacenamiento compartido. ¿Cuáles son las mejores prácticas aquí? ¿Hay algo disponible en Windows Clustering API para administrar tales cosas?

  • Mi aplicación usa sockets, y las conexiones persistentes son una norma en el campo donde trabajo. Creo que las conexiones persistentes no se pueden equilibrar en la carga. Una vez más, ¿cuáles son las recomendaciones arquitectónicas en este sentido?

Respuesta

7

Voy a responder primero a la parte de la conexión persistente porque es más fácil. Todas las buenas soluciones de equilibrio de carga de red (incluido el servicio NLB de Microsoft integrado en Windows Server, pero también los dispositivos de equilibrio de carga como F5 BigIP) tienen la capacidad de "pegar" las conexiones individuales de los clientes a nodos de clúster específicos durante la conexión. En la NLB de Microsoft esto se llama "Single Affinity", mientras que otros equilibradores de carga lo llaman "Sesiones adhesivas". A veces hay advertencias (por ejemplo, la NLB de Microsoft romperá las conexiones si se agrega un nuevo miembro al clúster, aunque una sola conexión nunca se mueve de un host a otro).

re: variables globales, son la ruina de los sistemas de carga equilibrada. La mayoría de los diseñadores de aplicaciones con equilibrio de carga harán un lote de re-arquitectura para minimizar la dependencia del estado compartido ya que impide la escalabilidad y la disponibilidad de una aplicación de equilibrio de carga. La mayoría de estos enfoques se reducen a una estrategia de dos pasos: primero, mover el estado compartido a una ubicación de alta disponibilidad, y segundo, cambiar la aplicación para minimizar el número de veces que se debe acceder al estado compartido.

La mayoría de las aplicaciones en clúster que he visto almacenarán el estado compartido (incluso el estado volátil compartido, como las variables globales) en un RDBMS. Esto es principalmente por conveniencia. También puede usar un in-memory database para un rendimiento máximo. Pero la simplicidad de usar un RDBMS para todo el estado compartido (transitorio y duradero), más el uso de herramientas de bases de datos existentes para alta disponibilidad, tiende a funcionar para muchos servicios. El rendimiento de un RDBMS es, por supuesto, órdenes de magnitud más lento que las variables globales en la memoria, pero si el estado compartido es pequeño, leerá de todos modos el caché del RDBMS, y si está haciendo una red hop para leer/escribir los datos la diferencia es relativamente menor. También puede marcar una gran diferencia optimizando el esquema de su base de datos para una lectura/escritura rápida, por ejemplo, eliminando índices innecesarios y usando NOLOCK para todas las consultas leídas donde no se requiere exactitud exacta de hasta milisegundos.

No digo que un RDBMS siempre será la mejor solución para el estado compartido, solo que mejorar los tiempos de acceso al estado compartido no suele ser la forma en que las aplicaciones con equilibrio de carga obtienen su rendimiento, sino que obtienen rendimiento por eliminando la necesidad de acceder de forma síncrona (y, especialmente, escribir) estado compartido en cada solicitud. Esa es la segunda cosa que anoté más arriba: cambiar su aplicación para reducir la dependencia del estado compartido.

Por ejemplo, para simples "contadores" y métricas similares, las aplicaciones a menudo pondrán en cola sus actualizaciones y tendrán un solo hilo a cargo de actualizar el estado compartido de forma asíncrona desde la cola.

Para casos más complejos, las aplicaciones pueden surgir de Concurrencia pesimista (verificando que un recurso esté disponible de antemano) en Optimistic Concurrency (suponiendo que esté disponible y luego anular el trabajo si terminó, por ejemplo, vendiendo el mismo artículo a dos clientes diferentes!).

Net-net, en situaciones de equilibrio de carga, las soluciones de fuerza bruta a menudo no funcionan tan bien como pensar creativamente acerca de su dependencia en estado compartido y encontrar formas ingeniosas para evitar tener que esperar para leer o escribir sincrónicamente estado en cada solicitud.

No me molestaría en utilizar MSCS (Microsoft Cluster Service) en su escenario. MSCS es una solución de conmutación por error, lo que significa que es buena para mantener una aplicación de un servidor altamente disponible incluso si uno de los nodos del clúster falla, pero no obtendrá la escalabilidad y simplicidad que obtendrá de un verdadero servicio de equilibrio de carga. Sospecho que MSCS tiene formas de compartir estado (en un disco compartido) pero requieren configurar un clúster de MSCS que implique la configuración de failover, el uso de un disco compartido y otra complejidad que no es apropiada para la mayoría de las aplicaciones con equilibrio de carga. Es mejor utilizar una base de datos o una solución en memoria especializada para almacenar su estado compartido.

1
  1. concurrencia (Salida Apache Cassandra, et al)
  2. velocidad de la luz temas (si a través del país o internacional va usted querrá un uso intensivo de las transacciones)
  3. copias de seguridad y eliminación de datos duplicados (Empresas como FalconStor o EMC puede ayudar aquí en un sistema distribuido. yo no subestimar la necesidad de consultar aquí)
+0

Gracias por el enlace Apache! – Jaywalker

+0

No hay problema Todavía está en desarrollo, pero escuché que es bastante robusto. – orokusaki

2

en cuanto a conexión persistente mirar en el port rules, debido a las reglas de puerto determinan qué puerto TCPIP se maneja y cómo.

MSDN:

Cuando una regla de puerto utiliza múltiples anfitrión equilibrio de carga, uno de los tres modos de afinidad cliente se selecciona. Cuando no se selecciona el modo de afinidad del cliente , Equilibrio de carga de red equilibra tráfico de cliente desde una dirección IP y diferentes puertos de origen en hosts de varios clústeres. Esto maximiza la granularidad del equilibrio de carga y minimiza el tiempo de respuesta a los clientes. Para ayudar en la gestión de sesiones de cliente, la afinidad predeterminada de un solo cliente equilibra la carga de todo el tráfico de red desde la dirección IP de un cliente dado en un host de clúster único . El modo de afinidad de clase C limita aún más este para equilibrar la carga de todo el tráfico de cliente desde un espacio de dirección de clase única.

En una aplicación asp.net, lo que permite que el estado de la sesión sea persistente es cuando la configuración del parámetro de afinidad del cliente está habilitada; El NLB dirige todas las conexiones TCP de una dirección IP de cliente al mismo host de clúster. Esto permite que el estado de la sesión se mantenga en la memoria del host;

El parámetro de afinidad del cliente garantiza que una conexión siempre se enrutará en el servidor en el que se conectó inicialmente; manteniendo así el estado de la aplicación.

Por lo tanto, creo que ocurriría lo mismo con la aplicación multihilo basada en Windows, si utiliza el parámetro de afinidad.

  1. Network Load Balancing Best practices
  2. Web Farming with the Network Load Balancing Service in Windows Server 2003 podría ayudar a darle una visión
Cuestiones relacionadas