Почему log4j2 использовал LMAX Disruptor в асинхронном регистраторе вместо любой другой встроенной неблокирующей структуры данных?

#logging #log4j2

#ведение журнала #log4j2

Вопрос:

Я выполняю асинхронное ведение журнала в разных регистраторах. Мне довелось подробно ознакомиться с асинхронным регистратором log4j2. Он использует LMAX Disruptor внутренне для хранения событий. Почему они используют LMAX Disruptor вместо любой встроенной неблокирующей структуры данных Java?

Комментарии:

1. Log4j2 нужна ограниченная очередь без мусора с хорошей задержкой / пропускной способностью. Какая встроенная очередь обладает такими характеристиками?

Ответ №1:

Асинхронные регистраторы, основанные на LMAX Disruptor, были представлены в Log4j 2.0-beta-5 в апреле 2013 года. Log4j2 в то время требовал Java 6. Единственная встроенная неблокирующая структура данных, о которой я знаю в Java 6, это ConcurrentLinkedQueue .

Почему прерыватель? Читая технический документ LMAX Disruptor, я узнал, что очереди, как правило, не являются оптимальной структурой данных для высокопроизводительной межпотоковой связи, потому что всегда есть разногласия в начале или в конце очереди.

LMAX создал лучший дизайн и в своих тестах производительности обнаружил, что LMAX Disruptor значительно превосходит его ArrayBlockingQueue . Они не тестировали ConcurrentLinkedQueue , потому что он неограничен и взорвал бы производителя (ошибка нехватки памяти) в сценариях, где есть медленный потребитель (что довольно распространено).

В то время у меня не было данных из моих собственных тестов, но я помню, что это ConcurrentLinkedQueue было лучше, чем ArrayBlockingQueue , что-то вроде увеличения пропускной способности в 2 раза (моя память о точных цифрах расплывчата). Таким образом, LMAX Disruptor был все еще значительно быстрее, и было гораздо меньше различий в результатах. ConcurrentLinkedQueue иногда результаты были хуже, чем ArrayBlockingQueue , довольно странно.

Производительность LMAX Disruptor была стабильной, намного быстрее, чем у других компонентов, и она была ограниченной, поэтому у нас не было бы нехватки памяти, если бы приложение использовало медленного потребителя, такого как вход в базу данных или консоль.

Как показывает страница производительности асинхронных регистраторов и страница производительности Log4j2 в целом, использование LMAX Disruptor позволило Log4j2 значительно опередить конкурирующие предложения по производительности, конечно, в то время, когда Log4j2 был впервые выпущен.