为什么log4j2在异步记录器中使用了LMAX Disruptor而不是其他任何内置的非阻塞数据结构?

问题描述

我正在不同的记录器中进行异步记录。我碰巧看到了log4j2的异步记录器的详细信息。它在内部使用 LMAX disruptor 存储事件。他们为什么使用LMAX disruptor而不是Java的任何内置非阻塞数据结构?

解决方法

基于LMAX Disruptor的异步日志记录器于2013年4月introduced in Log4j 2.0-beta-5。当时需要Java 4的Log4j2。我知道Java 6中唯一的内置非阻塞数据结构是{{ 1}}。

为什么要破坏者?阅读LMAX Disruptor white paper后,我了解到对于高性能的线程间通信,队列通常不是最佳的数据结构,因为队列的头尾总是有竞争。 / p>

LMAX创建了更好的设计,并在their performance tests中发现LMAX Disruptor的性能大大优于ConcurrentLinkedQueue。他们没有测试ArrayBlockingQueue,因为它ConcurrentLinkedQueue是不受限制的,并且在使用者缓慢的情况下(这很常见)会破坏生产者(内存不足错误)。

我当时没有来自自己测试的数据,但我记得ConcurrentLinkedQueueArrayBlockingQueue更好,吞吐量提高了2倍(确切的数字记忆模糊) 。因此,LMAX Disruptor仍然明显更快,并且结果之间的差异小得多。 ConcurrentLinkedQueue有时比ArrayBlockingQueue的结果差,很奇怪。

LMAX Disruptor的性能稳定,比其他组件快得多,并且受到限制,因此,如果应用程序使用速度较慢的使用者(例如登录数据库或控制台),我们不会耗尽内存。

正如Async Loggers performance page和整个Log4j2 performance page所示,LMAX Disruptor的使用使Log4j2在性能方面领先于竞争产品,肯定是在Log4j2首次发布之时。 / p>