linux内核中 关于内存相关的参数 缓存 写磁盘 /proc/sys/vm
在 linux 内核中有许多参数可以有用户进行配置。可以通过 sysctl -a 命令来查看。本文主要讲一些与内存相关的参数,关于内存相关的参数可以通过命令 sysctl -a | grep "vm\." 进行查看,其中各个参数在【官方文档】中也有详细描述。
1. /proc/sys/vm/
优化内核对 cache 和 dirty cache 的处理,主要是在这这个目录下。对于这个目录,官网是这样介绍的
This file contains the documentation for the sysctl files in /proc/sys/vm and is valid for Linux kernel version 2.6.29. The files in this directory can be used to tune the operation of the virtual memory (VM) subsystem of the Linux kernel and the writeout of dirty data to disk.
大概解释下就是如下:
在 sysctl 文件中配置的以 vm 开头的配置,存在这里面。对于Linux内核版本2.6.29+都是有效的。
此目录中的文件可用于调优 Linux 内核的虚拟内存(VM)子系统的操作和将 dirty data 写到磁盘。即缓存相关的参数。
2. 重要的修改项
写文件时,先写入内核的 cache 中,后台进程 pdflush 或 flush-n:m 负责异步将写操作 writeback 到磁盘。
注意:直接修改 echo 100 > /proc/sys/vm/min_free_kbytes 里面文件重启会失效 。还需要在 sysctl.conf 中修改 vm.min_free_kbytes = 100
centos7 弃用的参数
extra_free_kbytes
这个不是官网 kernel 自带的接口。centos7 已经弃用。
extra_free_kbytes 是 CentOS-6(kernel-2.6.32 导出的一个接口 ),该接口并未合入内核主线,它是 redhat 自己合入的一个patch。
在 CentOS-7(kernel-3.10) 上删除了该接口,转而使用dirty ratio来触发,因为直接回收耗时长的直接原因就是因为回收的时候会去回收dirty page,所以CentOS-7的这种做法更加合理一些
extra_free_kbytes在某种程度上也浪费了一些内存的使用。
手动释放缓存
drop_caches
更改 drop_caches 的值将导致内核丢弃clean caches,以及 reclaimable (可回收的) slab对象 (如 dentries 和 inode )。他们占用的内存将变成 free
To free pagecache: sync && echo 1 > /proc/sys/vm/drop_caches To free reclaimable slab objects (includes dentries and inodes): sync && echo 2 > /proc/sys/vm/drop_caches To free slab objects and pagecache: sync && echo 3 > /proc/sys/vm/drop_caches
这是一种非破坏性操作,不会释放任何 dirty objects。为了增加通过此操作释放的对象数量,用户可以在写入 /proc/sys/vm/drop_caches 之前运行 sync 。这将最大程度地减少系统上 dirty objects 的数量,释放更多的缓存。
该文件不是控制各种内核高速缓存(inodes,dentries,pagecache 等)增长的唯一方法,当系统上其他应用需要内存时,内核会自动回收这些对象。
使用此文件可能会导致性能问题。由于它丢弃了cached objects,因此重新创建被丢弃的objects可能会花费大量的 I/O 和 CPU,尤其是当它们使用过多时。所以在生产环境中谨慎使用。
page cache 策略 以下几个参数设定影响 dirty page 写入 disk 和其他回收策略
dirty_expire_centisecs
dirty_writeback_centisecs:默认值500,即5s ;单位厘秒 1s=100。这个进程 每隔一段时间 就被唤醒执行一次。他会检查这些 dirty page 脏页面 的时间是不是超时了,超时的话就会被写到磁盘。
dirty_writeback_centisecs
dirty_expire_centisecs:默认值3000,即30s;单位 厘秒。定义 dirty page 脏页面 的超时时间,这个只是写磁盘的一个标准。就算一个都没超时,但脏页面很多的话,也是会写磁盘的。这个下面会讲。
实验1:验证超时时间 dirty_writeback_centisecs
console 1
[root@tmp vm]# cat dirty_expire_centisecs 3000 [root@tmp vm]# echo 500 > dirty_expire_centisecs [root@tmp vm]# dd if=/dev/zero of=/tmp/wtest.txt bs=1M count=10 10+0 records in 10+0 records out 10485760 bytes (10 MB) copied, 0.00580514 s, 1.8 GB/s [root@tmp vm]# echo 700 > dirty_expire_centisecs [root@tmp vm]# dd if=/dev/zero of=/tmp/wtest2.txt bs=1M count=10 10+0 records in 10+0 records out 10485760 bytes (10 MB) copied, 0.00819349 s, 1.3 GB/s [root@tmp vm]# [root@tmp vm]#
console 2
[root@tmp ~]# cat while_check.sh #!/bin/bash while true do sleep 1 echo `date` `cat /proc/meminfo |grep -i dirty` done [root@tmp ~]# sh while_check.sh Wed Jan 15 17:45:00 CST 2020 Dirty: 16 kB Wed Jan 15 17:45:01 CST 2020 Dirty: 16 kB Wed Jan 15 17:45:02 CST 2020 Dirty: 16 kB Wed Jan 15 17:45:03 CST 2020 Dirty: 16 kB Wed Jan 15 17:45:04 CST 2020 Dirty: 10256 kB Wed Jan 15 17:45:05 CST 2020 Dirty: 10240 kB Wed Jan 15 17:45:06 CST 2020 Dirty: 10240 kB Wed Jan 15 17:45:07 CST 2020 Dirty: 10240 kB Wed Jan 15 17:45:08 CST 2020 Dirty: 10240 kB Wed Jan 15 17:45:22 CST 2020 Dirty: 0 kB Wed Jan 15 17:45:23 CST 2020 Dirty: 0 kB Wed Jan 15 17:45:24 CST 2020 Dirty: 0 kB Wed Jan 15 17:45:25 CST 2020 Dirty: 0 kB Wed Jan 15 17:45:26 CST 2020 Dirty: 10240 kB Wed Jan 15 17:45:27 CST 2020 Dirty: 10240 kB Wed Jan 15 17:45:28 CST 2020 Dirty: 10240 kB Wed Jan 15 17:45:29 CST 2020 Dirty: 10240 kB Wed Jan 15 17:45:30 CST 2020 Dirty: 10240 kB Wed Jan 15 17:45:31 CST 2020 Dirty: 10240 kB Wed Jan 15 17:45:32 CST 2020 Dirty: 10260 kB Wed Jan 15 17:45:33 CST 2020 Dirty: 10260 kB Wed Jan 15 17:45:34 CST 2020 Dirty: 10260 kB Wed Jan 15 17:45:35 CST 2020 Dirty: 10260 kB Wed Jan 15 17:45:36 CST 2020 Dirty: 20 kB Wed Jan 15 17:45:37 CST 2020 Dirty: 20 kB Wed Jan 15 17:45:38 CST 2020 Dirty: 20 kB
假如:超时时间 n,检测频率为 m; dirty data 被写入磁盘的时间为 x ,
那么: n <= x <= n+m
dirty_background_bytes 和 dirty_background_ratio
vm.dirty_background_bytes = 0
vm.dirty_background_ratio = 10
当 dirty_background_bytes 为 0 时,则 dirty_background_ratio 生效,否则 dirty_background_bytes 生效。
dirty_background_bytes : 这里不提,我们设定为 0 ,只修改百分比,提高通用性。
dirty_background_ratio :当 dirty pages / available memory (free pages + reclaimable pages 即 可回收page ) 的百分比达到设定阈值,启动相关内核线程 ( pdflush/flush/kdmflush ) 开始将脏页写入磁盘。如果该值过大,同时又有进程大量写磁盘(未使用DIRECT_IO)时,会使 pagecache 占用对应比例的系统内存。
dirty_bytes 和 dirty_ratio
vm.dirty_bytes = 0
vm.dirty_ratio = 20
当 dirty_bytes 为 0 时,则 dirty_ratio 生效,否则 dirty_bytes 生效。
dirty_bytes : 这里不提,我们设定为 0 ,只修改百分比,提高通用性。
dirty_ratio : 当 dirty pages / available memory (free pages + reclaimable pages 即 可回收page ) 的百分比达到设定阈值, 系统就会阻塞新的写请求,直到脏页被回写到磁盘。此值过低时,遇到写入突增时,会造成短时间内pagecache脏页快速上升,造成写请求耗时增加。但是此值也不能设置的太高,当该值太高时,会造成内核flush脏页时,超过内核限制的120s导致进程挂起或中断。
min_free_kbytes
vm.min_free_kbytes = 90112
一般不用调整这个参数。这个参数用来指定强制Linux VM保留的内存区域的最小值,单位是kb。VM会使用这个参数的值来计算系统中每个低端内存域的watermark[WMARK_MIN]值。每个低端内存域都会根据这个参数保留一定数量的空闲内存页。
避免内核,在紧急时刻/内部逻辑分配不出内存而导致死锁等问题。也不可调的过高,否则容易导致系统判定内存不足而出发OOM逻辑。
vfs_cache_pressure
vm.vfs_cache_pressure = 100
该文件表示内核回收用于 directory 和 inode cache 内存的倾向。
缺省值100 表示内核将根据 pagecache 和 swapcache ,把 directory 和 inode cache 保持在一个合理的百分比;降低该值低于100,将导致内核倾向于保留 directory 和 inode cache;增加该值超过 100,将导致内核倾向于回收 directory 和 inode cache。
当 vfs_cache_pressure = 0时,内核将永远不会由于内存压力而回收 dentries and inodes,这很容易导致内存不足引起 OOM。
在 vfs_cache_pressure = 1000 的情况下,它会寻找比可用对象多十倍的可释放对象。
OOM
oom_dump_tasks
vm.oom_dump_tasks = 1
启动 OOM 信息打印
当 OOM-KILLER 启动时,将会将各进程的 pid, uid, tgid, vm size, rss, pgtables_bytes, swapents, oom_score_adj, 名称等信息打印到 dmesg 里,管理员事后可以在 dmesg 信息中查看,定位问题。
oom_kill_allocating_task
vm.oom_kill_allocating_task = 0
控制是否杀死触发OOM的进程。
设置为 0 时,OOM-KILLER会扫描进程列表,选择一个进程来杀死。通常都会选择消耗内存最多的进程,杀死这样的进程后可以释放大量的内存。
设置为非 0 时,OOM-KILLER,只会简单地将触发OOM的进程杀死,避免遍历进程列表,减少了决策开销。
为了避免特殊的进程被 OOM-KILLER 干掉,可以修改 echo -1000 > /proc/$pid/oom_score_adj,禁止 OOM-KILLER 杀掉该进程
共 0 条评论