鍍金池/ 教程/ Java/ LMAX Disruptor——一個(gè)高性能、低延遲且簡(jiǎn)單的框架
Ringbuffer的特別之處
寫(xiě)入 Ringbuffer
鎖的缺點(diǎn)
神奇的緩存行填充
如何從Ringbuffer讀取
Disruptor Wizard已死,Disruptor Wizard永存!
線程間共享數(shù)據(jù)無(wú)需競(jìng)爭(zhēng)
LMAX Disruptor——一個(gè)高性能、低延遲且簡(jiǎn)單的框架
通過(guò) Axon 和 Disruptor處理 1M tps
揭秘內(nèi)存屏障
Disruptor (無(wú)鎖并發(fā)框架)-發(fā)布
LMAX架構(gòu)
偽共享(False Sharing)
解析 Disruptor 的依賴關(guān)系
Disruptor 2.0 更新摘要

LMAX Disruptor——一個(gè)高性能、低延遲且簡(jiǎn)單的框架

原文地址:LMAX Disruptor – High Performance, Low Latency and Simple Too

翻譯:楊帆 校對(duì):丁一

Disruptor 是一個(gè)用于在線程間通信的高效低延時(shí)的消息組件,它像個(gè)增強(qiáng)的隊(duì)列,并且它是讓 LMAX Exchange 跑的如此之快的一個(gè)關(guān)鍵創(chuàng)新。關(guān)于什么是 Disruptor、為何它很重要以及它的工作原理方面的信息都呈爆炸性增長(zhǎng) —— 這些文章很適合開(kāi)始學(xué)習(xí) Disruptor,還可跟著 LMAX BLOG 深入學(xué)習(xí)。這里還有一份更詳細(xì)的白皮書(shū)

雖然 disruptor 模式使用起來(lái)很簡(jiǎn)單,但是建立多個(gè)消費(fèi)者以及它們之間的依賴關(guān)系需要的樣板代碼太多了。為了能快速又簡(jiǎn)單適用于 99 %的場(chǎng)景,我為 Disruptor 模式準(zhǔn)備了一個(gè)簡(jiǎn)單的領(lǐng)域特定語(yǔ)言。例如,為建立一個(gè)消費(fèi)者的“四邊形模式”:

http://wiki.jikexueyuan.com/project/disruptor-getting-started/images/10-1.png" alt="" />

(從 Trisha Gee’s excellent series explaining the disruptor pattern 偷來(lái)的圖片)

在這種情況下,只要生產(chǎn)者(P1)將元素放到ring buffer上,消費(fèi)者 C1 和 C2 就可以并行處理這些元素。但是消費(fèi)者 C3 必須一直等到 C1 和 C2 處理完之后,才可以處理。在現(xiàn)實(shí)世界中的對(duì)應(yīng)的案例就像:在處理實(shí)際的業(yè)務(wù)邏輯(C3)之前,需要校驗(yàn)數(shù)據(jù)(C1),以及將數(shù)據(jù)寫(xiě)入磁盤(C2)。

用原生的 Disruptor 語(yǔ)法來(lái)創(chuàng)建這些消費(fèi)者的話代碼如下:

Executor executor = Executors.newCachedThreadPool();
BatchHandler handler1 = new MyBatchHandler1();
BatchHandler handler2 = new MyBatchHandler2();
BatchHandler handler3 = new MyBatchHandler3()
RingBuffer ringBuffer = new RingBuffer(ENTRY_FACTORY, RING_BUFFER_SIZE);
ConsumerBarrier consumerBarrier1 = ringBuffer.createConsumerBarrier();
BatchConsumer consumer1 = new BatchConsumer(consumerBarrier1, handler1);
BatchConsumer consumer2 = new BatchConsumer(consumerBarrier1, handler2);
ConsumerBarrier consumerBarrier2 =
ringBuffer.createConsumerBarrier(consumer1, consumer2);
BatchConsumer consumer3 = new BatchConsumer(consumerBarrier2, handler3);
executor.execute(consumer1);
executor.execute(consumer2);
executor.execute(consumer3);
ProducerBarrier producerBarrier =
ringBuffer.createProducerBarrier(consumer3);

在以上這段代碼中,我們不得不創(chuàng)建那些個(gè) handler(就是那些個(gè) MyBatchHandler 實(shí)例),外加消費(fèi)者屏障,BatchConsumer 實(shí)例,然后在他們各自的線程中處理這些消費(fèi)者。DSL 能幫我們完成很多創(chuàng)建工作,最終的結(jié)果如下:

Executor executor = Executors.newCachedThreadPool();
BatchHandler handler1 = new MyBatchHandler1();
BatchHandler handler2 = new MyBatchHandler2();
BatchHandler handler3 = new MyBatchHandler3();
DisruptorWizard dw = new DisruptorWizard(ENTRY_FACTORY,
    RING_BUFFER_SIZE, executor);
dw.consumeWith(handler1, handler2).then(handler3);
ProducerBarrier producerBarrier = dw.createProducerBarrier();

我們甚至可以在一個(gè)更復(fù)雜的六邊形模式中構(gòu)建一個(gè)并行消費(fèi)者鏈:

http://wiki.jikexueyuan.com/project/disruptor-getting-started/images/10-2.png" alt="" />

dw.consumeWith(handler1a, handler2a);
dw.after(handler1a).consumeWith(handler1b);
dw.after(handler2a).consumeWith(handler2b);
dw.after(handler1b, handler2b).consumeWith(handler3);
ProducerBarrier producerBarrier = dw.createProducerBarrier();

這個(gè)領(lǐng)域特定語(yǔ)言剛剛誕生不久,歡迎任何反饋,也歡迎大家從 github 上 fork 并改進(jìn)它。

原創(chuàng)文章,轉(zhuǎn)載請(qǐng)注明: 轉(zhuǎn)載自并發(fā)編程網(wǎng) – ifeve.com

本文鏈接地址: LMAX Disruptor——一個(gè)高性能、低延遲且簡(jiǎn)單的框架