sysctl 之内存释放及磁盘优化

Cache

文件缓存是提升性能的重要手段。毋庸置疑,读缓存(Read caching)在绝大多数情况下是有益无害的(程序可以直接从RAM中读取数据),而写缓存(Write caching)则相对复杂。Linux内核将写磁盘的操作分解成了,先写缓存,每隔一段时间再异步地将缓存写入磁盘。这提升了IO读写的速度,但存在一定风险。数据没有及时写入磁盘,所以存在数据丢失的风险。

同样,也存在cache被写爆的情况。还可能出现一次性往磁盘写入过多数据,以致使系统卡顿。之所以卡顿,是因为系统认为,缓存太大用异步的方式来不及把它们都写进磁盘,于是切换到同步的方式写入。(异步,即写入的同时进程能正常运行;同步,即写完之前其他进程不能工作)。

/etc/sysctl.conf 用于控制内核相关的配置参数,而且它的内容全部是对应于 /proc/sys/ 这个目录的子目录及文件

系统配置相关文件

[root@MongoDB ~]# ll /proc/sys
total 0
dr-xr-xr-x 1 root root 0 Apr 18 01:21 abi // 应用的二进制信息
dr-xr-xr-x 1 root root 0 Apr 17 03:56 crypto // 调试相关的系统配置目录
dr-xr-xr-x 1 root root 0 Apr 18 01:21 debug // 设备相关的系统配置目录
dr-xr-xr-x 1 root root 0 Apr 18 01:21 dev    // 文件系统相关的系统配置目录
dr-xr-xr-x 1 root root 0 Apr 17 03:44 fs  // 文件系统相关的系统配置目录
dr-xr-xr-x 1 root root 0 Apr 17 03:44 kernel // 内核相关的系统配置目录
dr-xr-xr-x 1 root root 0 Apr 17 03:44 net // 网络相关的系统配置目录
dr-xr-xr-x 1 root root 0 Apr 18 01:21 user // 用户相关的系统配置目录
dr-xr-xr-x 1 root root 0 Apr 17 03:46 vm // 内存相关的系统配置目录

sysctl.conf 文件内容与内存相关参数说明

vm.overcommit_memory = 0内存分配策略,可选0 1 2
0,表示内存将检查是否有足够的可用内存供应用进程使用,如果有,允许申请,否则,内存申请失败,将错误返回给应用进程
1,表示内存允许分配所有的物理内存,而不管当前的内存状态如何
2,表示内存允许分配所有的物理内存和交换空间所有的内存

//内存相关配置参数
vm.vfs_cache_pressure = 300
vm.dirty_background_bytes = 0
vm.dirty_background_ratio = 10
vm.dirty_bytes = 0
vm.dirty_ratio = 20
vm.dirty_writeback_centisecs = 500
vm.dirty_expire_centisecs = 3000
vm.dirtytime_expire_seconds = 43200
vm.zone_reclaim_mode = 1
参数解释:

vm.vfs_cache_pressure
控制内核回收directory和inode的回收速率,当降低该值会使得内核保留dentry和inode caches,当vfs_cache_pressure=0时,内核不会回收dentry和inode caches,这种情况下可能会导致内存泄漏。增加该值可能会影响系统性能,但会加快回收dentry和inode caches,可以通过slabtop命令查看dentry/inode caches的数值
vm.dirty_background_ratio
是内存可以填充脏数据的百分比。这些脏数据稍后会写入磁盘,pdflush/flush/kdmflush这些后台进程会稍后清理脏数据。比如,我有32G内存,那么有3.2G的脏数据可以待着内存里,超过3.2G的话就会有后台进程来清理。
vm.dirty_ratio
是可以用脏数据填充的绝对最大系统内存量,当系统到达此点时,必须将所有脏数据提交到磁盘,同时所有新的I/O块都会被阻塞,直到脏数据被写入磁盘(脏数据小于dirty_ratio)。这通常是长I/O卡顿的原因,但这也是保证内存中不会存在过量脏数据的保护机制。
vm.dirty_background_bytesvm.dirty_bytes
是另一种指定这些参数的方法。如果设置_bytes版本,则_ratio版本将变为0,反之亦然。
vm.dirty_writeback_centisecs
指定多长时间 pdflush/flush/kdmflush 这些进程会唤醒一次,然后检查是否有缓存需要清理。控制周期回写进程的唤醒时间,默认值为500,单位是厘秒,实际内核中是*10使用,即5s,也就是每隔5秒唤醒脏页回写进程,降低这个值可以把尖峰的写操作削平成多次写操作。
vm.dirty_expire_centisecs
指定脏数据能存活的时间。在这里它的值是30秒。当 pdflush/flush/kdmflush 在运行的时候,他们会检查是否有数据超过这个时限,如果有则会把它异步地写到磁盘中。毕竟数据在内存里待太久也会有丢失风险。
vm.zone_reclaim_mode=1
开启当内存不够用时就直接回收内存

Linux下有个内核参数overcommit_memory,是内存分配策略,程序在启动的时候会先去申请内存,尽管不一定都会用的到那么多。
overcommit_memory此参数决定是否接受超大内存请求的条件。这个参数有三个可能的值:
0 — 默认设置。内核执行启发式内存过量使用处理,方法是估算可用内存量,并拒绝明显无效的请求。遗憾的是因为内存是使用启发式而非准确算法计算进行部署,这个设置有时可能会造成系统中的可用内存超载。
1 — 内核执行无内存过量使用处理。使用这个设置会增大内存超载的可能性,但也可以增强大量使用内存任务的性能。
2 — 内存拒绝等于或者大于总可用 swap 大小以及overcommit_ratio指定的物理RAM比例的内存请求。如果您希望减小内存过度使用的风险,这个设置就是最好的。

通俗理解:
0:内核将检查是否有足够的内存分配给程序。如果没有则申请失败,并把错误返回给应用进程。而在Redis中这个错误就会表现为“Cannot allocate memory”,然后触发OOM
1:表示内核允许超量使用内存直到用完为止
2:表示内核决不超量使用内存,即系统整个内存空间不能超过swap+50%的RAM值,50%是overcommit_ratio默认值,此参数支持修改

说明:
1.提交background回写work
如果没有设置/proc/sys/vm/dirty_bytes和/proc/sys/vm/dirty_background_bytes,统计空闲页和可回收页面之后,并扣除min_free_kbytes以及系统保留内存;
如何设置了/proc/sys/vm/dirty_bytes,则按dirty_bytes计算脏页阈值,否则使用vm_dirty_ratio计算脏页阈值,默认值20%;
如何设置了/proc/sys/vm/dirty_background_bytes,则按其计算background脏页阈值,否则使用dirty_background_ratio计算background脏页阈值,默认值10%;
background脏页阈值不能大于脏页阈值,也就是background回写要早于进程主动刷脏页;
2.执行background回写work
实际执行background回写时需要再次做一次判断,因为background回写优先级比较低,其他work上可能已经回写了部分脏页,有可能此时已经低于阈值;
3.显式回写
background回写对于进程是无法感知的,但是如果脏页过多,来不及处理,内存消耗过快,此时在进程运行时就出现了内存不足,这是就需要显式的触发脏页回写,并阻塞等待内存释放后,进程才能进一步运行。这种情况主要是在write操作过程中出现

脏数据在内存停留条件为:
a:dirty_expire_centisecs时间以内
b:脏数据没有超过dirty_background_ratio阈值

sysctl 命令

sysctl 命令被用于在内核运行时动态地修改内核的运行参数,可用的内核参数在目录“/proc/sys”中

sysctl [-n] [-e] -w variable=value
sysctl [-n] [-e] -p (default /etc/sysctl.conf)
sysctl [-n] [-e] -a
常用参数的意义:
-w 临时改变某个指定参数的值,如
sysctl -w net.ipv4.ip_forward=1
-a 显示所有的系统参数
-p 从指定的文件加载系统参数,如不指定即从/etc/sysctl.conf中加载

如果仅仅是想临时改变某个系统参数的值,可以用两种方法来实现,例如想启用IP路由转发功能:
1) #echo 1 > /proc/sys/net/ipv4/ip_forward
2) #sysctl -w net.ipv4.ip_forward=1
以上两种方法都可能立即开启路由功能,但如果系统重启,或执行了
# service network restart
命令,所设置的值即会丢失,如果想永久保留配置,可以修改/etc/sysctl.conf文件
将 net.ipv4.ip_forward=0改为net.ipv4.ip_forward=1

free 命令

显示当前系统中的内存使用和空闲情况,也可以显示被内核占用的内存缓冲区
在这里插入图片描述
列1:total:物理内存的总大小
列2:used:被使用的大小
列3:free:可用内存空闲内存大小
列4:shared:被多个进程共享的内存
列5:buffer/cached:磁盘缓存的大小
列6:available:还可以被进程使用的物理内存大小

cache和buffer详解

buffer 和 cache 应该是两种类型的内存,但是 free 命令为什么会把它们放在一起呢?要回答这个问题需要我们做些准备工作。让我们先来搞清楚 buffer 与 cache 的含义。

buffer 在操作系统中指 buffer cache, 中文一般翻译为 “缓冲区”。要理解缓冲区,必须明确另外两个概念:“扇区” 和 “块”。扇区是设备的最小寻址单元,也叫 “硬扇区” 或 “设备块”。块是操作系统中文件系统的最小寻址单元,也叫 “文件块” 或 “I/O 块”。每个块包含一个或多个扇区,但大小不能超过一个页面,所以一个页可以容纳一个或多个内存中的块。当一个块被调入内存时,它要存储在一个缓冲区中。每个缓冲区与一个块对应,它相当于是磁盘块在内存中的表示:

buffer cache 只有块的概念而没有文件的概念,它只是把磁盘上的块直接搬到内存中而不关心块中究竟存放的是什么格式的文件。

cache 在操作系统中指 page cache,中文一般翻译为 “页高速缓存”。它主要用来减少对磁盘的 I/O 操作。是通过把磁盘中的数据缓存到物理内存中,把对磁盘的访问变为对物理内存的访问。页高速缓存缓存的是内存页面。缓存中的页来自对普通文件、块设备文件(这个指的就是 buffer cache 呀)和内存映射文件的读写。

页高速缓存对普通文件的缓存:当内核要读一个文件(比如 /etc/hosts)时,它会先检查这个文件的数据是不是已经在页高速缓存中了。如果在,就放弃访问磁盘,直接从内存中读取。这个行为称为缓存命中。如果数据不在缓存中,就是未命中缓存,此时内核就要调度块 I/O 操作从磁盘去读取数据。然后内核将读来的数据放入页高速缓存中。这种缓存的目标是文件系统可以识别的文件(比如 /etc/hosts)。

页高速缓存对块设备文件的缓存就是我们在前面介绍的 buffer cahce。因为独立的磁盘块通过缓冲区也被存入了页高速缓存(缓冲区最终是由页高速缓存来承载的)。

参考链接
原文链接:https://blog.csdn.net/baidu_20608025/article/details/105012723
原文链接:https://blog.csdn.net/longwang155069/article/details/50897026

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值