Live data from Hacker News

Disque – a distributed message broker

github.com

31–40 of 96 posts

Re: Disque – a distributed message broker

#32

Tbh, I'd have preferred a synchronous replication option for Redis nodes. That seems to be essentially the "improvement" in Disque and it'd be easier to maintain two replication nodes than two separate projects imo.

Hello, Redis + sync repl is a valid point of view IMHO, there are reasons why this was discarded, but it is definitely an option. However Redis + sync replication does not give you Disque at all. Disque is a specialized distributed system hard to simulate with Redis, nodes runs protocols in order to coordinate re-queueing the message, in order to federate to route messages, and so forth.

Re: Disque – a distributed message broker

#33
post #18

Can somebody help me better understand the possible uses for something like this?

Personally, I look forward to using this instead of Redis and RabbitMQ as the message broker for Celery. Celery is a background tasks framework for Python. You write code that defines tasks, then certain things trigger tasks. Classic example: user uploads a video, then in the background the video is re-encoded in some standard format. So after the upload is done, the web application triggers a task by sending a message to the message broker (RabbitMQ, Redis, or now Disque).

Why not just use RabbitMQ or Redis? Well, RabbitMQ is, in my experience, complex and fragile. It's got a ton of different features, which means you have to configure it to do anything beyond just the basics, and its management tools are somewhat lacking (why rabbitmqctl and rabbitmqadmin?). I recently started switching to Redis, because Redis is pretty much plug and play. It just works, and even minimal configuration that is necessary for this use case is very clear and simple. Moreover, it's got a very simple API for examining what's going on, no complex permissions management, vhosts, etc. It's only downside? It's not a message broker; it just has some of the right primitives to act like one.

This is not to say that RabbitMQ or Redis are bad. They are great for what they do. I simply don't want to use them as the backend for Celery for the reasons stated above.

Re: Disque – a distributed message broker

#35
post #18

Can somebody help me better understand the possible uses for something like this?

Personally, I look forward to using this instead of Redis and RabbitMQ as the message broker for Celery. Celery is a background tasks framework for Python. You write code that defines tasks, then certain things trigger tasks. Classic example: user uploads a video, then in the background the video is re-encoded in some standard format. So after the upload is done, the web application triggers a task by sending a messa…

"it's got a very simple API for examining what's going on"

which api are you referring to specifically?

Re: Disque – a distributed message broker

#36
post #18

Can somebody help me better understand the possible uses for something like this?

Message queues are "email for applications". They allow you to break up your application into components that talk to each other across processes, machines and time. For example if you need to print and send a letter to your customer, you can have the web frontend send a message to the printer task. Those messages can be queued up (in case the printer is down), and handled slowly or quickly by the printer. If you have two printers you can have them both pulling jobs off the same queue. Good message queues can offer reliability guarantees like at most once delivery, and persistence (saving message queues to disk in case machines go down). Also primitives like pub/sub where applications subscribe to data (think: stock feeds), and other applications publish that data.

Re: Disque – a distributed message broker

#37
post #26

Any functional advantage to using this instead of something like rabbitmq?

As a RabbitMQ user, I'll switch to the first viable alternative that is production ready.

RabbitMQ's clustering isn't great. It's sensitive to partitions, which can occur not just from actual network hiccups but also simply due to high CPU or I/O load, and it does not have a good strategy to recover from such partitions.

RabbitMQ is not multi-master by default. A queue is owned by a specific node, and if you have a partitioned cluster, that queue (and related objects such as exchanges and bindings) will disappear from other nodes.

You can patch RabbitMQ's clustering by enabling "high availability", which is their term for mirrored queues. Each queue will get a designated master, and be replicated to other nodes automatically. If a partition happens, the nodes elect a node to become a new master for a mirrored queue.

Unfortunately, this opens the cluster up to conflicts. Let's say you get brief partition. Now all the nodes see each other again, and you have conflicting queues: Node A used to be master of queue X, now node B is also master of queue X. During the split, their contents diverged a little bit. But RabbitMQ has no way to consolidate the two masters, so the queue is not operational.

To fix this, either you need to reconstruct the queue manually (usually impossible from an application's point of view), or wipe it (hardly a solution) or simply have RabbitMQ automatically pick a winning master and discard the other master(s). This mode is called "autoheal", and picks based on which master has the most messages; the previous master(s) are wiped and become slaves. This is coincidentally the only mode in which RabbitMQ can continue to run after a partition without manual intervention.

In practice, recovery has proved flaky for us. Nodes stay partitioned even after they should be able to see each other. We have also encountered a lot of bugs — for example, bindings or exchanges disappear on some nodes but not on others, or queues are inexplicably lost, or nodes otherwise just misbehave. We're on a cloud provider which is otherwise rock solid; of all the software (databases etc.) we employ in our clusters, RabbitMQ is the only one that misbehaves.

This is anecdotal, of course. Fortunately, the author of Jepsen, Kyle Kingsbury/"Aphyr", has done the maths to back this up, demonstrating that RabbitMQ's clustering is both theoretically and practically unsound [1].

This may be overly harsh. RabbitMQ is a decent project. RabbitMQ has a lot of features. Things like routing keys, flexible durability, TTLs and dead letter exchanges are great [†]. When it works, it works really well. But in the real world, I wouldn't want to run it more than two nodes, and preferably not at all.

[1] https://aphyr.com/posts/315-call-me-maybe-rabbitmq

[†] Although unfortunately DLXes are effectively unusable in a looping topology configuration (ie., for timed retries), as AMQP frames will increase indefinitely in size.

Re: Disque – a distributed message broker

#38

And there's a Ruby client for it already: https://rubygems.org/gems/disque

Would love to see multi-threaded workers. That's one of the pros of using sidekiq + redis today (it uses celluloid under the hood).

I'd be interested in what it might take to swap out the redis code for disque in Sidekiq.

Re: Disque – a distributed message broker

#39
post #32

Tbh, I'd have preferred a synchronous replication option for Redis nodes. That seems to be essentially the "improvement" in Disque and it'd be easier to maintain two replication nodes than two separate projects imo.

Hello, Redis + sync repl is a valid point of view IMHO, there are reasons why this was discarded, but it is definitely an option. However Redis + sync replication does not give you Disque at all. Disque is a specialized distributed system hard to simulate with Redis, nodes runs protocols in order to coordinate re-queueing the message, in order to federate to route messages, and so forth.

Fair enough. :)

I am basically using something I could fit in Redis + sync replication [in terms of data model / function] as a job queue presently so I suppose that is just where my mind jumps to.

Re: Disque – a distributed message broker

#40
post #22
post #18

Can somebody help me better understand the possible uses for something like this?

Let's say you have a web app that sends emails, and you have many worker processes actually sending emails. If you use something like Disque, instead of sending the email directly from the web app, you send a message to Disque, into the send_email queue: "Please send an email to foo@example.com". Workers sending emails will fetch from the send_email queue, and will get the message. Workers sending emails are supposed…

Other examples:

- Queueing media files to be encoded/transcoded.

- Trigger a build of your application from a web interface.

Basically anything that you want to do where you might not want the web server to block until the entire task is done.

Post reply on HN