通过配置优化文件读写性能
dirty_background_bytes & dirty_background_ratio
- 当系统脏页的比例超过
dirty_background_ratio
或者所占内存数量超过dirty_background_bytes
设定的阈值时,启动相关内核线程pdflush/flush/kdmflush
开始将脏页写入磁盘。 - 如果该值过大,同时又有进程大量未使用
DIRECT_IO
写磁盘时,会使 pagecache 占用对应比例的系统内存 - 两个参数是相对的,只能指定其中一个。当其中一个参数文件被写入时,会立即开始计算脏页限制,并且会将另一个参数的值清零
- 是内存可以填充脏数据的百分比
# 字节
vm.dirty_background_bytes = 0
# 百分比
vm.dirty_background_ratio = 10
dirty_bytes & dirty_ratio
- 当系统脏页达到系统内存
dirty_bytes
/dirty_ratio
阈值时,系统就会阻塞新的写请求,直到脏页被回写到磁盘 - 此值过低时,遇到写入突增时,会造成短时间内 pagecache 脏页快速上升,造成写请求耗时增加
- 当该值太高时,会造成内核 flush 脏页时,超过内核限制的 120s 导致进程挂起或中断
- 两个参数是相对的,只能指定其中一个。当其中一个参数文件被写入时,会立即开始计算脏页限制,并且会将另一个参数的值清零
- 是可以用脏数据填充的绝对最大系统内存量
- 是保证内存中不会存在过量脏数据的保护机制
vm.dirty_bytes = 0
vm.dirty_ratio = 20
dirty_expire_centisecs
- 指定脏数据能存活的时间。在这里它的值是 30 秒。当
pdflush/flush/kdmflush
在运行的时候,他们会检查是否有数据超过这个时限,如果有则会把它异步地写到磁盘中 - 当该值太小时,会造成 IO 提高过多
# 1/100s
vm.dirty_expire_centisecs = 3000
dirty_writeback_centisecs
- 指定多长时间
pdflush/flush/kdmflush
这些进程会唤醒一次,然后检查是否有缓存需要清理 - 如果设置为 0,则禁止周期性地唤醒回写线程
# 1/100s
vm.dirty_writeback_centisecs = 100
vfs_cache_pressure
drop_caches
查看相关信息
- sysctl
$ sysctl -a | grep dirty vm.dirty_background_bytes = 0 vm.dirty_background_ratio = 10 vm.dirty_bytes = 0 vm.dirty_expire_centisecs = 3000 vm.dirty_ratio = 20 vm.dirty_writeback_centisecs = 500 vm.dirtytime_expire_seconds = 43200
- vmstat
$ cat /proc/vmstat | egrep "dirty|writeback" nr_dirty 103 nr_writeback 0 nr_writeback_temp 0 nr_dirty_threshold 83638 nr_dirty_background_threshold 41768
优化配置
减少缓存
快速的磁盘子系统,减少数据丢失风险
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10
增加缓存
数据不是关键的,可丢失,允许存在更多的脏页
vm.dirty_background_ratio = 50
vm.dirty_ratio = 80
增减都用
应对突发数据高峰,允许大量 IO 存储在缓存中,后台慢慢异步刷新
vm.dirty_background_ratio = 5
vm.dirty_ratio = 80
系统后台进程在脏数据达到 5% 时就开始异步清理,但在 80% 之前系统不会强制同步写磁盘
IO 调度
/sys/block/sdX/queue/scheduler
/sys/block/sdX/queue/nr_requests
/sys/block/sdX/queue/read_ahead_kb