因最近项目需要,动手测试Flume的TailDir Source读取效率,然后遇到一个很奇怪的问题。
同时进行读写文件的效率比单独写文件高?
写进程:使用Files.readAllLines()将源文件数据读取后,使用Files.write()逐条写入Flume监控目录下的文件中。
读进程:Flume的TailDir Source负责读取数据,当文件中写入新数据时,将新写入的数据读取并输出至Flume的log文件。
环境:win7,TailDir无法在windows环境下使用的问题按照http://blog.csdn.net/u012373815/article/details/62238079
这位前辈的方法修改后能争产使用。
当单独运行写进程时,平均耗时6600ms。
当两进程同时运行时,平均耗时5400ms。
通过查看日志以及写进程输出的时间,发现写进程开始1s左右,读进程开始读文件。写进程结束1s内,读进程完成所有数据读取。从日志记录来看,可以确认数据写入和读取都是正常的。那么为什么两个进程比一个进程快呢?
1 package t1; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.io.UnsupportedEncodingException; 6 import java.nio.file.Files; 7 import java.nio.file.StandardOpenOption; 8 import java.util.Date; 9 import java.util.Iterator; 10 import java.util.List; 11 12 13 public class TestWriteFile { 14 public static void main(String[] args){ 15 File f=new File("E:/Flume/Test/data/msg-TestFile.log"); 16 List<String> list = null; 17 try { 18 if(f.exists()){ 19 f.delete(); 20 } 21 f.createNewFile(); 22 File f2=new File("E:/Flume/Test/msg-TestFile.log"); 23 list = Files.readAllLines(f2.toPath()); 24 } catch (IOException e) { 25 e.printStackTrace(); 26 } 27 Iterator it=list.iterator(); 28 long start=System.currentTimeMillis(); 29 System.out.println(new Date(start)); 30 while(it.hasNext()){ 31 try { 32 Files.write(f.toPath(),String.valueOf(it.next()+"\n").getBytes("UTF-8"),StandardOpenOption.APPEND); 33 } catch (UnsupportedEncodingException e) { 34 e.printStackTrace(); 35 } catch (IOException e) { 36 e.printStackTrace(); 37 } 38 } 39 long end=System.currentTimeMillis(); 40 System.out.println(new Date(end)); 41 System.out.println(end-start); 42 } 43 }
你的读写速度跟硬盘读写速度不是一个概念。
硬盘并不是大规模并行写入设备,底层都是以队列的模式向上层提供的接口功能,而且是按块的。
你可以设想一下你创建一个文件(相当于硬盘),然后向外提供接口 —— 由于支持并发,你要保证你的数据次序,你能同时seek(磁头能同时写到两个地方)吗