正文

結(jié)合最近Disruptor的學(xué)習(xí),和之前一直思考解決的大文件拆分問題,想到是否可以使用Disruptor作為生產(chǎn)者/消費(fèi)者傳遞數(shù)據(jù)的通道呢?借助其高效的傳遞,理論上應(yīng)當(dāng)可以提升性能。此文便是此想法的落地實(shí)現(xiàn)。

回到頂部

1. 問題描述

將大文件按照指定大小拆分為若干小文件。具體可參考:大文件拆分方案的java實(shí)踐(附源碼)。

回到頂部

2. 方案設(shè)計(jì)

設(shè)計(jì)簡(jiǎn)圖

如下:

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開發(fā)培訓(xùn)

核心組件

  • FileReadTask —— Disruptor的生產(chǎn)者線程,負(fù)責(zé)讀取源文件,;

  • Disruptor —— FileReadTask和FileLineEventHandler線程之間傳遞數(shù)據(jù)的通道,無阻塞;

  • RingBuffer —— Disruptor的核心組件,負(fù)責(zé)暫存被傳遞的消息,同時(shí)負(fù)責(zé)協(xié)調(diào)生產(chǎn)者和消費(fèi)者之間的工作節(jié)奏;

  • FileLineEventHandler —— 不斷從Disruptor中讀取FileLine,并直接扔給FileWriteTask的queue,是Disruptor的消費(fèi)者,同時(shí)也是queue的生產(chǎn)者;

  • FileWriteTask —— 從queue中讀取FileLine,并寫入到子文件,是queue的消費(fèi)者。

設(shè)計(jì)思路

使用Disruptor作為生產(chǎn)者和消費(fèi)者之間傳遞數(shù)據(jù)的通道,利用Disruptor高效傳遞數(shù)據(jù)的特性提升性能;

FileLineEventHandler作為Disruptor的消費(fèi)者,只負(fù)責(zé)從中讀取數(shù)據(jù),但是不負(fù)責(zé)耗時(shí)長(zhǎng)的子文件操作;

FIleWriteTask服務(wù)耗時(shí)長(zhǎng)的文件寫入工作,且每個(gè)task獨(dú)享queue,減少資源競(jìng)爭(zhēng)。

回到頂部

3.  性能表現(xiàn)

實(shí)測(cè)下來,和之前的‘生產(chǎn)者/消費(fèi)者+nio’方案性能相當(dāng),最佳性能點(diǎn)為:

方案

-Xms

-Xmx

readTaskNum

writeTaskNum

queueSize

Durition
(ms)

jvm_
CPU(%)

jvm_
mem

Physics
_mem

生產(chǎn)者/消費(fèi)者+nio

512m

512m

24

8

4096

8158

80

100M

4.6G

Disruptor+生產(chǎn)者/消費(fèi)者+nio

512m

512m

2

2

1024

6191  

80

500m

4.2G

 相對(duì)與不使用Disruptor的方案,時(shí)延有所下降,但是并不明顯,兩個(gè)方案主要瓶頸都在于FileReadTask中對(duì)文件進(jìn)行拆分的邏輯處理太費(fèi)時(shí),需要逐個(gè)字節(jié)讀取并比對(duì)是否為換行符/回車符。所以性能提升并不是很明顯。且性能表現(xiàn)并不穩(wěn)定。

回到頂部

4. 心得

這個(gè)示例或許沒有達(dá)到想要的效果,但是通過這個(gè)實(shí)例,將Disruptor用到了生產(chǎn)者和消費(fèi)者模式中,體會(huì)Disruptor的設(shè)計(jì)初衷,提升生產(chǎn)者與消費(fèi)者之間數(shù)據(jù)傳遞的效率,尤其是在純粹地快速交換數(shù)據(jù)的場(chǎng)景非常有用。

Disruptor持有的entry對(duì)象不宜直接傳遞給后續(xù)消費(fèi)者使用,鑒于Disruptor會(huì)對(duì)RingBuffer的entries做內(nèi)存預(yù)加載,且會(huì)循環(huán)使用對(duì)應(yīng)entries,所以如果供消費(fèi)者直接使用,會(huì)出現(xiàn)數(shù)據(jù)覆蓋的問題??梢詤⒖紝?shí)例代碼中FileLineEventHandler對(duì)寫入queue的FileLine的處理。

回到頂部

5. 代碼示例

github地址:https://github.com/daoqidelv/filespilt-demo

包路徑:com.daoqidlv.filespilt.disruptor

 http://www.cnblogs.com/daoqidelv/p/7107474.html