krisleech

krisleech

We are deploying an Elixir application to production for the first time (first ever Elixir app for me :tada:) and realised that we need to cluster the nodes because things like Quantum will run on every instance, with a cluster we can configure it to run on a single node.

We are using libcluster with the gossip strategy and it works locally.

We can start two iex sessions with different names and they form a cluster.

We can see the other nodes with Node.list().

However once deployed to AWS, whilst we can manually connect the nodes, they do not automatically connect.

In the logs we can see the gossip protocol heartbeat.

Given we can connect manually and we see the heartbeat are there other reasons this might be failing?

This is how we have things setup:

defmodule Shared.Application do
  use Application

  def start(_type, _args) do
    children =
      [
        {
          Cluster.Supervisor, 
          [
            cluster_topologies(), 
            [name: Shared.ClusterSupervisor]
          ]
        }
      ]

    opts = [strategy: :one_for_one, name: Shared.Supervisor]
    Supervisor.start_link(children, opts)
  end

  defp cluster_topologies do
    [
      gossip: [
        strategy: Cluster.Strategy.Gossip
      ]
    ]
  end
end

Any ideas much appreciated!

Showing Posts 1 to 10

Hermanverschooten

Hermanverschooten

I am doing something similar in dev, in production however I use a different strategy.
I have this in my runtime.exs:

  topology_hosts =
    System.get_env("PARTNERS") ||
      raise """
      environment variable PARTNERS is missing, no cluster will be active
      """
  config :gratwifi,
    topology: [
      ipc: [
        strategy: Cluster.Strategy.Epmd,
        config: [
          hosts: topology_hosts |> String.split(",") |> Enum.map(&String.to_atom/1)
        ]
      ]
    ]

And then in application.exs:

def start(_type, _args) do
    topologies = Application.get_env(:gratwifi, :topology)
...
children = 
  [
    ...
        {Cluster.Supervisor, [topologies, [name: GratWiFi.ClusterSupervisor]]},
    ...
  ]

The PARTNERS environment variable is set to a comma-separated list of all my nodes.

AND very important the access to the epmd port is restricted to these hosts on all my nodes.

LostKobrakai

LostKobrakai

The default for the gossip strategy is to use multicast, which is not necessarily supported by all networks as mentioned on later docs to what you linked: Cluster.Strategy.Gossip — libcluster v3.5.0

krisleech

krisleech OP

Thanks for the example, the reason for choosing the gossip strategy was that we didn’t want to statically maintain a list of node names. We are using AWS ECS and will be employing auto-scaling in the future. So new instances will be spun on on demand and need to connect to the cluster.

krisleech

krisleech OP

In the meantime I tried the libcluster_postgres strategy and this works both locally and on AWS.

It’s perhaps overkill given the cluster will not span multiple regions, so I’ll have a look at the suggestion from @LostKobrakai about multicast support and see if I can get gossip protocol to work.

krisleech

krisleech OP

Apparently AWS Fargate does not support UDP multicast or broadcast, I’ve not verified this for certain, but it certainly should explain why the Gossip protocol doesn’t work.

Hermanverschooten

Hermanverschooten

If al the nodes are resolvable through a single dns name, you could use DNSCluster.

albydarned

albydarned

Seeing the exact same with EC2 instances. Works locally, on AWS must be connected manually. Seems VPC just doesn’t support multicast. I only need a couple nodes right now, So I guess I could use Epmd for now. Would like this to just be automatic though. Postgres would probably work, but as you said seems like overkill.

What solution did you end up going with?

krisleech

krisleech OP

We are using libcluster_postgres.

The only thing I have noticed is that when we do a deploy (to ECS, Fargate) it spins up new nodes and they join the same cluster as the existing nodes (prior to them being terminated), so we get double sized cluster for a 10ish mins. We could change the cookie value to have two cluster’s during deployment, but we’ve not seen any issues with the current setup yet.

Also when the old nodes are said to be terminated in the AWS UI they actually aren’t for a few more minutes, you can still connect to them and see them as part of the cluster.

albydarned

albydarned

Interesting, thanks for sharing. Thats helpful to know how the cookies work. I’m running on EC2 machines. Using iex with --name and --cookie options, I can get each node to autoconnect using libcluster_postgres. Most reliable seems to be when i set --name equal to app@ However, making an elixir release seems like the --name is forcing itself to ip-. These then don’t autoconnect, even though I see the “connected to postgres” message from libcluster. I can always call Node.connect and it will work.

Did you run into anything simliar? I’ve even gotten to the point where using env.sh in the release directory to successfully get the ./app start_iex to show the correct app name with the IP. But, in release mode the same settings don’t autoconnect.

albydarned

albydarned

Just tried EPMD, and it works flawlessly with the local DNS names I set up inside of AWS. For some reason I just cannot get Gossip or Postgres to connect automatically when in release mode.

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
water
I’m aware of 2 such projects, are there others? git: GitHub - team-alembic/realworld: A fullstack Phoenix LiveView application with back...
New
itzmidinesh
Hi all, I’m working on a Phoenix project where I need to make external HTTP requests and I’m trying to choose between Req and HTTPoison....
New
peck
Hi everyone. My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
leoschweizer
Hi, we run different LLM models across a cluster, with each node loading a configurable subset. Model-specific queues let nodes consume ...
New
csmr
Hi all, I’m new here and would like to hear peoples views on my Elixir/Phoenix based game-engine! :smiley: Mutonex gamedesign was finish...
New
Stef-Verniers
Hello I’ve been coding in Elixir for almost two years now because of my current job where we implemented Elixir in our application. But ...
New

Other Trending Topics Top

dominicletz
Hey there, I haven’t seen a list of useful Elixir specific skills for the popular AI tools yet so I’m starting one here with my first. ...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
OndrejValenta
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly) AI dream has many faces, but general...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
kip
In 2021 I started a new library called Tempo with the objective of modelling time as a set of intervals - not as instants. In 2022 I gave...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews