惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cloudbric
Cloudbric
WordPress大学
WordPress大学
博客园 - 叶小钗
B
Blog RSS Feed
T
Tailwind CSS Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
美团技术团队
Scott Helme
Scott Helme
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Hugging Face - Blog
Hugging Face - Blog
T
Threat Research - Cisco Blogs
B
Blog
V
V2EX
Simon Willison's Weblog
Simon Willison's Weblog
I
Intezer
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threatpost
Cisco Talos Blog
Cisco Talos Blog
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
PCI Perspectives
PCI Perspectives
雷峰网
雷峰网
The Register - Security
The Register - Security
博客园 - 【当耐特】
Google DeepMind News
Google DeepMind News
N
News and Events Feed by Topic
H
Hackread – Cybersecurity News, Data Breaches, AI and More
U
Unit 42
Security Latest
Security Latest
NISL@THU
NISL@THU
腾讯CDC
S
SegmentFault 最新的问题
小众软件
小众软件
The GitHub Blog
The GitHub Blog
月光博客
月光博客
A
Arctic Wolf
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
Netflix TechBlog - Medium
IT之家
IT之家
D
DataBreaches.Net
C
CXSECURITY Database RSS Feed - CXSecurity.com
N
News | PayPal Newsroom
L
LINUX DO - 最新话题
博客园 - 司徒正美
大猫的无限游戏
大猫的无限游戏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
J
Java Code Geeks
TaoSecurity Blog
TaoSecurity Blog
P
Privacy International News Feed

jola.dev

How to stop Claude from saying load-bearing | jola.dev Let libraries be libraries | jola.dev CI workflows on Tangled for Elixir | jola.dev Automatically syncing your blog to atproto and standard.site | jola.dev Appreciation for the small web | jola.dev Treating LLMs as programming books Publishing your blog to standard.site in Elixir Generating OG images in Elixir The social contract of writing Highest Random Weight in Elixir bunnyx: a bunny.net Elixir client library Building for the joy of building Running local models on an M4 with 24GB memory How to hit your Claude weekly limit so you can go outside and touch grass Dropping Cloudflare for bunny.net Building a blog with Elixir and Phoenix Stay in the Loop: How I Actually Use Claude Code Ruthless Prioritization: The Path to Delivery Estimates Are More Valuable Than You Think When Software Engineers Think They Need More Focus Time If the Goal is Resiliency, Defensive Programming is Your Enemy The Magic of Daily Pull Requests: Why Smaller is Better Building a Distributed Rate Limiter in Elixir with HashRing Announcing Hex Diff Building Hex Diff Push-based GenStage The Erlang :queue module in Elixir Patterns for managing ETS tables Health checks for Plug and Phoenix The new `Registry.select/2` and what match specs are Elixir String Processing Optimization
Elixir Cluster 101 | jola.dev
https://jola.dev/about · 2026-07-21 · via jola.dev

One of the main super powers of Elixir (and other BEAM languages) is the built-in functionality for clustering nodes and communicating transparently across the cluster. Any distributed systems normally come with serious disclaimers. It’s very hard to get synchronized state across a cluster right, avoiding corrupted states during net splits or unreliable networks, dealing effectively with rolling deploys and mismatching versions of code.

But that shouldn’t discourage us. There’s a wide range of use cases for distributed Elixir, also known as disterl (and a bunch of other things, we really need a consistent name for this). You just need something that matches a few basic criteria:

  • It’s okay if some data is lost
  • It’s okay if some data is incorrect

As long as those criteria match, distributed Elixir, and distributed systems, are not actually that scary. Because it’s going to work most of the time, and for the use cases that match those criteria it’s frequently going to be a really good, low effort, and very performant option.

Where do you start

Before anything else, you need to ensure you’re starting your nodes in a cluster enabled configuration. If you’re using Phoenix and releases, this might just be a matter of editing env.sh.eex to add something like

export RELEASE_DISTRIBUTION=name

export RELEASE_NODE=app@$(hostname -i | awk '{print $1}')

and to ensure DNSCluster is configured.

or if you’re trying this out locally, start a few nodes with

# First terminal tab

iex --name first@127.0.0.1

# Second terminal tab

iex --name second@127.0.0.1

They’re started in distributed mode, but are still not connected. Let’s do that next. Go to the tab for one of the nodes, let’s say first.

iex(first@127.0.0.1)1> Node.list

[]

iex(first@127.0.0.1)2> Node.ping(:"second@127.0.0.1")

:pong

iex(first@127.0.0.1)3> Node.list

[:"second@127.0.0.1"]

iex(first@127.0.0.1)4> Node.self

:"first@127.0.0.1"

And we’re connected! Although really cool, it’s not really enough to just be connected, we want to be able to do something with it.

Tracking cluster state

Generally, building on top of the cluster functionality of Elixir starts with tracking the state of the cluster itself. This means keeping track of which nodes are members of the cluster, and when nodes join and leave. The latter is especially important for modern stacks that do rolling deploys, maybe many times a day, meaning constant churn of cluster membership.

The magic invocation that gives us access to the cluster membership transitions is :net_kernel.monitor_nodes(true). Call that function in a GenServer and you’ve subscribed to events for nodes joining and leaving. Let’s look at an example of a process that keeps track of the cluster state.

defmodule Cluster do

use GenServer

require Logger

def members(name \\ __MODULE__) do

GenServer.call(name, :members)

end

def start_link(opts) do

GenServer.start_link(__MODULE__, opts, name: __MODULE__)

end

@impl GenServer

def init(_opts) do

:net_kernel.monitor_nodes(true)

nodes = [Node.self() | Node.list()]

Logger.info("Cluster: #{Enum.join(nodes, ", ")}")

{:ok, nodes}

end

@impl GenServer

def handle_info({:nodeup, node}, nodes) do

Logger.info("Cluster: #{node} connected")

{:noreply, [node | nodes]}

end

def handle_info({:nodedown, node}, nodes) do

Logger.info("Cluster: #{node} disconnected")

{:noreply, List.delete(nodes, node)}

end

@impl GenServer

def handle_call(:members, _from, nodes) do

{:reply, nodes, nodes}

end

end

As nodes join and leave, we’ll see logs outputted. But more importantly, we can now get the current list of nodes in the cluster at any given point using the Cluster.members() function call. In a production setup, we’d also want to track the state of the cluster as metrics, maybe a nice gauge/last_value of connected nodes, or a counter for every change in membership. Unreliable networks can cause churn or net splits, where some nodes are connected but lack a connection with the other nodes. It’s important to track the reliability of the network, and alert on things like nodes failing to connect after a given amount of time.

What next?

What we have so far is the foundation of a lot of features you can build on top of distributed Elixir, but it wouldn’t be any fun if we stopped here. In the next blog post we'll take a look at a common use case: consistent rate limiting across multiple nodes. Keep an eye out of that!