Disruptor quickStart!

????????說到隊列,大家都很熟悉弦撩,像生活中不管是吃飯還是買東西基本上都會遇到排隊,先排隊的人先付款论皆,不允許插隊益楼,否則可能會出現(xiàn)下面的情況:


先進先出猾漫,這就是典型的“隊列”。

簡單回顧jdk里的隊列

這里簡單講一下以下倆種隊列

1感凤、阻塞隊列:

ArrayBlockingQueue:?Object[] +?count +?lock.condition(notEmpty悯周、notFull)

入隊:

?? ?不阻塞:add、offer 滿了直接報錯

? ? 阻塞:put 滿了:notFull.await();(當出隊和刪除元素時喚醒put操作)

出隊:

? ? take():當空時,notEmpty.await();當有元素入隊時喚醒.

? ? poll():當空時直接返回null

LinkedBlockingQueue:Node實現(xiàn)陪竿、加鎖(讀鎖禽翼、寫鎖分離)、可選的有界隊列族跛。需要考慮實際使用中的內(nèi)存問題闰挡,防止溢出。

應(yīng)用:Eexcutors默認是使用LinkedBlockingQueue礁哄,但是在實際應(yīng)用中长酗,更應(yīng)該手動創(chuàng)建線程池使用有界隊列,防止生產(chǎn)者生產(chǎn)過快桐绒,導(dǎo)致內(nèi)存溢出花枫。

2、延遲隊列:

DelayQueue :?PriorityQueue + Lock.condition +?leader

PriorityQueue優(yōu)先級隊列

condition 延遲等待

leader 避免不必要的kong等待

參數(shù):

?? ?getDelay()延遲時間

?? ?compareTo()通過該方法比較從PriorityQueue里取值

入隊:

add掏膏、put劳翰、offer:入隊時會將換喚醒等待中的線程,進行一次出隊處理

出隊:

take()阻塞:

?? ?1馒疹、如果隊列里無數(shù)據(jù)佳簸,元素入隊時會被喚醒

? ? 2、有數(shù)據(jù)颖变,會阻塞至?xí)r間滿足

poll():滿足隊列有數(shù)據(jù)并且delay時間不大于0會取出元素生均,否則立即返回null—可能會搶占成為leader

還有優(yōu)先級隊列等就不一一細說,有興趣的同學(xué)可以去看一下腥刹。

應(yīng)用:延時任務(wù):設(shè)置任務(wù)延遲多久執(zhí)行马胧;需要設(shè)置過期值的處理,例如緩存過期衔峰,實現(xiàn)方式:每次getDealy()方法提供一個緩存創(chuàng)建時間與當前時間的差值佩脊,出隊時compareTo()方法取差值最小的。每次入隊時都會重新取出隊列里差值最小的值進行處理垫卤。

????????我們使用隊列的威彰,更多的是像生產(chǎn)者、消費者這種場景穴肘。這種場景大多數(shù)情況又對處理速度有著要求歇盼,所以我們會使用多線程技術(shù)。使用多線程就可能會出現(xiàn)并發(fā)评抚,為了避免出錯豹缀,我們會選擇線程安全的隊列伯复。例如ArrayBlockingQueue、LinkedBlockingQueue或者是ConcurrentLinkedQueue邢笙,前倆者是通過加鎖取實現(xiàn)啸如,后面一種是通過cas去實現(xiàn)線程安全。但是又要考慮到生產(chǎn)者過快可能造出的內(nèi)存溢出的問題鸣剪,所以看起來ArrayBlockingQueue是最符合要求的。但是恰恰加鎖效率又是最慢的丈积,所以就引出了我們今天需要討論的主題:Disruptor筐骇!

比較:

ArrayBlockingQueue VS Disruptor

看代碼。江滨。铛纬。

介紹

????????Martin Fowler在自己網(wǎng)站上寫了一篇LMAX架構(gòu)的文章,在文章中他介紹了LMAX是一種新型零售金融交易平臺唬滑,它能夠以很低的延遲產(chǎn)生大量交易告唆。這個系統(tǒng)是建立在JVM平臺上,其核心是一個業(yè)務(wù)邏輯處理器晶密,它能夠在一個線程里每秒處理6百萬訂單擒悬。業(yè)務(wù)邏輯處理器完全是運行在內(nèi)存中(圈起來要考),使用事件源驅(qū)動方式稻艰。業(yè)務(wù)邏輯處理器的核心是Disruptor懂牧。

接下來我們來看一下disruptor是如何做到無阻塞、多生產(chǎn)尊勿、多消費的僧凤。



EventFactory:創(chuàng)建消息(任務(wù))的工廠類

ringBufferSize:容器的長度

Executor:消費者線程池,執(zhí)行任務(wù)的線程

ProductType:生產(chǎn)者類型:單生產(chǎn)者元扔、多生產(chǎn)者

WaitStrategy:等待策略

下面簡單看一下disruptor的代碼躯保。

看代碼。澎语。途事。

可以看出在調(diào)用了start()方法后,消費者線程就已經(jīng)開啟擅羞,其中涉及到一個重要的概念:EventProcessor

BatchEventProcessor主要事件循環(huán)盯孙,處理disruptor中的event,擁有消費者的Sequence

另一個核心概念:RingBuffer:它是一個首尾相接的環(huán)狀的容器祟滴,用來在多線程中傳遞數(shù)據(jù)振惰。可以看到我們進行生產(chǎn)者時垄懂,先從ringbuffer里拿骑晶,再進行投遞痛垛。


這里使用next()獲得的序號為數(shù)組中下一個可用的元素,再get(seq)獲取到該位置的元素桶蛔,再進行賦值處理匙头。

這里的序號是如何產(chǎn)生的呢?

Sequence:順序遞增的序號來編號仔雷,管理交換的數(shù)據(jù)蹂析。生產(chǎn)者和消費者都會有維護自己的Sequence,通過進行比較碟婆,來平衡生產(chǎn)者和消費者的關(guān)系电抚。消除偽共享(填充緩存行)。

Sequencer:在生產(chǎn)者和消費者之間快速竖共、正確的傳遞數(shù)據(jù)的并發(fā)算法

Sequence Barrier:序號柵欄蝙叛,用來平衡生產(chǎn)者和消費者之間的關(guān)系

上面說到ringBuffer有定義長度,說明是一個有界的隊列公给,那么可能會出現(xiàn)以下倆種情況:當消費者消費速度大于生產(chǎn)者生產(chǎn)者速度借帘,生產(chǎn)者還未來得及往隊列寫入,或者生產(chǎn)者生產(chǎn)速度大于消費者消費速度淌铐,此時怎么辦呢肺然?

常用的WaitStrategy等待策略(消費者等待)

BlockingWaitStrategy使用了鎖,低效的策略腿准。

SleepingWaitStrategy對生產(chǎn)者線程的影響最小狰挡,適合用于異步日志類似的場景。(不加鎖空等)

YieldingWaitStrategy性能最好释涛,適合用于低延遲的系統(tǒng)加叁,在要求極高性能且之間處理線數(shù)小于cpu邏輯核心數(shù)的場景中,推薦使用唇撬。(無鎖策略它匕。主要是使用了Thread.yield()多線程交替執(zhí)行)

至此,disruptor的基本核心概念已經(jīng)介紹完畢窖认!

Disruptor多邊形操作:


如何實現(xiàn)第一張圖里的多邊形操作豫柬?

```

disruptor.handleEventsWith(E1, E2);

disruptor.after(E1).handleEventsWith(E3);

disruptor.after(E2).handleEventsWith(E4);

disruptor.after(E3, E4).handleEventsWith(E5);

```

有興趣的同學(xué)可以試一下!

再了解了disruptor的核心概念和看了代碼之后扑浸,就可以繼續(xù)學(xué)習(xí)disruptor的多生產(chǎn)多消費模型了烧给,disruptor的多線程才能發(fā)揮真正的力量!

多生產(chǎn)多消費模型


簡單看一下代碼喝噪。础嫡。。


簡單分析,多個生產(chǎn)者同時向ringbuffer投遞數(shù)據(jù)榴鼎,假設(shè)此時倆個生產(chǎn)者將ringbuffer已經(jīng)填滿伯诬,因為sequence的序號是自增+1(若不滿足獲取條件則循環(huán)掛起當前線程),所以生產(chǎn)的時候能保證線程安全巫财,只需要一個sequence即可盗似。當多消費者來消費的時候,因為消費速度不同平项,例如消費者1來消費0赫舒、1,消費者2消費2闽瓢、4接癌,消費者3消費3。當消費者消費完0后鸳粉,消費者2消費完2后扔涧,消費者3消費完3后园担,生產(chǎn)者再往隊列投遞數(shù)據(jù)時届谈,其他位置還未被消費,會投遞到第0個位置弯汰, 此時再想投遞數(shù)據(jù)時艰山,雖然消費2的第二個位置空缺、消費者3的第三個位置空缺咏闪,消費者還在消費1時曙搬,無法繼續(xù)投遞。因為是通過比較消費者自身維護的sequence的最小的序號鸽嫂,來進行比較纵装。

應(yīng)用:

Apache Storm、Camel据某、Log4j 2

Log4j2 example:

使用了實現(xiàn)EventTranslator的提交機制橡娄。


可參考美團文章:https://tech.meituan.com/2016/11/18/disruptor.html中指出:美團在公司內(nèi)部統(tǒng)一推行日志接入規(guī)范,要求必須使用Log4j 2癣籽,使普通單機QPS的上限不再只停留在幾千挽唉,極高地提升了服務(wù)性能。

over筷狼∑孔眩~!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末埂材,一起剝皮案震驚了整個濱河市塑顺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌俏险,老刑警劉巖茬暇,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件首昔,死亡現(xiàn)場離奇詭異,居然都是意外死亡糙俗,警方通過查閱死者的電腦和手機勒奇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巧骚,“玉大人赊颠,你說我怎么就攤上這事∨耄” “怎么了竣蹦?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長沧奴。 經(jīng)常有香客問我痘括,道長,這世上最難降的妖魔是什么滔吠? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任纲菌,我火速辦了婚禮,結(jié)果婚禮上疮绷,老公的妹妹穿的比我還像新娘翰舌。我一直安慰自己,他們只是感情好冬骚,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布椅贱。 她就那樣靜靜地躺著,像睡著了一般只冻。 火紅的嫁衣襯著肌膚如雪庇麦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天喜德,我揣著相機與錄音山橄,去河邊找鬼。 笑死住诸,一個胖子當著我的面吹牛驾胆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播贱呐,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼丧诺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了奄薇?” 一聲冷哼從身側(cè)響起驳阎,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后呵晚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蜘腌,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年饵隙,在試婚紗的時候發(fā)現(xiàn)自己被綠了撮珠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡金矛,死狀恐怖芯急,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情驶俊,我是刑警寧澤娶耍,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站饼酿,受9級特大地震影響榕酒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜故俐,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一想鹰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧购披,春花似錦杖挣、人聲如沸肩榕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽株汉。三九已至筐乳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間乔妈,已是汗流浹背蝙云。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留路召,地道東北人勃刨。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像股淡,于是被迫代替她去往敵國和親身隐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353