I am going through Asynchronous logging in different loggers. I happened to see log4j2's async logger in detail. It is using LMAX Disruptor internally to store events. Why are they using LMAX Disruptor instead of any built-in non-blocking data structure of java?
Async Loggers, based on the LMAX Disruptor, were introduced in Log4j 2.0-beta-5 in April 2013. Log4j2 at the time required Java 6. The only built-in non-blocking datastructure that I am aware of in Java 6 is ConcurrentLinkedQueue
.
Why the Disruptor? Reading the LMAX Disruptor white paper, I learned that queues are generally not optimal data structure for high-performance inter-thread communication, because there is always contention on the head or the tail of the queue.
LMAX created a better design, and found in their performance tests that the LMAX Disruptor vastly outperformed ArrayBlockingQueue
. They did not test ConcurrentLinkedQueue
because it is unbounded and would blow up the producer (out of memory error) in scenarios where there is a slow consumer (which is quite common).
I don't have data from my own tests at the time, but I remember that ConcurrentLinkedQueue
was better than ArrayBlockingQueue
, something like 2x higher throughput (my memory of the exact numbers is vague). So LMAX Disruptor was still significantly faster, and there was much less variance around the results. ConcurrentLinkedQueue
sometimes had worse results than ArrayBlockingQueue
, quite strange.
LMAX Disruptor performance was stable, much faster than other components, and it was bounded, so we would not run out of memory if an application would use a slow consumer like logging to a database or the console.
As the Async Loggers performance page, and the overall Log4j2 performance page shows, the use of LMAX Disruptor put Log4j2 miles ahead of competing offerings in terms of performance, certainly at the time when Log4j2 was first released.
© 2022 - 2024 — McMap. All rights reserved.