關於Disruptor的分享

第一篇博客,萬事開頭難。有點粗糙。

介紹:

最近項目中須要修改bug,涉及到前面大牛寫的用disruptor異步處理業務的場景。後來業務bug修復了,可是線上的處理特別慢,延遲將近一個小時,因此抽空記錄下來學習的過程。不過因爲本人才疏學淺,實在是能力有限,不少理解有問題的地方,但願用過的人可以幫我指正出來,一塊兒學習。謝謝。 LMAX是一種新型零售金融交易平臺,它可以以很低的延遲產生大量交易。這個系統是創建在JVM平臺上,其核心是一個業務邏輯處理器,它可以在一個線程裏每秒處理6百萬訂單。業務邏輯處理器徹底是運行在內存中,使用事件源驅動方式。業務邏輯處理器的核心是Disruptor。 首先咱們都知道併發編程的好處,看起來並行處理的效率比單線程的來的快的多,因此在許多涉及到高併發的場景中,可是在這裏要打破併發處理更快的理解,這樣方便理解disruptor爲何這樣快。編程

第一點,數據結構。

disruptor採用的是ringbuffer,是一種環形數組,借一張盜來的圖。 ![ringbuffer]數組

首先爲何要用數組,都知道大部分緩存都用鏈表隊列。來對比一下鏈表和數組。緩存

數組和鏈表的區別

數組是將元素在內存中連續存放,因爲每一個元素佔用內存相同,能夠經過下標迅速訪問數組中任何元素。 可是若是要在數組中增長一個元素,須要移動大量元素,在內存中空出一個元素的空間,而後將要增長的元素放在其中。 一樣的道理,若是想刪除一個元素,一樣須要移動大量元素去填掉被移動的元素。若是應用須要快速訪問數據,不多或不插入和刪除元素,就應該用數組。 鏈表剛好相反,鏈表中的元素在內存中不是順序存儲的,而是經過存在元素中的指針聯繫到一塊兒。好比:上一個元素有個指針指到下一個元素, 以此類推,直到最後一個元素。若是要訪問鏈表中一個元素,須要從第一個元素開始,一直找到須要的元素位置。可是增長和刪除一個元素對於鏈表數據結構就很是簡單了, 只要修改元素中的指針就能夠了。若是應用須要常常插入和刪除元素你就須要用鏈表數據結構了。 因此說場景中大部分消費者須要刪除隊列中的數據,因此須要鏈表的隊列。而不是數組。 這裏爲何能夠用數組呢,由於場景中能夠覆蓋數據,而不須要刪除數據,並且不須要擴容,由於是環形的。容量固定的,最好是2的冪數,這樣方便後面生產消費獲取位置。並且數組能夠預加載相鄰的元素。 並且它只維護了一個尾指針,用來幫助生產消費者獲取位置。數據結構

第三點,無鎖,緩存行填充 ,解決僞共享以及內存屏障的問題

通常來講鎖是下降效率的。 對於共享數據。因此我認爲若是我應用disruptor, 模式的話我會選單生產,多消費的模式,儘管它提供了多生產多消費的模式, 可是這樣會有寫入的競爭,會影響效率。讀取數據的話,卻是無所謂。 這裏還有涉及cpu,主內存的相關問題。儘管這纔是disruptor快的真正緣由,可是太過抽象,看懂一點,也不能很好理解。仍是參考譯文吧。 http://ifeve.com/disruptor-cacheline-padding/ ###Next 下一篇我會給出disruptor的demo代碼而且結合項目中的業務場景,嘗試找出線上處理沒有達到期待的速度的緣由。併發

參考文章:

http://ifeve.com/disruptor異步

相關文章
相關標籤/搜索