我正在尝试从 java 程序创建 300M 文件,我从旧文件 API 切换到新的 java 7 nio 包,但新包的运行速度比旧包还要慢。
我发现 CPU 使用率比使用旧文件 API 时要少,但我正在运行这个简单的代码,我得到 0.5Mbytes/sec 的文件传输速率,并且来自 java 的写入正在读取一个磁盘并写入另一个(写入是访问磁盘的唯一进程)。
Files.write(FileSystems.getDefault().getPath(filePath), fiveToTenKBytes, StandardOpenOption.CREATE);
有没有希望在这里获得合理的吞吐量?
更新:
我正在从大文件中解压缩 3 亿个 5-10k 字节的图像文件。我有 3 个磁盘,1 个本地磁盘和 2 个 SAN 连接(大文件的典型吞吐率约为 20MB/秒)。
我还尝试了这段代码,它将速度提高到几乎不低于 2MB/秒的吞吐量(解压这些文件需要 9 天)。
ByteBuffer byteBuffer = ByteBuffer.wrap(imageBinary, 0, (BytesWritable)value).getLength());
FileOutputStream fos = new FileOutputStream( imageFile );
fos.getChannel().write(byteBuffer);
fos.close();
我从本地磁盘读取并写入 SAN 附加磁盘。我正在读取 Hadoop SequenceFile 格式,hadoop 通常能够使用基本相同的代码以 20MB/秒的速度读取这些文件。
除了超级慢之外,唯一看起来不合适的是,我看到读取 IO 比写入 IO 多大约 2:1,尽管序列文件是 gzip 压缩的(尽管图像实际上得到了 1:1 的比例),所以压缩文件应该是大约。1:1 与输出。
第二次更新
看着iostat
我看到一些奇数,我们在这里查看 xvdf,我有一个 java 进程读取xvdb
和写入,xvdf
并且没有其他进程处于活动状态xvdf
iostat -d 30
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
xvdap1 1.37 5.60 4.13 168 124
xvdb 14.80 620.00 0.00 18600 0
xvdap3 0.00 0.00 0.00 0 0
xvdf 668.50 2638.40 282.27 79152 8468
xvdg 1052.70 3751.87 2315.47 112556 69464
读取xvdf
是写入的 10 倍,这令人难以置信。
fstab
/dev/xvdf /mnt/ebs1 auto defaults,noatime,nodiratime 0 0
/dev/xvdg /mnt/ebs2 auto defaults,noatime,nodiratime 0 0