Hacker News new | past | comments | ask | show | jobs | submit login

After reading Enterprise Integration Patterns [1] a few years ago, I've been under the impression that message queues are the holy grail for decoupling systems that you want to pull apart, but this offers a really nice perspective on where they might not be a panacea. Thank you!

There's a couple of nice ideas in here (the "message pump" for one at least) that I'm going to steal and use at work. It's also comforting to know that we're not completely crazy for using a DB to store tasks/processes that need to be run and retried if necessary instead of a message queue.

[1] https://en.wikipedia.org/wiki/Enterprise_Integration_Pattern...




I know what you meant by saying you use DB _instead_ of message queue but I think it kind of points to a broader point - message queue is a concept and the technology used to implement it is just implementation detail. It just turns out that databases have all kinds of useful and powerful operations that make implementing message queues relatively easy.


If you don't need high throughput and otherwise don't have a reason to add a separate technology to the stack just to have a queue, SQL can make a great, simple and reliable queue!

* Postgresql and Oracle with skip locked

* MS SQL Server with readpast

* DB2 with skip locked data

If you use MySQL, it's going to be a bit more difficult.


I hadn't heard of skip locked before, and very much enjoyed this article walking through it for postgres: https://blog.2ndquadrant.com/what-is-select-skip-locked-for-...


Love the headline "Most work queue implementations in SQL are wrong". That kind of stuff makes me read an article...

This short screencast was also very helpful https://www.pgcasts.com/episodes/7/skip-locked/


Using the database as a queue is an anti-pattern. There used to be an entire blog series about why this is the case. However, I can't find it at the moment.


With MySQL, there's a fairly simple trick you can do to build a queue. Set a temp var to null, run an update with a select subquery to update state of next row(s), then select that var to get your queue row pk's.


Having been on the receiving end of more than a few apps where the devs used a database as a queue, I say "please don't".

Yes, Oracle's AQ product is built on top of an RDBMS. And yes, early versions of Microsoft's MSMQ used SQL Server. But most dev teams use the database as a shortcut and don't invest the effort in making their hacktastic DB queue work like a real product.


I have used DB as queues very successfully in multiple projects (as well as "real" queues in others), so your "please don't" is not very persuasive. Some actual argument, instead of content-free "hacktastic" vs. "real product" designations would be appreciated.

And you use "shortcut" like some kind of negative attribute. Of course they use DB as a shortcut, and they should - it works well and even has additional features (transactions with your primary store) that you wouldn't get with separate queue product.


Monitoring and administration are more difficult until you write them yourself, especially if you are splitting monolithic code. Many of the message queue products you download include these. Can your DB message queue also support different queue concepts and message routing?


In my case it supported multiple queues (also, a concept of hierarchical queues), but no message routing. As for administration and monitoring - you are correct, you don't get it out of the box. Well, you do get some basic administration for free from whoever administers your database :)

On the other hand, you can grow solution for those organically over time to fit your needs.


In a previous life I was on a team that moved a ecomm backend-Email Service Provider(ESP) from a postgres based queue to rabbitMQ. The motivation was voiced in language similar to yours, "hacktasic" was actually used more than once as a reason to replace the DB with rabbitMQ.

In the end, I'd say they were equally reliable, but from a data analyst's perspective I very much missed the postgres based queue. I think the mechanics inherent to a database solution prompted the original implementers to keep messages around over time vs the mechanics inherent to an MQ solution where they became ephemeral (on the senders side.) Having access to those messages was a treasure trove for troubleshooting and for analytics. That and from a pure cost benefit stance, sending 10-20k messages a day to the ESP definitely didn't necessitate the expensive rearchitecture, as the DB solution was more than capable of handling the load on cheap hardware.


Yeah, at 10-20k it definitely sounds like overkill. Some of our past systems sent a couple million emails per day using a MySQL backed email queue.


The reason to use message queues rather than RDBMS for queue behaviors isn't because queues do stuff databases don't, but rather because of connection cost. There's a lot of complicated handling noise around the database connection, whereas queues tend to be very inexpensive.


As an alternate anecdote, I have had far more issues with MQ connections than with RDBMS connections. I don't think there is a clear advantage to messaging from that standpoint.


Do you mean development/complexity cost or performance cost? If it is the former, then I don't really see it. If it is the latter then yes - RDBMS backed queue is probably going to hit scaling limits earlier then dedicated product.


> message queues are the holy grail for decoupling systems

I also like the idea, but the counterpoint is: "now you have to monitor the queue".

(I only work in small apps for my own use so its more like Postgres and forget...)


you mean now you CAN monitor the queue... it's been very helpful for us to just throw alerts on queue size in AWS Simple Queue Service.. but we have some apps keeping state in Mongo and you have to write a custom script each time to query and send data to Cloudwatch


Using message queues to decouple the components suffer the same problem as micro services. You start to get a lot of implicit dependencies that you must document.


Beyond that, you tend to often realize you haven't quite made the logical split of components in quite the right place, or the "right place" for that split to be changes over time. Then you've got the fun task of moving functionality from one component to another, which is extremely expensive in development time.

(or, more often than not, because of the cost of doing this, you end up putting up with a slightly batshit-insane design...)


What kind of implicit dependencies?


Service A sends a message to Service B, so Service A is dependent on Service B to function properly.

With careful management, it can be kept to a minimum, but I haven't seen that work for systems with a large numbers of developers working on it yet.


Or in my experience, Service A sends a message to Service B, which sends a message to Service C, which sends a message to Services D, E, and F, and Service F sends another message to Service C, which this time it sends a message to Service G (so at least it's not completely circular), which then hits the database and returns information back up the chain.

I'm exaggerating a little bit, but not too much (actually, on further reflection, I might actually be downplaying it a bit. some of our services schedule tasks with like 10 different services for every item processed, and we do tens of thousands a day).

Debugging issues in this mess is not fun, because there's so many places you need to check to see if it's the source of the failure or not, and a failure in one service could really be in a different service so you have to test all the way up and down the chain. For every bug.


That's a problem of badly specified services. You should be able to look at the messages only, and see where a bug starts.

But then, I'm mostly against microservices because they lead to harder problems on every place. Documentation isn't even the worst.


But I was under the impression that the point of message brokering is that it doesn't have to be service A that puts it there; only that some service puts the message there.

I feel like the article is attacking message brokering by discussing the disadvantages of bad use cases for them. A good use case for message brokers is when work needs to be done on an item, but not immediately.

My company uses them in a way I believe is quite effective. We pull in data from an external source, and send the ID of the item to about five different queues to do different tasks. Each time one of the queues finishes the work, it send a message to a validator that checks to see if all the work is done. If it isn't, it waits to get that message again from another worker. If it is, it marks that item as ready for the end user.

These are the kinds of use cases I think message brokers should be used for. Not to send a message and wait to get an answer back. Why not just use an HTTP request for that?


> But I was under the impression that the point of message brokering is that it doesn't have to be service A that puts it there; only that some service puts the message there.

It doesn't matter, but it's more about debugging. If Service A does not work correctly, where is the bug? Is i Service A? Service B? The network?

The use at your company, is idiomatic to the paradigm. You have n different units of work, that can run seperately, so you do that and communicate with messages.


If you are using messages correctly, it shouldn't be difficult to debug. You have an input and output for each service and you see where something happens differently than expected. I'm not sure where you are saying the difficulty comes from.


That matches my experience — I've seen a fairly common learning process where someone adopts a message queue, decides it's great and uses it all over the place, and then spends awhile working through the various failures which didn't happen in their development/testing environment so they're making decisions about how to handle dropped messages, duplicates, etc. in a rush.

It's not that hard to do but it seems to take people by surprise and it's not helped by some poor defaults like almost everything in the RabbitMQ ecosystem silently blocking when the queue fills up (this probably happened transiently multiple times before it hit the level where it caused a visible outage but how many people will notice that if the default isn't to log or raise an error?).




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: