Distributed Erlang
Pids, links, and monitors work transparently across nodes.
33.1 Starting nodes
erl -sname alice -setcookie secret
erl -sname bob -setcookie secret
# fully qualified: erl -name [email protected] -setcookie secret(bob@host)1> net_adm:ping('alice@host').
pong
(bob@host)2> nodes().
['alice@host']
(bob@host)3> node().
'bob@host'33.2 Remote operations
Pids, links, and monitors work transparently across nodes.
spawn('alice@host', fun() -> io:format("on ~p~n", [node()]) end),
{registered_name, 'alice@host'} ! Msg,
rpc:call('alice@host', erlang, system_info, [process_count]),
erpc:call('alice@host', lists, sum, [[1, 2, 3]]), % OTP 23+, preferred
erpc:multicall(nodes(), erlang, memory, [total]),
rpc:multicall(nodes(), M, F, A),
monitor_node('alice@host', true), % {nodedown, Node}
net_kernel:monitor_nodes(true),
erlang:disconnect_node('alice@host').33.3 Security & infrastructure
Cookie: shared secret for authentication (~/.erlang.cookie, erlang:set_cookie/2). Not encryption!
EPMD: port mapper daemon on TCP 4369; nodes listen on dynamic ports (restrict with inet_dist_listen_min/max).
TLS distribution: -proto_dist inet_tls with certificates for untrusted networks.
Hidden nodes (-hidden) don't join the full mesh.
Default topology is a fully connected mesh → practical limits around 50–200 nodes; beyond that use Partisan or hierarchical designs.
33.4 Global names & process groups
global:register_name(leader, self()),
global:whereis_name(leader),
global:send(leader, Msg),
gen_server:call({global, leader}, ping),
pg:start_link(), % pg (OTP 23+) replaced pg2
pg:join(workers, self()),
pg:get_members(workers),
pg:monitor(workers). % OTP 25+33.5 Handling netsplits
Distributed systems must handle partitions: use monitors (nodedown), idempotent operations, CRDTs, or consensus libraries (ra — Raft, used by RabbitMQ quorum queues; riak_core for consistent hashing / dynamo-style systems).