Pistrie

Pistrie

How would you scale up an Elixir/Phoenix application if only a specific part is responsible for that requirement?

Hi everyone, I’ve got a question related to project architecture.

In the microservice sphere there is this concept where you can scale up individual services when needed. So imagine the following scenario:

     ┌────────────────────┐
     │RabbitMQ Message Bus│
     └────────────────────┘
       ▲            ▲
       │            │
 ┌─────┴───┐    ┌───┴──────────┐
 │Webserver│    │Expensive jobs│
 └─────────┘    └──────────────┘

The precise job doesn’t really matter, but let’s assume that we’re processing and/or modifying images or something.
The ‘expensive jobs’ box retrieves jobs from RabbitMQ and returns the result.
Let’s say that the expensive jobs get popular with our users, so we want to add another box that retrieves jobs from RabbitMQ.

     ┌────────────────────┐
     │RabbitMQ Message Bus│
     └────────────────────┘
       ▲            ▲   ▲
       │            │   └──────────┐
       │            │              │
 ┌─────┴───┐    ┌───┴──────────┐ ┌─┴────────────┐
 │Webserver│    │Expensive jobs│ │Expensive jobs│
 └─────────┘    └──────────────┘ └──────────────┘

We’ve now effectively doubled our capacity for handling these expensive jobs.

My question is as follows: how would you achieve something similar in an Elixir (Phoenix) monolith? We can use Oban to perform background jobs, but what if the amount of jobs becomes sufficiently large that the queue reaches its limit. We could theoretically scale up the entire server, but that doesn’t feel correct for some reason.

Most Liked

LostKobrakai

LostKobrakai

I’d argue at that scale the difference between a monolith and microservices becomes muddy. Because the remaining difference will just be “code organization” when you start to scale out a system (especially heterogenously).

Afaik both Oban Pro as well as the recently introduced FLAME library/pattern can help with adding more nodes (horizonal scaling) over adding more power to the current one.

dimitarvp

dimitarvp

The BEAM VM has work-stealing schedulers (among other goodies) so bumping up a single server’s specs will naturally lead to increase of capacity in processing the expensive jobs, because they’re the ones demanding more resources, and the runtime will give it to them.

Delay scaling out as if your life depends on it. New and extremely annoying problems await you there.

tj0

tj0

You could deploy a monolith 100 times and set aside 90 of those for jobs if you wanted. Don’t be bothered with whether there is one service deployed and running or many on a container / vm. There is a time for that, but not worth it early. Colocating services / data also is important if latency is there when scaling.

Scaling up is much easier than scaling out. Agreed with everyone else in the thread so far. You don’t want to be paying for giant machines to be idle 99% of the time though.

My preference would be deploy the monolith n-times and separate the usage / clustering. FLAME looks interesting also, but never tried it.

Last Post!

Pistrie

Pistrie

:+1: Fair enough, and the BEAM has the advantage of scaling horizontally rather easily (compared to other solutions anyway) should you reach the limit of upwards scaling

Where Next?

Popular in Questions Top

minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
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
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

Other popular topics Top

minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31494 112
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 40042 209
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
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

We're in Beta

About us Mission Statement