Всем привет!
Еще один широиспользуемый паттерн, более низкого уровня, чем описанные ранее: LMAX Disruptor.
https://lmax-exchange.github.io/disruptor/disruptor.html
Это готовая библиотека, решающая следующую задачу: есть упорядоченная очередь из каких-то данных, пишет в нее один поток, обрабатывать данные нужно в несколько потоков без блокировок. Реализована в виде кольцевого буфера и набора указателей на текущую ячейку буфера, по одному для каждого потока-читателя\писателя. В каждый момент времени в буфер пишет один поток, блокировки не ставятся, каждый поток может прочитать указатели других потоков и т.об. понять, с какими ячейками можно работать. Библиотеку достаточно хорошо пиарят, даже сам Мартин Фаулер: https://martinfowler.com/articles/lmax.html Использует log4j https://logging.apache.org/log4j/2.x/manual/async.html#UnderTheHood
Но вернемся к более общим архитектурным принципам: при реализации этой библиотеки используется принцип Mechanical Sympathy https://www.baeldung.com/lmax-disruptor-concurrency#1-mechanical-sympathy.
Суть его в следующем: хотя язык программирования и JVM в случае Java скрывают от нас кишочки компьютера - регистры процессора, кэши процессора 1,2,3 уровня, особенности работы процессора - для максимальной производительности их нужно учитывать. На примере LMAX Disruptor:
1) кольцевой буфер позволяет переиспользовать объекты в куче, уменьшая нагрузку на Garbage Collector
2) кольцевой буфер выделяется одним "куском", поэтому использует последовательные адреса в памяти, что ускоряет пакетное чтение из буфера - как за счет собственно последовательного чтения, так и зачет упреждающего кэширования процессором
3) одновременная запись в память приводит к взаимным сбросам кэша у различных ядер процессора, что плохо сказывается на производительности. В LMAX Disruptor, как я уже говорил, в каждый момент времени пишет в буфер один поток.
Все это вместе с отсутствием блокировок приводит к хорошей производительности.
Но к слову есть люди, считающие библиотеку слишком распиаренной - см. комментарии к статье https://dev.cheremin.info/2011/09/disruptor-1.html
#patterns #library
Еще один широиспользуемый паттерн, более низкого уровня, чем описанные ранее: LMAX Disruptor.
https://lmax-exchange.github.io/disruptor/disruptor.html
Это готовая библиотека, решающая следующую задачу: есть упорядоченная очередь из каких-то данных, пишет в нее один поток, обрабатывать данные нужно в несколько потоков без блокировок. Реализована в виде кольцевого буфера и набора указателей на текущую ячейку буфера, по одному для каждого потока-читателя\писателя. В каждый момент времени в буфер пишет один поток, блокировки не ставятся, каждый поток может прочитать указатели других потоков и т.об. понять, с какими ячейками можно работать. Библиотеку достаточно хорошо пиарят, даже сам Мартин Фаулер: https://martinfowler.com/articles/lmax.html Использует log4j https://logging.apache.org/log4j/2.x/manual/async.html#UnderTheHood
Но вернемся к более общим архитектурным принципам: при реализации этой библиотеки используется принцип Mechanical Sympathy https://www.baeldung.com/lmax-disruptor-concurrency#1-mechanical-sympathy.
Суть его в следующем: хотя язык программирования и JVM в случае Java скрывают от нас кишочки компьютера - регистры процессора, кэши процессора 1,2,3 уровня, особенности работы процессора - для максимальной производительности их нужно учитывать. На примере LMAX Disruptor:
1) кольцевой буфер позволяет переиспользовать объекты в куче, уменьшая нагрузку на Garbage Collector
2) кольцевой буфер выделяется одним "куском", поэтому использует последовательные адреса в памяти, что ускоряет пакетное чтение из буфера - как за счет собственно последовательного чтения, так и зачет упреждающего кэширования процессором
3) одновременная запись в память приводит к взаимным сбросам кэша у различных ядер процессора, что плохо сказывается на производительности. В LMAX Disruptor, как я уже говорил, в каждый момент времени пишет в буфер один поток.
Все это вместе с отсутствием блокировок приводит к хорошей производительности.
Но к слову есть люди, считающие библиотеку слишком распиаренной - см. комментарии к статье https://dev.cheremin.info/2011/09/disruptor-1.html
#patterns #library
lmax-exchange.github.io
LMAX Disruptor: High performance alternative to bounded queues for exchanging data between concurrent threads