artem

artem

What is the Elixir/OTP way for long queues that in JVM world would live on RabbitMQ or Kafka?

Hi All

I am still learning Elixir in semi-hobby mode, so sorry if the question is stupid. Imagine an API that processes survey responses, possibly in computationally expensive way (maybe fashionable AI is being trained from them or something like this). When survey gets published to some popular facebook group or twitter nearly simultaneous submissions can easily overload a small server.

I come from JVM world and one of the usual ways there for surviving against connection overload is whenever possible to accept a request, put it to the queuing service such as RabbitMQ and then slowly (e.g. in 1-3 threads) pull them to process. Or if we are in a less serious service, then maybe a homemade queue in just the heap memory and/or persisted to database.

My understanding is that Elixir/OTP are so great regarding number of connections, that it is not really a concern. However, processing tons of feedback still needs CPU, RAM (especially is machine learning is involved), saving to database, etc.

What is the Elixir way for handling such situations?

  • Do we just post messages from every API call and some genserver slowly processes then one by one?
  • Do you use database persistence in such situation somehow (it wouldn’t be nice to drop queued survey results if service dies)? With some standard libraries?

P.S.
I realize that you can perfectly use RabbitMQ or Kafka from Elixir as well. Still certainly if I can have just one elixir box to do it for a small business SaaS, then it would be great not to add more nodes to the system.

Most Liked

cjbottaro

cjbottaro

For persistent queues, I’m becoming a big fan of NATS Jetstream. It has nothing to do with Elixir btw. Before that, I was using Faktory a lot (which is based on Redis).

Jetstream is distributed and highly available. You can create both queues and streams.

The protocol to talk to Jetstream is extremely simple. Most Jetstream concepts are simple, but the feature set is huge, despite its simplicity.

Jetstream also comes with an amazingly robust pub/sub system.

Jetstream is much more simple than Kafka, but the feature set is greater.

lucaong

lucaong

Hi @artem ,
I am mostly just repeating things that were already mentioned by other people in this thread, but I hope to offer some points on which to decide what to choose based on your specific needs.

As you mentioned, you can definitely use Kafka and/or RabbitMQ from Elixir. RabbitMQ is actually written in Erlang, and runs on the same VM as Elixir. That said, it very much depends on whether you only need scalable and concurrent execution of tasks, or if you need to persist your jobs on disk to recover from a restart of a worker instance without loosing messages.

If you do not need to persist tasks on disk, Elixir/OTP has already very good facilities for managing concurrent tasks, and to scale to a large number of concurrent requests, without reaching outside of the language ecosystem. That’s because OTP relies on exchanging messages asynchronously across lightweight processes. This is really one of the use cases that Erlang is built for. One thing to be aware is that GenServer will not automatically provide a back pressure mechanism: it’s possible to do that, but does not come by default. There are some libraries, such as the already mentioned gen_stage, that facilitate the implementation of pipelines to process tasks in parallel, with back pressure, throttling, and more.

If you instead want to persist those jobs to disk, to recover from a restart without loosing them, I’d consider something like RabbitMQ (with durable queues enabled) or like Oban (based on Postgres), depending on your specific needs.

derpycoder

derpycoder

I have the following book in my backlog, and a general idea of how things can be done in Elixir:


I would tackle it by using GenStage. It has concept of Producer and Consumers, which helps with consumption of data in batched fashion. If the machine learning Consumer gets overwhelmed, it can ask for less work from Producer.. (i.e. Backpressure)

If requirements get more complicated, then we can go for Broadway.

For persistence across restarts, I guess Oban will do the trick.

Last Post!

yolo007wizard

yolo007wizard

NATS looks cool, just did a quick read up on it. Wonder how hard it would be to get db persistance.

Where Next?

Popular in Questions Top

JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
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
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 130286 1222
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36654 110
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
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
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement