0%

Linux kernel vm pagecache 配置优化项

通过配置优化文件读写性能

dirty_background_bytes & dirty_background_ratio

  1. 当系统脏页的比例超过 dirty_background_ratio 或者所占内存数量超过 dirty_background_bytes 设定的阈值时,启动相关内核线程 pdflush/flush/kdmflush 开始将脏页写入磁盘。
  2. 如果该值过大,同时又有进程大量未使用 DIRECT_IO 写磁盘时,会使 pagecache 占用对应比例的系统内存
  3. 两个参数是相对的,只能指定其中一个。当其中一个参数文件被写入时,会立即开始计算脏页限制,并且会将另一个参数的值清零
  4. 是内存可以填充脏数据的百分比
# 字节
vm.dirty_background_bytes = 0
# 百分比
vm.dirty_background_ratio = 10

dirty_bytes & dirty_ratio

  1. 当系统脏页达到系统内存 dirty_bytes / dirty_ratio 阈值时,系统就会阻塞新的写请求,直到脏页被回写到磁盘
  2. 此值过低时,遇到写入突增时,会造成短时间内 pagecache 脏页快速上升,造成写请求耗时增加
  3. 当该值太高时,会造成内核 flush 脏页时,超过内核限制的 120s 导致进程挂起或中断
  4. 两个参数是相对的,只能指定其中一个。当其中一个参数文件被写入时,会立即开始计算脏页限制,并且会将另一个参数的值清零
  5. 是可以用脏数据填充的绝对最大系统内存量
  6. 是保证内存中不会存在过量脏数据的保护机制
vm.dirty_bytes = 0
vm.dirty_ratio = 20

dirty_expire_centisecs

  1. 指定脏数据能存活的时间。在这里它的值是 30 秒。当 pdflush/flush/kdmflush 在运行的时候,他们会检查是否有数据超过这个时限,如果有则会把它异步地写到磁盘中
  2. 当该值太小时,会造成 IO 提高过多
# 1/100s
vm.dirty_expire_centisecs = 3000

dirty_writeback_centisecs

  1. 指定多长时间 pdflush/flush/kdmflush 这些进程会唤醒一次,然后检查是否有缓存需要清理
  2. 如果设置为 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 调度

linux I/O优化 磁盘读写参数设置

  • /sys/block/sdX/queue/scheduler
  • /sys/block/sdX/queue/nr_requests
  • /sys/block/sdX/queue/read_ahead_kb