me gustaría utilizar Zookeeper + Norbert a saber sobre qué hosts están subiendo y abajo:
http://www.ibm.com/developerworks/library/j-zookeeper/
Ahora cada nodo en mi granja de servidores de chat puede conocer todos los hosts en el cluster lógico. Recibirán una devolución de llamada cuando un nodo se desconecta (o entra en línea). Ahora cualquier nodo puede mantener una lista ordenada de miembros de clúster actuales, hash la ID de sala de chat y mod por tamaño de lista para obtener el índice dentro de la lista, que es el nodo que debe alojar cualquier sala de chat determinada. Podemos agregar 1 y volver a crear un segundo índice (requiere un bucle hasta que obtenga un índice nuevo) para calcular el segundo host para que contenga una segunda copia de la sala de chat para redundancia. En cada uno de los dos hosts de salas de chat hay un actor de sala de chat que reenvía todos los mensajes de chat a cada actor de Websocket que es miembro de la sala de chat.
Ahora podemos enviar mensajes de chat a través de ambos actores de sala de chat activos con un enrutador Akka personalizado. Un cliente simplemente envía el mensaje una vez y el enrutador hará los mods de hash y los enviará a los dos actores remotos de la sala de chat. Usaría el algoritmo de Twitter snowflake para generar identificadores únicos de 64 bits para los mensajes que se envían. Vea el algoritmo en el método nextId() del código en el siguiente enlace. El datacenterId y workerId se pueden ajustar mediante las propiedades Norbert para asegurar que ninguno de chocar identificaciones que se genera en los diferentes servidores:
https://github.com/twitter/snowflake/blob/master/src/main/scala/com/twitter/service/snowflake/IdWorker.scala
Ahora dos copias de cada mensaje se destinará a cada extremo de cliente a través de cada uno de los dos activos actores de sala de chat. En cada actor del cliente de Websocket me gustaría quitar la máscara de bits de las identificaciones de copo de nieve para aprender el número del centro de datos Id + trabajador enviando el mensaje y hacer un seguimiento del número de mensajes de chat más alto visto desde cada host en el clúster. Entonces ignoraría cualquier mensaje que no sea más alto que lo que ya se ha visto en el cliente dado para un host remitente dado. Esto desduplicaría el par de mensajes que llegan a través de los dos actores activos de la sala de chat.
Hasta ahora todo bien; Tendríamos mensajes flexibles en el sentido de que si un nodo muere, no perderemos la única copia superviviente de las salas de chat. Los mensajes fluirán ininterrumpidamente a través de la segunda sala de chat automáticamente.
A continuación tenemos que ocuparnos de los nodos que abandonan el clúster o que se vuelven a agregar al clúster. Obtendremos una devolución de llamada de Norbert dentro de cada nodo para notificarnos sobre los cambios en la membresía del clúster. En esta devolución de llamada podemos enviar un mensaje akka a través del enrutador personalizado que indica la nueva lista de miembros y el nombre de host actual. El enrutador personalizado en el host actual verá ese mensaje y actualizará su estado para conocer la nueva membresía del clúster y calcular el nuevo par de nodos para enviar cualquier tráfico de chat determinado.Este reconocimiento de la nueva membresía del clúster será enviado por el enrutador a todos los nodos para que cada servidor pueda realizar un seguimiento cuando todos los servidores hayan alcanzado el cambio de membresía y ahora estén enviando mensajes correctamente.
La sala de chat superviviente puede seguir activa después del cambio de membresía. En este caso, todos los enrutadores en todos los nodos seguirán enviándolo como normal, pero también enviarán un mensaje especulativo al nuevo segundo host de sala de chat. Es posible que la segunda sala de chat aún no se haya levantado, pero eso no es un problema ya que los mensajes fluirán a través del sobreviviente. Si la sala de chat superviviente ya no está activa después de que la membresía cambie, todos los enrutadores en todos los hosts al principio enviarán a tres hosts; el sobreviviente y los dos nuevos nodos. El mecanismo de vigilancia de akka death se puede usar para que todos los nodos puedan ver eventualmente el apagado de la sala de chat superviviente para volver al tráfico del chat de enrutamiento a través de dos hosts.
A continuación tenemos que migrar la sala de chat del servidor superviviente a uno o dos nuevos hosts, según las circunstancias. El actor de la sala de chat en algún momento recibirá un mensaje contándole sobre la nueva membresía del grupo. Comenzará enviando una copia de la membresía de la sala de chat a los nuevos nodos. Este mensaje creará la nueva copia del actor de sala de chat con la membresía correcta en los nuevos nodos. Si el sobreviviente ya no es uno de los dos nodos que deberían albergar la sala de chat, pasará al modo de desmantelamiento. En el modo de desmantelamiento, solo reenviará los mensajes a los nuevos nodos primarios y secundarios, no a los miembros de la sala de chat. El reenvío de mensajes Akka es perfecto para esto.
Una sala de desactivación escuchará los mensajes de acuse de recibo de membresía de clúster de norbert de cada nodo. Eventualmente verá que todos los nodos dentro del clúster han reconocido la nueva membresía del clúster. Luego sabe que ya no recibirá más mensajes para reenviar. Entonces puede matarse a sí mismo. El hotswapping de Akka es perfecto para implementar el comportamiento de desmantelamiento.
Hasta ahora todo bien; tenemos una configuración de mensajería flexible que no perderá mensajes para un bloqueo de nodo. En el punto en que cambia la membresía del clúster, obtendremos un aumento del tráfico intranodo para copiar las salas de chat a nuevos nodos. También tenemos una ráfaga residual de reenvío intranodo de mensajes a los nodos hasta que todos los servidores se hayan puesto al corriente con qué salas de chat han movido dos servidores. Si queremos ampliar el sistema, podemos esperar hasta un punto bajo en el tráfico del usuario y simplemente activar un nuevo nodo. Las salas de chat se redistribuirían a través de los nuevos nodos automáticamente.
La descripción anterior se basa en la lectura de la siguiente papel y traducirla en conceptos akka:
https://www.dropbox.com/s/iihpq9bjcfver07/VLDB-Paper.pdf
Estoy de acuerdo con la respuesta de Freed y que puede haber simplemente desplazados el problema de un único punto de fallo hacia el almacenamiento. Por supuesto, un caché distribuido es una mejora, pero como dijo Freed no es perfecto. Actualmente estoy accediendo a redis a través de un 'Storage'-Actor implementado que actualmente maneja solicitudes de datos (como obtener la lista de miembros actuales). Si lo hice bien, para mi implementación este sería el lugar para evitar un cuello de botella con una futura implementación de clúster de akka. – th3hamm0r
no necesita esperar las extensiones de agrupamiento Akka, consulte las publicaciones de blog vinculadas en mi respuesta. Akka está muy lejos de soportar el agrupamiento completo. – SoftMemes
La lista de membresías de salas de chat se puede mantener en dos actores en dos servidores para tolerancia a errores con actualizaciones enviadas a ambos. Consulte este documento que describe cómo hacer esto con paxos y hash mod de la ID de sala de chat para asignar host primario/secundario para la sala de chat. Luego, cada cliente websocket calcula los dos servidores para saber cuál es la principal para consultar, y luego volver a la secundaria si ese host baja https://www.dropbox.com/s/iihpq9bjcfver07/VLDB-Paper.pdf (claramente es mejor comprarlo). ese servidor de caché de sesión ahora se llama aerospike que lo escribes tú mismo, pero su algoritmo y diseño es muy informativo). – simbo1905