我的应用程序正在使用O_DIRECT将2MB的数据直接刷新到3路条带存储(安装为lvm卷)。
我在这个存储上的写入速度非常可怜。 iostat显示大型请求大小被分解为较小的请求大小。
avgrq-sz
< 20 ...该驱动器读取的内容不多。
需要大约2秒来清除2MB的连续内存块(使用mlock
确保),扇区对齐(使用posix_memalign
),而使用dd
和{进行测试{1}}对存储能力进行评分>写入速度为20Mbps。
我很感激有关如何进一步调查此问题的任何线索。
PS:如果这不是这个查询的正确论坛,我会很感激指示一个可能有用的指标。
感谢。
答案 0 :(得分:0)
在Linux上写IO分手吗?
磁盘本身可能具有最大的请求大小,需要权衡块大小和延迟(发送到磁盘的请求越大,消耗的时间就越长),并且可以{{3 }}。鉴于以上所有内容,内核将进一步分解在向下提交堆栈时太大的单个请求。
对于任何可以进一步调查此问题的线索,我将不胜感激。
不幸的是,很难说avgrq-sz
为何这么小(如果它的扇区中每个I / O大约10KByte)而没有看到代码实际提交I / O(也许您的程序正在提交10KB缓冲区)? )。我们也不清楚在提问者测试中iozone
和dd
是否使用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
}
或通过多个进程/线程)达到最大的吞吐量,因为您已经剥夺了内核为您创建向设备并行提交的最佳方法。