psy*_*ca0 5 linux performance io performance-tuning linux-kernel
我已经研究了一段时间了,但事情并不符合我的期望,但我不知道是因为有什么不对,还是我的期望是错误的。
所以,我有一个内存超过 100GB 的系统,我将我的内存设置dirty_background_bytes
为 9663676416(9GB)和dirty_bytes
两倍(19327352832 或 18GB)
在我看来,这应该让我最多可以将 9GB 写入文件,但实际上它只是位于内存中,不需要访问磁盘。Mydirty_expire_centisecs
是默认值3000
(30 秒)。
所以当我运行时:
# dd if=/dev/zero of=/data/disk_test bs=1M count=2000
Run Code Online (Sandbox Code Playgroud)
并跑了:
# while sleep 5; do egrep 'Dirty|Writeback' /proc/meminfo | awk '{print $2;}' | xargs; done
Run Code Online (Sandbox Code Playgroud)
(以 kb 为单位打印脏字节,以 kb 为单位打印回写,在 5 秒快照时以 kb 为单位打印 WritebackTmp)
我本来希望看到它转储 2GB 到页面缓存中,在那里等待 30 秒,然后开始将数据写入磁盘(因为它从未超过 9GB 背景比率)
相反,我看到的是:
3716 0 0
4948 0 0
3536 0 0
1801912 18492 0
558664 31860 0
7244 0 0
8404 0 0
Run Code Online (Sandbox Code Playgroud)
一旦页面缓存跳转,它就已经在写数据,直到我们回到我们开始的地方。
我实际上正在做的工作基本上是想看看我的进程瓶颈是磁盘 IO 还是其他一些因素,但在中间我被这种行为弄糊涂了。我认为只要进程仍在缓冲区中运行,磁盘写入性能就不应该真正相关,因为它应该只是转储到内存中。
那么,我是否误解了这些功能应该工作的方式,还是发生了一些奇怪的事情?
dd
这可能是命令在每次迭代时取消链接并创建新的 disk_test的副作用。
尝试首先使用单个dd if=/dev/zero of=/data/disk_test bs=1M count=2000
命令创建目标文件,然后使用命令运行循环dd if=/dev/zero of=/data/disk_test bs=1M count=2000 conv=notrunc,nocreat
。
解释: notrunc
有所作为,因为在过去添加了一些启发式方法来防止应用程序执行replace-via-rename和replace-via-truncate并随后崩溃以损坏其数据。这种启发式基本上强制刷新属于打开->写入->截断文件的数据。
从安装手册页:
auto_da_alloc|noauto_da_alloc
当 noauto_da_alloc 通过以下模式替换现有文件时,许多损坏的应用程序不使用 fsync()
fd = open("foo.new")/write(fd,..)/close(fd)/ 重命名("foo.new", "foo")
或者更糟
fd = 打开(“foo”,O_TRUNC)/写入(fd,..)/关闭(fd)。
如果启用了auto_da_alloc,ext4将检测replace-via-rename和replace-via-truncate模式,并强制分配任何延迟的分配块,以便在下一次日志提交时,在默认的data=ordered模式下,在提交 rename() 操作之前,新文件将被强制写入磁盘。这提供了与 ext3 大致相同级别的保证,并避免了在延迟分配块被强制写入磁盘之前系统崩溃时可能发生的“零长度”问题。
还可以查看XFS 常见问题解答
归档时间: |
|
查看次数: |
529 次 |
最近记录: |