I’m working to increase my understanding of how to build distributed systems as a way to leverage concurrency. I understand this is a broad topic, but I’m wondering if anyone has some examples of how to structure “work” across multiple nodes or multiple apps.
I admit I am not even sure I follow how things happen when you deploy a single app across multiple nodes (e.g. 1 app deployed to 2 EC2 instances)… that means there are 2 instances of the Erlang VM running. How is work delegated? E.g. if it’s a Phoenix app, does a multiple-server deployment assume that a load balancer is figuring out the “division of labor” and routing requests to different nodes? And does this assume that each node more or less has no awareness of the other nodes?
Or how about when you want to process a stream of inputs (e.g. using Task.async_stream/3)… do you have any way of routing the processing to different nodes? For this to work, wouldn’t each node need to know about the other nodes? Locally, this happens by specifying --sname and --remsh options when starting the app, e.g. something like
You would thus have a set of nodes that the other nodes can know are is responsible for doing particular jobs.
You would also have processes that serve particular purposes registered at initialisation, they would have their own PIDs that would include the host addresses identifiable by remote nodes anyway, so you could forward requests to those processes even though they are on remote nodes using very similar messaging sending procedures.
You could forward requests to a request resolving process that would identify which process is in charge of what service, or even request the spawn of a process by a pool manager in order to service a given request.
You would want to use calls to do this, to receive confirmation that the request was successfully served. Here is the documentation for remote procedure calls.
This probably isn’t a whole lot of info, just pointing you in the right direction, I’d definitely consider giving chapters 10 - 12 from Elixir in Action a read.
Hey, have you checked the “Introduction to Mix” guide in the official documentation?
Although the name can be a bit misleading, this is the description of the guide:
In this guide, we will build a complete Elixir application, with its own supervision tree, configuration, tests, and more.
The application works as a distributed key-value store. We are going to organize key-value pairs into buckets and distribute those buckets across multiple nodes. We will also build a simple client that allows us to connect to any of those nodes and send requests
I think it might be helpful, it covers how nodes connect to each other using the configurations and shows some example of running code in a remote node and distributing work across nodes via sharding.
Overall the erlang runtime does no magic to help you and you still need to build your own mechanisms of distribution and load balancing in your application, but it provides all the building blocks you’ll need to do so.