erlang cloud cluster-computing distributed-computing

Grupos de erlang



cloud cluster-computing (5)

Estoy tratando de implementar un clúster utilizando Erlang como el pegamento que lo mantiene todo unido. Me gusta la idea de que crea un gráfico de nodos totalmente conectado, pero al leer diferentes artículos en línea, parece que esto no se adapta bien (con un máximo de 50 a 100 nodos). ¿Los desarrolladores de OTP impusieron esta limitación a propósito? Sé que puede configurar los nodos para que tengan conexiones explícitas, así como para tener nodos ocultos, etc. Pero, parece que la configuración predeterminada lista para usar no es muy escalable.

Así que a las preguntas:

  1. Si tenía 5 nodos (A, B, C, D, E), todos tenían conexiones explícitas tales como ABCDE. ¿Erlang / OTP le permite a A hablar directamente a E o A tiene que pasar mensajes de B a D para llegar a E, y esa es la razón para el gráfico totalmente conectado? De nuevo, tiene sentido pero no se adapta bien a lo que he visto.

  2. Si uno intentara buscar un sistema escalable y tolerante a fallos, ¿cuáles son sus opciones? Parece que, si no puede crear un gráfico totalmente conectado porque tiene demasiados nodos, lo mejor sería crear un árbol de algún tipo. Pero, esto no parece ser muy tolerante a fallos porque si la raíz o cualquier padre de los nodos secundarios muere, perdería una parte importante de su agrupación.

  3. Al analizar a los supervisores y trabajadores, todos los ejemplos que he visto aplican esto a los procesos en un solo nodo. ¿Podría aplicarse a un grupo de nodos para ayudar a implementar la tolerancia a fallos?

  4. ¿Pueden los nodos ser parte de varios grupos?

Gracias por su ayuda, si me he perdido un sitio web o blog post-reciente (de aproximadamente 1 año de edad), me encantaría verlos. Pero, he rastreado el internet bastante bien.


  1. Sí, puede enviar mensajes a un proceso en cualquier nodo remoto de un clúster, por ejemplo, utilizando su identificador de proceso (pid). Esto se llama transparencia de ubicación. Y sí, se escala bien (consulte Riak, CouchDB, RabbitMQ, etc.).

  2. Tenga en cuenta que un nodo puede ejecutar cientos de miles de procesos. Erlang ha demostrado ser muy escalable y fue construido para la tolerancia a fallas. Hay otros enfoques para construir más grande, por ejemplo, el enfoque SOA de CloudI (ver comentarios). También puede crear clústeres que utilicen nodos ocultos si realmente lo necesita.

  3. En el nivel de nodo, debería adoptar un enfoque diferente, por ejemplo, construir nodos idénticos que sean fáciles de reemplazar si fallan y el trabajo es asumido por los nodos restantes. Echa un vistazo a cómo Riak maneja esto (mira riak_core y consulta la publicación del blog Introducción a Riak Core ).

  4. Los nodos pueden salir e ingresar a un clúster, pero no pueden formar parte de varios clústeres al mismo tiempo. Los nodos conectados comparten una cookie de clúster que se utiliza para identificar los nodos conectados. Puede configurar la cookie mientras se está ejecutando la máquina virtual (ver Distributed Erlang ).

Lea http://learnyousomeerlang.com/ para mayor bien.


1) Creo que necesita una conexión directa entre nodos para comunicarse entre procesos. Sin embargo, esto significa que no necesita conexiones persistentes entre todos los nodos si dos nunca se comunicarán (digamos si solo son trabajadores, no coordinadores).

2) Puede crear un gráfico no totalmente conectado de nodos erlang. La documentación es difícil de encontrar y viene con problemas: deshabilita el sistema global que maneja los nombres globales en el clúster, por lo que tiene que hacer todo por nombres registrados localmente o nombres registrados localmente en nodos remotos. O simplemente usar Pids, ya que funcionan también. Para iniciar un nodo erlang como este, use erl ... -connect_all false ... Espero que sepas lo que estás haciendo, ya que no podía confiar en mí mismo para hacer eso.

También resulta que un gráfico no totalmente conectado de nodos erlang es un tema de investigación actual. El proyecto RELEASE actualmente está trabajando exactamente en eso, y ha creado un concepto de grupos S, que son esencialmente grupos totalmente conectados. Sin embargo, los nodos pueden ser miembros de más de un grupo S y los nodos en grupos s separados no tienen que estar completamente conectados, pero pueden establecer las conexiones que necesitan bajo demanda para realizar una comunicación directa de nodo a nodo. Vale la pena encontrar presentaciones de ellos porque la investigación es realmente interesante.

Otra cosa que vale la pena señalar es que varias personas han descubierto que puede obtener hasta 150-200 nodos en un clúster totalmente conectado. ¿Realmente tiene un caso de uso para más nodos que eso? Seguramente, 150-200 computadoras increíblemente robustas harían la mayoría de las cosas que podrías lanzarles, a menos que tengas un proyecto ridículo que hacer.

3) Si bien no puede iniciar procesos en un nodo diferente usando gen_server:start_link/3,4 , ciertamente puede llamar a servidores en un nodo externo con mucha facilidad. Parece que han pasado por alto el hecho de poder iniciar servidores en nodos externos, pero probablemente haya una buena razón para ello, como un número ridículo de casos de error.

4) Intente ver los nodos ocultos y tener un clúster no completamente conectado. Deben permitirte agrupar los nodos como mejor te parezca.

TL; DR: escalar es difícil, vamos de compras.


1) si se hablan el uno al otro

2) 3) y 4) En términos generales, al crear un sistema escalable y tolerante a fallos, desearía, o más aún, dividir la carga de trabajo en diferentes "regiones" o "grupos". El modelo Supervisor / Trabajador tiene esto previsto así la topología. Lo que necesita es unos pocos procesos que coordinen el trabajo entre los grupos y todos los trabajadores dentro de un solo grupo se comunicarán entre sí para equilibrar el grupo.

Como puede ver, con esta topología, la "limitación" no es realmente una limitación siempre que divida sus tareas con cuidado y de manera equilibrada. Personalmente, creo que una estructura similar a un árbol para los procesos de supervisión no se puede evitar en sistemas a gran escala, y esta es la práctica que estoy siguiendo. Las razones varían, pero se reducen a la escalabilidad, la tolerancia a fallos como la implementación de la política de retroceso, las necesidades de mantenimiento y la portabilidad de los clústeres.

Así que en conclusión,

2) use una topología en forma de árbol para sus supervisores. permita que los trabajadores se conecten entre sí explícitamente y hablen dentro de su propio dominio con los supervisores.

3) si bien este es el entorno diseñado de forma nativa, como supongo, estoy bastante seguro de que un supervisor puede hablar con un trabajador en una máquina diferente. No sugeriría esto ya que la tolerancia a fallas puede ser un infierno en el escenario de un trabajador remoto.

4) nunca debe permitir que un nodo sea parte de dos grupos diferentes en el mismo momento. Puede cambiarlo de un clúster a otro sin embargo.


El protocolo de distribución se trata de proporcionar robustez, no escalabilidad. Lo que quiere hacer es agrupar su clúster en áreas más pequeñas y luego usar conexiones, que no están distribuidas en Erlang sino en, por ejemplo, sesiones TCP. Podrías correr 5 grupos de 10 máquinas cada uno. Esto significa que las 10 máquinas tienen una distribución perfecta de Pid: puede llamar a un pid en otra máquina. Pero la distribución a otro grupo significa que no puede dirigirse al grupo sin problemas de esa manera.

Por lo general, se desea algún tipo de "reflexión de ruta" como en BGP.


Ya hay algunas respuestas buenas, así que estoy tratando de ser simple.

1) No, si A y E no están conectados directamente, A no puede hablar con E El protocolo de distribución se ejecuta en conexión TCP directa, sin enrutamiento incluido.

2) Creo que una estructura de árbol es lo suficientemente buena - siempre existen concesiones.

3) No hay un ''supervisor para nodos'', pero erlang:monitor_node es tu amigo.

4) si. Un nodo puede comunicarse con nodos de diferentes ''clusters''. En el nodo local, use erlang:set_cookie(OtherNode, OtherCookie) para acceder a un nodo remoto con una cookie diferente.