Disruptor的应用示例——大文件拆分
正文
结合最近Disruptor的学习,和之前一直思考解决的大文件拆分问题,想到是否可以使用Disruptor作为生产者/消费者传递数据的通道呢?借助其高效的传递,理论上应当可以提升性能。此文便是此想法的落地实现。
1. 问题描述
将大文件按照指定大小拆分为若干小文件。具体可参考:大文件拆分方案的java实践(附源码)。
2. 方案设计
设计简图
如下:
核心组件
- FileReadTask —— Disruptor的生产者线程,负责读取源文件,;
- Disruptor —— FileReadTask和FileLineEventHandler线程之间传递数据的通道,无阻塞;
- RingBuffer —— Disruptor的核心组件,负责暂存被传递的消息,同时负责协调生产者和消费者之间的工作节奏;
- FileLineEventHandler —— 不断从Disruptor中读取FileLine,并直接扔给FileWriteTask的queue,是Disruptor的消费者,同时也是queue的生产者;
- FileWriteTask —— 从queue中读取FileLine,并写入到子文件,是queue的消费者。
设计思路
使用Disruptor作为生产者和消费者之间传递数据的通道,利用Disruptor高效传递数据的特性提升性能;
FileLineEventHandler作为Disruptor的消费者,只负责从中读取数据,但是不负责耗时长的子文件操作;
FIleWriteTask服务耗时长的文件写入工作,且每个task独享queue,减少资源竞争。
3. 性能表现
实测下来,和之前的‘生产者/消费者+nio’方案性能相当,最佳性能点为:
方案 |
-Xms |
-Xmx |
readTaskNum |
writeTaskNum |
queueSize |
Durition |
jvm_ |
jvm_ |
Physics |
生产者/消费者+nio |
512m |
512m |
24 |
8 |
4096 |
8158 |
80 |
100M |
4.6G |
Disruptor+生产者/消费者+nio |
512m |
512m |
2 |
2 |
1024 |
6191 |
80 |
500m |
4.2G |
相对与不使用Disruptor的方案,时延有所下降,但是并不明显,两个方案主要瓶颈都在于FileReadTask中对文件进行拆分的逻辑处理太费时,需要逐个字节读取并比对是否为换行符/回车符。所以性能提升并不是很明显。且性能表现并不稳定。
4. 心得
这个示例或许没有达到想要的效果,但是通过这个实例,将Disruptor用到了生产者和消费者模式中,体会Disruptor的设计初衷,提升生产者与消费者之间数据传递的效率,尤其是在纯粹地快速交换数据的场景非常有用。
Disruptor持有的entry对象不宜直接传递给后续消费者使用,鉴于Disruptor会对RingBuffer的entries做内存预加载,且会循环使用对应entries,所以如果供消费者直接使用,会出现数据覆盖的问题。可以参考实例代码中FileLineEventHandler对写入queue的FileLine的处理。
5. 代码示例
github地址:https://github.com/daoqidelv/filespilt-demo
包路径:com.daoqidlv.filespilt.disruptor
*****************************************************************************************
********************* 联系方式:qq:464675856; email: huyangleng3684@sina.com **********************
********** 微信个人账号:mr_daoqi ************ ************* 微信公众号:倒骑的驴 **************
*****************************************************************************************
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了