成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何使用Disruptor(一)Ringbuffer的特別

開發 后端
首先介紹ringbuffer。我對Disruptor的最初印象就是ringbuffer。但是后來我意識到盡管ringbuffer是整個模式(Disruptor)的核心,但是Disruptor對ringbuffer的訪問控制策略才是真正的關鍵點所在。

最近,我們開源了LMAX Disruptor, 它是我們的交易系統吞吐量快(LMAX是一個新型的交易平臺,號稱能夠單線程每秒處理數百萬的訂單)的關鍵原因。為什么我們要將其開源?我們意識到對高性 能編程領域的一些傳統觀點,有點不對勁。我們找到了一種更好、更快地在線程間共享數據的方法,如果不公開于業界共享的話,那未免太自私了。同時開源也讓我 們覺得看起來更酷。

從這個站點,你可以下載到一篇解釋什么是Disruptor及它為什么如此高性能的文檔。這篇文檔的編寫過程,我并沒有參與太多,只是簡單地插入了一些標點符號和重組了一些我不懂的句子,但是非常高興的是,我仍然從中提升了自己的寫作水平。

我發現要把所有的事情一下子全部解釋清楚還是有點困難的,所有我準備一部分一部分地解釋它們,以適合我的NADD聽眾。

首先介紹ringbuffer。我對Disruptor的最初印象就是ringbuffer。但是后來我意識到盡管ringbuffer是整個模式(Disruptor)的核心,但是Disruptor對ringbuffer的訪問控制策略才是真正的關鍵點所在。

 

ringbuffer到底是什么?

嗯,正如名字所說的一樣,它是一個環(首尾相接的環),你可以把它用做在不同上下文(線程)間傳遞數據的buffer。

RingBuffer.png

(好吧,這是我通過畫圖板手畫的,我試著畫草圖,希望我的強迫癥不會讓我畫完美的圓和直線)

基本來說,ringbuffer擁有一個序號,這個序號指向數組中下一個可用的元素。(校對注:如下圖右邊的圖片表示序號,這個序號指向數組的索引4的位置。)

RingBufferInitial.png

隨著你不停地填充這個buffer(可能也會有相應的讀取),這個序號會一直增長,直到繞過這個環。

要找到數組中當前序號指向的元素,可以通過mod操作:

sequence mod array length = array index           

以上面的ringbuffer為例(java的mod語法):12 % 10 = 2。很簡單吧。

事實上,上圖中的ringbuffer只有10個槽完全是個意外。如果槽的個數是2的N次方更有利于基于二進制的計算機進行計算。

(校對注:2的N次方換成二進制就是1000,100,10,1這樣的數字, sequence & (array length-1) = array index,比如一共有8槽,3&(8-1)=3,HashMap就是用這個方式來定位數組元素的,這種方式比取模的速度更快。)

那又怎么樣?

如果你看了維基百科里面的關于環形buffer的 詞條,你就會發現,我們的實現方式,與其最大的區別在于:沒有尾指針。我們只維護了一個指向下一個可用位置的序號。這種實現是經過深思熟慮的—我們選擇用 環形buffer的最初原因就是想要提供可靠的消息傳遞。我們需要將已經被服務發送過的消息保存起來,這樣當另外一個服務通過nak (校對注:拒絕應答信號)告訴我們沒有成功收到消息時,我們能夠重新發送給他們。

聽起來,環形buffer非常適合這個場景。它維護了一個指向尾部的序號,當收到nak(校對注:拒絕應答信號)請求,可以重發從那一點到當前序號之間的所有消息:

RingBufferReplay.png

我們實現的ring buffer和大家常用的隊列之間的區別是,我們不刪除buffer中的數據,也就是說這些數據一直存放在buffer中,直到新的數據覆蓋他們。這就是 和維基百科版本相比,我們不需要尾指針的原因。ringbuffer本身并不控制是否需要重疊(決定是否重疊是生產者-消費者行為模式的一部分–如果你等 不急我寫blog來說明它們,那么可以自行檢出Disruptor項目)。

它為什么如此優秀?

之所以ringbuffer采用這種數據結構,是因為它在可靠消息傳遞方面有很好的性能。這就夠了,不過它還有一些其他的優點。

首先,因為它是數組,所以要比鏈表快,而且有一個容易預測的訪問模式。(譯者注:數組內元素的內存地址的連續性存儲的)。這是對CPU緩存友好的—也就是說,在硬件級別,數組中的元素是會被預加載的,因此在ringbuffer當中,cpu無需時不時去主存加載數組中的下一個元素。(校對注:因為只要一個元素被加載到緩存行,其他相鄰的幾個元素也會被加載進同一個緩存行)

其次,你可以為數組預先分配內存,使得數組對象一直存在(除非程序終止)。這就意味著不需要花大量的時間用于垃圾回收。此外,不像鏈表那樣,需要為每一個添加到其上面的對象創造節點對象—對應的,當刪除節點時,需要執行相應的內存清理操作。

缺少的部分

我并沒有在本文中介紹如何避免ringbuffer產生重疊,以及如何對ringbuffer進行讀寫操作。你可能注意到了我將ringbuffer和鏈表那樣的數據結構進行比較,因為我并認為鏈表是實際問題的標準答案。

當你將Disruptor和基于 隊列之類的實現進行比較時,事情將變得很有趣。隊列通常注重維護隊列的頭尾元素,添加和刪除元素等。所有的這些我都沒有在ringbuffer里提到,這 是因為ringbuffer不負責這些事情,我們把這些操作都移到了數據結構(ringbuffer)的外部

原文鏈接:http://ifeve.com/ringbuffer/

譯文鏈接:http://ifeve.com/dissecting-disruptor-whats-so-special/

責任編輯:陳四芳 來源: ifeve.com
相關推薦

2013-06-18 11:15:44

DisruptorRingbuffer

2013-06-19 11:33:13

DisruptorRingbuffer

2024-12-31 07:56:33

Disruptor內存有界隊列消費模式

2013-06-17 14:41:10

Disruptor并發編程

2009-07-31 11:34:39

光纜用途

2022-06-09 08:36:56

高性能Disruptor模式

2025-03-04 00:30:00

2012-05-10 10:18:14

JavaDisruptor

2022-12-09 08:40:56

高性能內存隊列

2011-04-06 10:09:56

MySQL數據庫安裝

2017-11-29 16:00:42

加班行業無效

2023-10-23 11:40:44

SpringBootDisruptor

2013-06-19 10:55:40

Disruptor并發框架

2022-04-05 12:59:07

源碼線程onEvent

2021-02-02 15:38:19

Disruptor緩存Java

2018-07-03 15:29:00

2018-01-22 09:56:24

2012-02-13 09:57:51

JavaDisruptor

2024-12-11 07:59:02

2021-03-11 08:55:47

JavaUser對象
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久久视频在线 | 日韩精品一区二区三区中文在线 | 国产精品国产三级国产aⅴ无密码 | 久久天天躁狠狠躁夜夜躁2014 | 欧美一级高潮片免费的 | 成年精品 | 国产激情偷乱视频一区二区三区 | 亚洲精品乱码久久久久久黑人 | 91久久精品国产91久久 | 久草中文在线观看 | 伊人一二三| 欧美视频成人 | 在线 丝袜 欧美 日韩 制服 | 中文字幕免费中文 | 老外黄色一级片 | 国产一区精品在线 | 亚洲高清av在线 | 亚洲精品视频在线 | 欧洲一级毛片 | 亚洲一区二区欧美 | 韩国av网站在线观看 | 国产精品中文在线 | 国产农村妇女毛片精品久久麻豆 | 天天操夜夜骑 | 亚洲精品视频免费观看 | 成人免费看片又大又黄 | 国产在线视频三区 | 91资源在线 | 免费在线观看成年人视频 | 成人在线观 | 欧美日韩1区2区 | 国产在线精品一区二区 | 91精品一区 | 免费在线成人网 | 免费高潮视频95在线观看网站 | 亚洲区中文字幕 | 亚洲精品一区二区三区在线 | 国产一区二区三区在线 | 色婷婷激情综合 | 在线观看亚洲专区 | www久久久 |