Disruptor的应用示例——大文件拆分
结合最近Disruptor的学习,和之前一直思考解决的大文件拆分问题,想到是否可以使用Disruptor作为生产者/消费者传递数据的通道呢?借助其高效的传递,理论上应当可以提升性能。此文便是此想法的落地实现。
问题描述
将大文件按照指定大小拆分为若干小文件。具体可参考:大文件拆分方案的java实践(附源码)。
方案设计
设计简图
如下:
核心组件
- 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,减少资源竞争。
性能表现
实测下来,和之前的‘生产者/消费者+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中对文件进行拆分的逻辑处理太费时,需要逐个字节读取并比对是否为换行符/回车符。所以性能提升并不是很明显。且性能表现并不稳定。
心得
这个示例或许没有达到想要的效果,但是通过这个实例,将Disruptor用到了生产者和消费者模式中,体会Disruptor的设计初衷,提升生产者与消费者之间数据传递的效率,尤其是在纯粹地快速交换数据的场景非常有用。
Disruptor持有的entry对象不宜直接传递给后续消费者使用,鉴于Disruptor会对RingBuffer的entries做内存预加载,且会循环使用对应entries,所以如果供消费者直接使用,会出现数据覆盖的问题。可以参考实例代码中FileLineEventHandler对写入queue的FileLine的处理。
代码示例
github地址:https://github.com/daoqidelv/filespilt-demo
包路径:com.daoqidlv.filespilt.disruptor
Disruptor的应用示例——大文件拆分的更多相关文章
- 大文件拆分问题的java实践(附源码)
引子 大文件拆分问题涉及到io处理.并发编程.生产者/消费者模式的理解,是一个很好的综合应用场景,为此,花点时间做一些实践,对相关的知识做一次梳理和集成,总结一些共性的处理方案和思路,以供后续工作中借 ...
- 大文件拆分方案的java实践(附源码)
引子 大文件拆分问题涉及到io处理.并发编程.生产者/消费者模式的理解,是一个很好的综合应用场景,为此,花点时间做一些实践,对相关的知识做一次梳理和集成,总结一些共性的处理方案和思路,以供后续工作中借 ...
- Java:大文件拆分工具
java大文件拆分工具(过滤掉表头) import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File ...
- elasticsearch bulk批量导入 大文件拆分
命令如下: curl -s -XPOST http://localhost:9200/_bulk --data-binary @data.json 如果上传的data.json文件较大,可以将其切分为 ...
- RedHat/CentOS 大文件拆分及合并与md5验证
[root@tdh55 mnt]# cd /opt/[root@tdh55 opt]# ll -h-rw-r--r--. 1 root root 7.5G May 12 11:19 TDH-Image ...
- python 小程序大文件的拆分合并
1. 将大文件拆分为小文件 I 通过二进制的方式将大文件读取出来,将其拆分存,以不同的文件方式存放在一个目录下面 II 提供两种操作方式交互式和命令行模式 #! usr/bin/python # -* ...
- 高效读取大文件,再也不用担心 OOM 了!
内存读取 第一个版本,采用内存读取的方式,所有的数据首先读读取到内存中,程序代码如下: Stopwatch stopwatch = Stopwatch.createStarted(); // 将全部行 ...
- PHP读取CSV大文件导入数据库的示例
对于数百万条数据量的CSV文件,文件大小可能达到数百M,如果简单读取的话很可能出现超时或者卡死的现象. 为了成功将CSV文件里的数据导入数据库,分批处理是非常必要的. 下面这个函数是读取CSV文件中指 ...
- php平均拆分大文件为N个小文件
用PHP程序拆分大文件为N个小文件 /* 假设有文件data.log , 内容如下,行数很多,假设有上亿条数据,文件大小大概在800M左右 92735290 80334472 49114074 871 ...
随机推荐
- hive、impala集成ldap
1.概要 1.1 环境信息 hadoop:cdh5.10 os:centos6.7 user:root hive.impala已集成sentry 1.2 访问控制权限 这里通过使用openldap来控 ...
- sublime Text3 新建文件时定义模块
开发的过程中有很多的东西,不需要每次编写,如果每次编写这样会很蛋疼,所以sublime 提供了一个牛逼的插件SublimeTmpl, 这个插件可以定义自己新建的模块. sublimeTmpl 安装 1 ...
- 网页web前端学习技巧
1. 写js效果时一定要注意先分析好效果的行为,尽量用最简单通用性的代码.分析步骤可以是1.先把要实现的功能一步一步的写在纸上(即自然语言)2.再根据自然语言翻译成机器语言,用jquery写的代码一定 ...
- Spark操作HBase问题:java.io.IOException: Non-increasing Bloom keys
1 问题描述 在使用Spark BulkLoad数据到HBase时遇到以下问题: 17/05/19 14:47:26 WARN scheduler.TaskSetManager: Lost task ...
- ReentrantLock深入学习
ReentrankLock 分为 非公平锁及公平锁 首先我们看一下它里面有哪些属性: private final Sync sync;Sync 这个类是 ReentrantLock的 一个静态内部类 ...
- aws上redhat安装lmysql服务记
aws上redhat安装lmysql服务记 1.准备材料 1.1
- SparkMLlib学习之线性回归
SparkMLlib学习之线性回归 (一)回归的概念 1,回归与分类的区别 分类模型处理表示类别的离散变量,而回归模型则处理可以取任意实数的目标变量.但是二者基本的原则类似,都是通过确定一个模型,将输 ...
- tomcat产生大量TIME_WAIT连接
http://blog.csdn.net/jiangguilong2000/article/details/12523771
- SonarQube+Jenkins,搭建持续交付平台
前言 Kurt Bittner曾说过,如果敏捷仅仅只是开始,那持续交付就是头条! "If Agile Was the Opening Act, Continuous Delivery is ...
- sql 经典面试题
如果数据库里两个日期型字段d1,d2,怎样用sql语句列出按月的所有区间,比如表结构如下localid d1 d21 2014-1-15 2014-3- ...