在linux上写IO分手?

时间:2011-04-22 21:35:46

标签: linux performance linux-kernel iostat

我的应用程序正在使用O_DIRECT将2MB的数据直接刷新到3路条带存储(安装为lvm卷)。

我在这个存储上的写入速度非常可怜。 iostat显示大型请求大小被分解为较小的请求大小。

avgrq-sz< 20 ...该驱动器读取的内容不多。

需要大约2秒来清除2MB的连续内存块(使用mlock确保),扇区对齐(使用posix_memalign),而使用dd和{进行测试{1}}对存储能力进行评分>写入速度为20Mbps。

我很感激有关如何进一步调查此问题的任何线索。

PS:如果这不是这个查询的正确论坛,我会很感激指示一个可能有用的指标。​​

感谢。

1 个答案:

答案 0 :(得分:0)

  

在Linux上写IO分手吗?

磁盘本身可能具有最大的请求大小,需要权衡块大小和延迟(发送到磁盘的请求越大,消耗的时间就越长),并且可以{{3 }}。鉴于以上所有内容,内核将进一步分解在向下提交堆栈时太大的单个请求。

  

对于任何可以进一步调查此问题的线索,我将不胜感激。

不幸的是,很难说avgrq-sz为何这么小(如果它的扇区中每个I / O大约10KByte)而没有看到代码实际提交I / O(也许您的程序正在提交10KB缓冲区)? )。我们也不清楚在提问者测试中iozonedd是否使用O_DIRECT。如果不是这样,那么他们的I / O就会进入回写缓存,然后再流出来,内核可以以更优化的方式做到这一点。

注意:使用O_DIRECT并不是走得更快的条纹。在constraints on how much vectored I/O a driver can consume in a single request中,如果愿意,O_DIRECT编写磁盘io_uring会增加您并行提交I / O的压力(例如,通过AIO / static private async Task addMeeting(string subject, int roomId,bool coffee, bool receptionist, bool valetParking, string deductedFrom, string program) { await GetToken(); //some code with await } static async Task<string> GetToken() { //some code with await } 或通过多个进程/线程)达到最大的吞吐量,因为您已经剥夺了内核为您创建向设备并行提交的最佳方法。