Disruptor quickStart!

??說到隊列抹竹,大家都很熟悉,像生活中不管是吃飯還是買東西基本上都會遇到排隊父泳,先排隊的人先付款般哼,不允許插隊吴汪,否則可能會出現(xiàn)下面的情況:

image

先進(jìn)先出,這就是典型的“隊列”蒸眠。

簡單回顧jdk里的隊列

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

1漾橙、阻塞隊列:

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

入隊:

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

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

出隊:

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

poll():當(dāng)空時直接返回null

LinkedBlockingQueue:Node實現(xiàn)霜运、加鎖(讀鎖、寫鎖分離)蒋腮、可選的有界隊列淘捡。需要考慮實際使用中的內(nèi)存問題,防止溢出池摧。

應(yīng)用:Eexcutors默認(rèn)是使用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等待

方法:

getDelay()延遲時間

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

入隊:

add瓣距、put、offer:入隊時會將換喚醒等待中的線程代咸,進(jìn)行一次出隊處理

出隊:

take()阻塞:

1蹈丸、如果隊列里無數(shù)據(jù),元素入隊時會被喚醒

2呐芥、有數(shù)據(jù)逻杖,會阻塞至?xí)r間滿足

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

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

應(yīng)用:延時任務(wù):設(shè)置任務(wù)延遲多久執(zhí)行;需要設(shè)置過期值的處理滨攻,例如緩存過期够话,實現(xiàn)方式:每次getDealy()方法提供一個緩存創(chuàng)建時間與當(dāng)前時間的差值,出隊時compareTo()方法取差值最小的光绕。每次入隊時都會重新取出隊列里差值最小的值進(jìn)行處理女嘲。

??我們使用隊列的,更多的是像生產(chǎn)者诞帐、消費(fèi)者這種場景欣尼。這種場景大多數(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ù)邏輯處理器完全是運(yùn)行在內(nèi)存中(圈起來要考)估脆,使用事件源驅(qū)動方式钦奋。業(yè)務(wù)邏輯處理器的核心是Disruptor。

接下來我們來看一下disruptor是如何做到無阻塞疙赠、多生產(chǎn)付材、多消費(fèi)的。

image

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

ringBufferSize:容器的長度

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

ProductType:生產(chǎn)者類型:單生產(chǎn)者厌衔、多生產(chǎn)者

WaitStrategy:等待策略

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

看代碼捍岳。富寿。。

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

BatchEventProcessor主要事件循環(huán),處理disruptor中的event银萍,擁有消費(fèi)者的Sequence

image

另一個核心概念:RingBuffer:它是一個首尾相接的環(huán)狀的容器泞坦,用來在多線程中傳遞數(shù)據(jù)∽┣辏可以看到我們進(jìn)行生產(chǎn)者時贰锁,先從ringbuffer里拿赃梧,再進(jìn)行投遞。

image

這里使用next()獲得的序號為數(shù)組中下一個可用的元素豌熄,再get(seq)獲取到該位置的元素授嘀,再進(jìn)行賦值處理。

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

Sequence:順序遞增的序號來編號蹄皱,管理交換的數(shù)據(jù)。生產(chǎn)者和消費(fèi)者都會有維護(hù)自己的Sequence芯肤,通過進(jìn)行比較巷折,來平衡生產(chǎn)者和消費(fèi)者的關(guān)系。消除偽共享(填充緩存行)崖咨。

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

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

image

上面說到ringBuffer有定義長度击蹲,說明是一個有界的隊列署拟,那么可能會出現(xiàn)以下倆種情況:當(dāng)消費(fèi)者消費(fèi)速度大于生產(chǎn)者生產(chǎn)者速度,生產(chǎn)者還未來得及往隊列寫入歌豺,或者生產(chǎn)者生產(chǎn)速度大于消費(fèi)者消費(fèi)速度推穷,此時怎么辦呢?

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

BlockingWaitStrategy使用了鎖类咧,低效的策略馒铃。

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

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

至此述寡,disruptor的基本核心概念已經(jīng)介紹完畢柿隙!

Disruptor多邊形操作:

image

如何實現(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)多消費(fèi)模型了,disruptor的多線程才能發(fā)揮真正的力量螟炫!

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

image

簡單看一下代碼波附。。。

image

簡單分析掸屡,多個生產(chǎn)者同時向ringbuffer投遞數(shù)據(jù)封寞,假設(shè)此時倆個生產(chǎn)者將ringbuffer已經(jīng)填滿,因為sequence的序號是自增+1(若不滿足獲取條件則循環(huán)掛起當(dāng)前線程)仅财,所以生產(chǎn)的時候能保證線程安全狈究,只需要一個sequence即可。當(dāng)多消費(fèi)者來消費(fèi)的時候盏求,因為消費(fèi)速度不同抖锥,例如消費(fèi)者1來消費(fèi)0、1碎罚,消費(fèi)者2消費(fèi)2磅废、4,消費(fèi)者3消費(fèi)3荆烈。當(dāng)消費(fèi)者消費(fèi)完0后拯勉,消費(fèi)者2消費(fèi)完2后,消費(fèi)者3消費(fèi)完3后耙考,生產(chǎn)者再往隊列投遞數(shù)據(jù)時谜喊,其他位置還未被消費(fèi)潭兽,會投遞到第0個位置倦始, 此時再想投遞數(shù)據(jù)時,雖然消費(fèi)2的第二個位置空缺山卦、消費(fèi)者3的第三個位置空缺鞋邑,消費(fèi)者還在消費(fèi)1時,無法繼續(xù)投遞账蓉。因為是通過比較消費(fèi)者自身維護(hù)的sequence的最小的序號枚碗,來進(jìn)行比較。

應(yīng)用:

Apache Storm铸本、Camel肮雨、Log4j 2

Log4j2 example:

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

image

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

over波丰。~舶得!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末掰烟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纫骑,老刑警劉巖蝎亚,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異先馆,居然都是意外死亡颖对,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門磨隘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缤底,“玉大人,你說我怎么就攤上這事番捂「鲞螅” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵设预,是天一觀的道長徙歼。 經(jīng)常有香客問我,道長鳖枕,這世上最難降的妖魔是什么魄梯? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮宾符,結(jié)果婚禮上酿秸,老公的妹妹穿的比我還像新娘。我一直安慰自己魏烫,他們只是感情好辣苏,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著哄褒,像睡著了一般稀蟋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上呐赡,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天退客,我揣著相機(jī)與錄音,去河邊找鬼链嘀。 笑死萌狂,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的管闷。 我是一名探鬼主播粥脚,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼包个!你這毒婦竟也來了刷允?” 一聲冷哼從身側(cè)響起冤留,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎树灶,沒想到半個月后纤怒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡天通,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年泊窘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片像寒。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡烘豹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出诺祸,到底是詐尸還是另有隱情携悯,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布筷笨,位于F島的核電站憔鬼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏胃夏。R本人自食惡果不足惜轴或,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望仰禀。 院中可真熱鬧照雁,春花似錦、人聲如沸悼瘾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽亥宿。三九已至,卻和暖如春砂沛,著一層夾襖步出監(jiān)牢的瞬間烫扼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工碍庵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留映企,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓静浴,卻偏偏與公主長得像堰氓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子苹享,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345