2011-03-31 15 views
7

Estoy trabajando en mi proyecto de tesis de bc que debe ser un servidor de Minecraft escrito en Scala y Akka. El servidor debe poder implementarse fácilmente en la nube o en un clúster (no estoy seguro de si uso la terminología adecuada ... debería ejecutarse en múltiples nodos). Sin embargo, soy novato en Akka y me he estado preguntando cómo implementar tal cosa. El problema que estoy tratando de resolver en este momento es cómo compartir el estado entre los actores en diferentes nodos. Mi primera idea fue tener un actor de Camel que leyera tcp stream de clientes de Minecraft y luego lo enviara al equilibrador de carga, que seleccionaría un nodo que procesaría la solicitud y luego enviaría una respuesta al cliente a través de tcp. Digamos que tengo un actor de implementación de AuthenticationService que verifica si las credenciales proporcionadas por el usuario son válidas. Cada nodo tendría tal actor (o quizás más de ellos) y todos los actores deberían tener exactamente la misma base de datos (o estado) de usuarios todo el tiempo. Mi pregunta es, ¿cuál es el mejor enfoque para mantener este estado? He encontrado algunas soluciones que podría pensar, pero no he hecho algo así, por favor señale las fallas:Akka y el estado entre los actores en el clúster

Solución # 1: Mantener el estado en una base de datos. Esto probablemente funcionaría muy bien para este ejemplo de autenticación donde el estado solo está representado por algo así como una lista de nombre de usuario y contraseñas, pero probablemente no funcionaría en los casos en que el estado contiene objetos que no pueden dividirse fácilmente en enteros y cadenas.

Solución # 2: cada vez que se solicite a un determinado actor que cambie su estado, el actor, después de procesar la solicitud, transmitirá información sobre el cambio a todos los demás actores del mismo tipo que cambiarían su estado según la información enviada por el actor original. Esto parece muy ineficiente y bastante torpe.

Solución n. ° 3: Tener un nodo determinado sirve como una especie de nodo de estado, en el que habría actores que representan el estado de todo el servidor. Cualquier otro actor, excepto los actores en dicho nodo, no tendría ningún estado y pediría a los actores en el "nodo estatal" cada vez que necesitarían algunos datos. Esto parece ser ineficiente y un poco imperfecto.

Así que ahí lo tienes. La única solución que realmente me gusta es la primera, pero como he dicho, probablemente solo funcione en un subconjunto de problemas muy limitado (cuando el estado se puede dividir en estructuras redis). Cualquier respuesta de gurús más experimentados sería muy acertada. Saludos, Tomas Herman

Respuesta

3

La solución n. ° 1 podría ser lenta. Además, es un cuello de botella y un único punto de falla (lo que significa que la aplicación deja de funcionar si el nodo con la base de datos falla). La solución n. ° 3 tiene problemas similares.

La solución n. ° 2 es menos trivial de lo que parece. Primero, es un punto único de falla. En segundo lugar, no hay atomicidad u otras garantías de ordenamiento (como la regularidad) para lecturas o escrituras, a menos que haga un total order broadcast (que es más caro que una transmisión regular). De hecho, la mayoría de los algoritmos de registro distribuido harán transmisiones bajo el capó, por lo que, si bien es ineficiente, puede ser necesario.

Según lo que ha descrito, necesita atomicidad para su registro distribuido. ¿Qué quiero decir con atomicidad? Atomicity significa que cualquier lectura o escritura en una secuencia de lecturas y escrituras simultáneas aparece como si ocurriera en un solo punto en el tiempo. Informalmente, en la Solución n. ° 2 con un solo actor sosteniendo un registro, esto garantiza que si se producen 2 escrituras posteriores W1 y luego W2 en el registro (es decir, 2 emisiones), entonces ningún otro actor que lea los valores del registro léelos en el orden diferente que primero W1 y luego W2 (en realidad es más complicado que eso). Si revisa un par de ejemplos de transmisiones posteriores donde los mensajes llegan al destino en diferentes momentos, verá que dicha propiedad de pedido no está garantizada en absoluto.

Si ordenar garantías o la atomicidad no son un problema, algún tipo de algoritmo basado en chismes podría hacer el truco para propagar lentamente los cambios a todos los nodos. Esto probablemente no sería muy útil en tu ejemplo.

Si quiere total tolerancia a fallas y atómico, le recomiendo que lea este book sobre programación distribuida confiable por Rachid Guerraoui y Luís Rodrigues, o las partes relacionadas con abstracciones de registros distribuidos. Estos algoritmos se construyen encima de un mensaje que pasa la capa de comunicación y mantienen un registro distribuido que admite operaciones de lectura y escritura. Puede usar dicho algoritmo para almacenar información de estado distribuido. Sin embargo, no son aplicables a miles de nodos o clusters grandes porque no se escalan, por lo general tienen un polinomio de complejidad en la cantidad de nodos.

Por otro lado, puede que no necesite tener el estado del registro distribuido replicado en todos los nodos, replicándolo a través de un subconjunto de sus nodos (en lugar de un solo nodo) y accediendo a ellos para leer o escribir a partir de él, proporcionando un cierto nivel de tolerancia a fallas (solo si todo el subconjunto de nodos falla, se perderá la información del registro). Posiblemente pueda adaptar los algoritmos en el libro para cumplir este propósito.

+0

Oye, muchas gracias por la respuesta. Esto parece mucho más difícil de lo que pensé que sería:]. En realidad, tendré que pensar en el problema por un tiempo para averiguar si realmente REQUIERE atomicidad en las operaciones. Veré el libro, gracias por la propina. O tal vez podría simplemente usar otros nodos como esclavos para el maestro que contendría toda la información y otros nodos simplemente recibirían un mensaje y harían algo de cálculo sobre los datos recibidos del maestro. Sin embargo, todavía no se siente bien. – Arg

+0

De nada. Solo recuerde que el problema de tener un nodo maestro siempre será que es un punto único de falla. Si le preocupa la tolerancia a fallas, eso puede ser un problema. Quizás también pueda consultar algunas de las implementaciones distribuidas de la tabla hash para ver si pueden ayudarlo (por ejemplo, Apache Cassandra). – axel22

+0

Sí, la tolerancia a fallas no es un gran problema. No en esta etapa, de todos modos. Además, necesito algún tipo de nodo privilegiado de la definición de todos modos. A la que los clientes de Minecraft se conectarían. – Arg

Cuestiones relacionadas