【发布时间】:2023-03-11 12:52:03
【问题描述】:
我使用 FileChannel 编写了一个程序来测试 java 中的 IO 性能。立即写入数据并调用 force(false)。我的Linux服务器有12个ssd硬盘,sda~sdl,我测试写数据到不同的硬盘,性能差别很大,不知道为什么?
代码:
public static void main(String[] args) throws IOException, InterruptedException {
RandomAccessFile aFile = new RandomAccessFile(args[0], "rw");
int count = Integer.parseInt(args[1]);
int idx = count;
FileChannel channel = aFile.getChannel();
long time = 0;
long bytes = 0;
while (--idx > 0) {
String newData = "New String to write to file..." + System.currentTimeMillis();
String buff = "";
for (int i = 0 ; i<100; i++) {
buff += newData;
}
bytes += buff.length();
ByteBuffer buf = ByteBuffer.allocate(buff.length());
buf.clear();
buf.put(buff.getBytes());
buf.flip();
while(buf.hasRemaining()) {
channel.write(buf);
}
long st = System.nanoTime();
channel.force(false);
long et = System.nanoTime();
System.out.println("force time : " + (et - st));
time += (et -st);
}
System.out.println("wirte " + count + " record, " + bytes + " bytes, force avg time : " + time/count);
}
结果如下:
sda:写入 1000000 条记录,4299995700 字节,强制平均时间:273480 ns
sdb:写入 100000 条记录,429995700 字节,强制平均时间:5868387 ns
平均时间差异很大。
这是一些 IO 监控数据。
数据:
iostat data image
数据库:
iostat data image
【问题讨论】:
-
你能澄清你认为的问题吗?似乎没有足够的信息来得出任何结论。 0.005 秒的变化对于磁盘 IO 来说意义不大,除非它是高度可重现的。我假设驱动器都是一样的,除了
sda也有操作系统? -
注意:当您写入文件进行基准测试时,您不需要创建虚拟数据(除非数据将被压缩)一个充满零字节的文件与包含随机的文件相同数据。
-
所有这些磁盘是否是同一控制器上相同型号的驱动器和相同的文件系统类型?顺便说一句,对于 SSD 来说,即使 72 MB/s 听起来也不是很高。我会寻找 400 - 500 MB/s
-
我会首先编写超过 4 KB 的块,例如256 KB 或 2 MB。
-
所有硬盘都是同一型号,ext3文件系统,不知道为什么sda的强制延迟低很多。
标签: java linux performance io