low.sock

low.sock

Libcluster intermittent disconnects - what can I configure to create a more reliable cluster?

Hi,

I’m currently running a Elixir application which leverages Phoenix channels. I’ve clustered my application together using libcluster but my application gets intermittent warnings about node disconnects. This is an example of the message that I’m getting:

[warning] ‘global’ at node :“app name@ip” disconnected node :“app name@ip” in order to prevent overlapping partitions

I have also had users raise issues about de-sync, which would make me believe that this is an issue.

I’ve deployed my application on Fly.io and it seems that the nodes that are farther from every other node disconnect more often. For instance, most of my servers are in North America and Europe but my node in South America disconnects quite frequently, with my node in Australia being a close second. I’m running 20 nodes in total.

Basically what my question boils down to is what can I do about this? Is there a configuration that would allow node to wait longer for a response from other nodes? I know there Erlang flags but I wanted to ask here first if those would be a good idea and how could I go about adding these on a Dockerfile (which Fly uses to deploy the application).

Sorry for the long post and any advice would be much appreciated :slight_smile:

Edit: just fixed some formatting in the post

Most Liked

asabil

asabil

Yes, something like this should work:

config :kernel,
  net_ticktime: 120
LostKobrakai

LostKobrakai

If you’re talking about pubsub then forking is not needed. Pubsub already supports adapters to use different backends. E.g. there’s a redis based backend for heroku users.

hst337

hst337

It appears that nodes just lose connection from time to time

This is what global source code says about it:

%% ----------------------------------------------------------------
%% Prevent Overlapping Partitions Algorithm
%% ========================================
%%
%% 1. When a node lose connection to another node it sends a
%%    {lost_connection, LostConnNode, OtherNode} message to all
%%    other nodes that it knows of.
%% 2. When a lost_connection message is received the receiver
%%    first checks if it has seen this message before. If so, it
%%    just ignores it. If it has not seen it before, it sends the
%%    message to all nodes it knows of. This in order to ensure
%%    that all connected nodes will receive this message. It then
%%    sends a {remove_connection, LostConnRecvNode} message (where
%%    LostConnRecvNode is its own node name) to OtherNode and
%%    clear all information about OtherNode so OtherNode wont be
%%    part of ReceiverNode's cluster anymore. When this information
%%    has been cleared, no lost_connection will be triggered when
%%    a nodedown message for the connection to OtherNode is
%%    received.
%% 3. When a {remove_connection, LostConnRecvNode} message is
%%    received, the receiver node takes down the connection to
%%    LostConnRecvNode and clears its information about
%%    LostConnRecvNode so it is not part of its cluster anymore.
%%    Both nodes will receive a nodedown message due to the
%%    connection being closed, but none of them will send
%%    lost_connection messages since they have cleared information
%%    about the other node.
%%
%% This will take down more connections than the minimum amount
%% of connections to remove in order to form fully connected
%% partitions. For example, if the user takes down a connection
%% between two nodes, the rest of the nodes will disconnect from
%% both of these nodes instead of just one. This is due to:
%% * We do not want to partition a remaining network when a node
%%   has halted. When you receive a nodedown and/or lost_connection
%%   messages you don't know if the corresponding node has halted
%%   or if there are network issues.
%% * We need to decide which connection to take down as soon as
%%   we receive a lost_connection message in order to prevent
%%   inconsistencies entering global's state.
%% * All nodes need to make the same choices independent of
%%   each other.
%% 
%% ----------------------------------------------------------------

So, the real question is are you sure that the connection between nodes is not lost from time to time? If you’re sure, what tool do you use to check it?

chasers

chasers

Also very interested in the ideal global config.

We see a lot of packet loss between regions on Fly depending on the region and have managed to only get 4 regions (8 nodes) running somewhat reliably.

Had to build latency monitoring. See: Status - Supabase Realtime

It logs latencies to our logging infra too if they are over a threshold.

Note: the default PubSub adapter sends all messages to all nodes.

The Redis adapter would route everything through one box which would negate the whole global cluster idea.

aramallo

aramallo

I am @chasers ! :blush:

I think the way Partisan could help in this situation is exactly what @chasers suggests. However, this can only be accomplished when using the HyParView topology which maintains a partial mesh (eventually and probabilistically) forming a fully connected graph and uses transitive message transmission.

Using HyParView rules out the possibility of using partisan’s OTP behaviours at the moment (working on trying to solve this next, the key issue is how to implement monitoring).

Also notice that using Partisan rules out using Phoenix as it relies on disterl and OTP. For Phoenix to work we would need to fork it and teach it how to use Partisan and Partisan’s OTP behaviours.

I have plans to test Partisan itself and Bondy (which uses Partisan) in Fly.io for this very same reason.

Where Next?

Popular in Questions Top

Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New

Other popular topics Top

fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
326 29600 154
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New

We're in Beta

About us Mission Statement