我正在研究一个servlet,它确实在HTTP POST多部分消息中接收附件。这些文件必须存储到挂载的文件系统中。 这一切都运行良好,只是性能不是我根据我在文件系统上运行的 IO 测试所期望的。
在我的机器上,我有 2 个文件系统,一个本地文件系统 FSA 和一个托管在另一台主机上的 CIFS 文件系统 FSB。FSB 必须在上线时使用,FSA i 用于比较 FSB 的性能。当我使用以下命令测试文件系统的吞吐量和延迟时;
通dd if=/dev/zero of=$FS/test.img bs=1G count=1 oflag=dsync
延迟dd if=/dev/zero of=$FS/test.img bs=512 count=1000 oflag=dsync
我确实得到了以下读数;
- FSA 吞吐量 844MB/秒,延迟 590MB/秒
- 前端总线吞吐量 50,4MB/s,延迟 116KB/s
为了将文件保存到磁盘,我确实使用了org.apache.commons.io.FileUtils的copInputStreamToFile方法。不可能使用JDK7及更高版本,因此java.nio是没有选择的。
// Register starttime of FileIO
startTime = System.currentTimeMillis();
// Fastest way to write stream to file
FileUtils.copyInputStreamToFile(formFieldStream, newFile);
LOG.info(String.format("[Session: %s] [Operation: maakaan io] [File: %s] [%s ms]",
sessionID, fileNaam,
(System.currentTimeMillis() - startTime)));
当使用此 servlet 将 110MB 的文件保存到 FSA 时,大约需要 10 秒,在 FSB 上大约需要 13 秒。因此,选择的文件系统会有所不同,但写入速度的差异与测量的吞吐量差异并不对应。当使用指定的文件系统 FSB 时,从 Java 代码写入文件的速度约为 10MB/s,仍然比直接使用 dd 写入文件要慢得多。由于我在测试中使用了一个大文件,所以我选择使用文件系统的测量吞吐量。
是否有任何选项可以提高此 servlet 的写入速度,或者如何确定导致"迟钝"的原因
干杯 彼得
== 更新 1 ==
在FileUtils.copyInputStreamToFile和org.apache.commons.fileupload的实现中似乎有一个4K的缓冲区。在分析飞行记录(JRockit)时,我也可以看到这一点。我已经能够增加写入缓冲区。现在正在努力查看我是否可以解决文件加载器中的缓冲区。
使用虚拟源代码在文件系统上运行的 I/O 测试 无关紧要。这里的限制因素是网络,它比文件系统、CPU、Java 或IOUtils
慢几个数量级。