2

Suppose I have a message broker that allows consumers to specify a batch size. What are the advantages and disadvantages of consuming events in batches compared to consume them one by one?

The obvious advantage I could think of is increased speed. As a drawback, higher delay, which will be more noticeable the lower the speed at which events get published.

2

2 Answers 2

2

A batch interface usually means that the code is designed or optimized to process the records all at once instead of one by one at a time. Many systems have optimized methods for loading or processing batches of data. This means you get faster throughput as opposed to individual processing. Usually batch processing is done at certain intervals and is less real time in nature.

The system is less chatty because data is coming in bigger chunks.

Downsides are if one record fails, the entire batch is failed unless there is a failure/recovery mechanism in place that removes the troublesome data and re-runs the batch automatically. This can become complex.

Also, true batch processing should give you a bump in throughput. If there is a batch but actual processing is one at a time, then the batch interface is not really needed. The only benefit in that case is less back and forth communication.

1

As has been stated, the advantage of batch processing is performance, or perhaps more accurately can be performance.

Specifically, most RDBMS systems are much, much faster at writing lots at a time rather than what DB people know as RBAR ("row by agonizing row" processing). If you expect many records to be arriving rapidly, there can be multiple-orders-of-magnitude difference in the ingestion speed. I wrote an article on this several years ago, which you can find here https://www.sqlservercentral.com/blogs/soa-and-message-based-integration-the-challenge-of-bulk-data-changes

The tl:dr version is that in my demo a 20,000 row write to SQL Server took 228 times longer to complete if you write the rows one at a time than it did writing them all at once as a set.

Writing to in-memory, non-locking relational, like SQL Server in-memory (aka Hekaton), or to key-value stores, typically does not suffer as much from this.

As mentioned by Jon Raynor, the downside to batching is error handling. In the best case it typically means reprocessing a whole batch, which is obviously more costly than reprocessing a single message. In the worst case, where messages have an inherent order that must be preserved and subsequent messages can modify the same state as prior messages in non-idempotent ways, this can imply a very expensive - and perhaps logically complicated - rollback operation. Transactional systems which provide built in rollback capabilities (ACID databases) of course remove the complication of rollback, but not the IO cost.

Note that batched processing does not necessarily mean higher latency in achieving consistency between your systems. Batching does not imply waiting for a buffer to fill up to a certain size before processing the incoming messages. Indeed, this is not a logically sound approach, since there is no way to know whether or not more messages will be arriving "any time soon", so you never know when to process the batch if you try to do it this way. Rather, batched processing simply means taking the messages available in your pipeline right now - however many there may be - and processing all of them at once.

The logical implication of this is that if your message consumption rate at the subscriber(s) is able to keep up with your peak message generation rate during burst times, the batch size is never greater than one. Therefore you pay for the additional cost of batch processing logic, but for no good reason.

If you want a simple set of rules for deciding which way to go, I propose the following: If you are writing to an ACID relational database, and if you ever get spikes in message generation rates (eg, large transactions on publisher systems updating thousands or tens of thousands of rows in a single transaction), then go with batched writes at the subscriber side. The performance cost of not doing so can be crippling. For example, an end-of-month process where I work takes 15 minutes to complete at the publisher side, but 8 - 12 hours to write to the CRM system via one-at-a-time web api calls, because it does not support batched writes.

On the other hand, if you don't have large amounts of messages being generated rapidly by publishers (whether consistently, or in bursts), then stick with one-at-a-time processing. It's easier to code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.