Live data from Hacker News

Asynchronous Processing in Web Apps, Part 1: A Database Is Not a Queue

blog.gomiso.com

1–10 of 29 posts

Re: Asynchronous Processing in Web Apps, Part 1: A Database Is Not a Queue

#3

great post! this is what I wish I had as a starting point when I was learning how to get web apps to do work smarter rather than diving straight into celery documentation cause someone told me that would be the way to go!

Thanks! That's exactly why I am writing this series. I plan to take people slowly through everything about asynchronous processing, message queues, handling job processing, etc. Message queues are underused in modern web apps, and I think also not understood as well as they should be. Planning to include plenty of diagrams along the way to help with that.

Re: Asynchronous Processing in Web Apps, Part 1: A Database Is Not a Queue

#4
Nice clear introduction.

You can write a simple Async DB system without running into deadlocks. Deadlocks tend to occur when you have 2 processes trying to lock 2 different resources in differing orders. Not a case you'll run into here.

Also, you could do something like (correct me if I'm wrong, but I think it should be safe):

  update queue set owner = '1_time_use_rand_key' where owner is null order by id limit 1;
Not that I'm advocating this, you should definitely use a proper system to manage these types of tasks! :)

Re: Asynchronous Processing in Web Apps, Part 1: A Database Is Not a Queue

#5
I think the article is good, however, I feel compelled to weigh in from the countervailing general direction:

I am a message queue skeptic. Not that they should never be used, but rather a general feeling that complex, dedicated message queue software is often used for engineering problems between two or three orders of magnitudes too small before they deliver value. And, for most projects, queue replacement is not too difficult, especially if one's use of a database-backed queue is relatively naive.

As such, I will -- with an open mind -- suggest that general purpose database management software masquerading as queues is not an outright antipattern, and the times to use them in this way is probably more commonly seen than the opposite, where a dedicated queue delivers clear value.

Here are my main reasons for thinking that, which almost entirely have something to do with being able to address one's queue and one's other data in the same transaction:

* Performance: a pedantically unsound but basically reasonable rule of thumb (as experienced by me) would suggest that one needs to be processing somewhere between hundreds or thousands of messages per second with at least fifty (and maybe up to a hundred or two) parallel executors processing or emitting messages before there are performance issues where the lower constants of a dedicated queuing package become attractive. Below this kind of throughput, one starts to experience some more pain than gain.

* Correctness: Most database + queue integrations do a lousy job of what is effectively two-phase commit between different data storage instances (so that would include two+ RDBMSes, even if they are of the same kind, e.g. 2xPostgreSQL), and frequently the queue has to be counted among these (exception: when the queue contents can be lost/can be rebuilt/is idempotent at all times). Systems do a lousy job of making this work because it's pretty finicky to do a good job in many situations, i.e. expensive and time consuming.

* Constants, when dealing with other systems: When one does do a good job and has interesting requirements in the 'correctness' case, it often means doing forms of two-phase commit, whether explicitly supported by the system (e.g. PREPARE TRANSACTION) or a spiritual equivalent via carefully thought out state machines. In principle these could be relatively cheap, but typically to avoid complexity more expensive approaches are employed, such as a couple extra UPDATE requests to poke at some home-grown state machine.

Also, my experience indicates that as systems evolve, there will be inevitable bugs in these state machines that, by nature, span systems. Be vigilant and make sure you get more value than pain, and try to avoid having too many of them.

* HA is still hard: clustering is generally in principle possible, but make sure you read the fine print. For example, many people use Redis as a queue, but it is not really unlike any other monolithic database most generally -- its main draw as a vanilla queue is good execution-time constants. The same could be said of Apache ActiveMQ in its least byzantine configuration. One might think that one would get a lot of leverage 'for free' given the simpler semantics of queues vs the diversity of access methods in most general purpose databases, but so far I have not seen that to be the case, for the very good reason that a lot of people expect a lot of reliability out of their queues (no less than the transactional nature of some databases), and doing that is either most natural in a monolithic system or slow, or complicated, or both in a multi-master distributed system.

All in all, if you think you need dedicated queuing software to send a few dozen emails a second (that's a lot of email for most people!), think twice: it might still be a good idea, but brace yourself for these pitfalls or convince yourself that they probably mostly don't apply to you.

Re: Asynchronous Processing in Web Apps, Part 1: A Database Is Not a Queue

#6
post #5

I think the article is good, however, I feel compelled to weigh in from the countervailing general direction: I am a message queue skeptic. Not that they should never be used, but rather a general feeling that complex, dedicated message queue software is often used for engineering problems between two or three orders of magnitudes too small before they deliver value. And, for most projects, queue replacement is not t…

Thanks for your feedback, I appreciate the thoughtful response. I actually agree that generalized message queues can often be complex and perhaps even unnecessary when dealing with asynchronous processing at a small scale depending on your needs.

I think the important thing is to understand your requirements, the volume of jobs, etc. In my series, I also plan to introduce much simpler lighter work queues that are a perfect medium between a 'heavy duty' generalized message queue and trying to wedge a queue into a database.

But as with everything, people should evaluate the available options for themselves. My goal is just to provide people with a framework for understanding the tradeoffs.

Re: Asynchronous Processing in Web Apps, Part 1: A Database Is Not a Queue

#7
Nice article. One thing you should talk about in my opinion are systems like Redis. Redis can be used as a generalized key value store, but it can also be used as a messaging platform. In fact many systems like Storm (which would be another great topic) have easy integration with redis pub subs. While Redis and other solutions like it probably are not a good fit for all your data, they are great for mixed supporting data, caching and messaging. There are also really nice integrations if you like Java, these days you can make Spring message driven beans to consume messages from a redis pub sub very easily with minimal configuration. ZeroMQ is probably another technology that is worth discussing, either using it with a layer like Storm on top or by itself. Not every messaging system has to be heavyweight and cumbersome like the good ole' days.

Re: Asynchronous Processing in Web Apps, Part 1: A Database Is Not a Queue

#8
I dunno. I've seen companies go through 4 or 5 different message queue systems and find that none of them work quite right.

12 years or so ago I developed a few systems that used qmail as a message queue and I was pretty happy with that.

Asynchronous processing is a necessary evil, but I think a lot of people underestimate the difficulty. It's one thing to compress a video in the background, but if you have one asynchronous task that spawns a bunch of asynchronous tasks and they spawn asychronous tasks and someday they all come together... Well maybe they come together someday. There's a definite "complexity barrier" you hit when asynchronous applications rapidly become harder to maintain.

There are ways around this, but I've frequently seen MQ-based systems that never get "done".

Re: Asynchronous Processing in Web Apps, Part 1: A Database Is Not a Queue

#9
With a traditional database this typically means a service that is constantly querying for new processing tasks or messages.

Traditionally, but not necessarily; PostgreSQL supports the LISTEN and NOTIFY commands for asynchronous notifications, without polling.

Re: Asynchronous Processing in Web Apps, Part 1: A Database Is Not a Queue

#10

I dunno. I've seen companies go through 4 or 5 different message queue systems and find that none of them work quite right. 12 years or so ago I developed a few systems that used qmail as a message queue and I was pretty happy with that. Asynchronous processing is a necessary evil, but I think a lot of people underestimate the difficulty. It's one thing to compress a video in the background, but if you have one async…

I believe this is the problem that Storm was supposed to solve ( https://github.com/nathanmarz/storm ). Or Amazon's SWF ( http://aws.amazon.com/swf/ ). They work in the case where you can define the flow between all of the tasks.
Post reply on HN