内存、IO、网络优化(2)
时间:2020-04-17 14:13 来源:潇湘夜雨 作者:华嵩阳 点击:次
使用buffer cache缓存文件元数据据;
使用page cache缓存DISK IO;
使用shm完成进程间通信;
使用buffer cache、arp cache和connetion tracking提升网络IO性能;
5.3 调整进程的slab缓存
[root@hadoop-master ~]# cat /proc/slabinfo | grep inode #查看进程的slab缓存
ext4_inode_cache 20721 20724 1000 4 1 : tunables 54 27 8 : slabdata 5181 5181 0
[root@hadoop-master ~]# echo 'ext4_inode_cache 108 54 8' > /proc/slabinfo #调整slab缓存大小
[root@hadoop-master ~]# cat /proc/slabinfo | grep inode #调整后的slab缓存
ext4_inode_cache 20721 20724 1000 4 1 : tunables 108 54 8 : slabdata 5181 5181 0
6.交换内存:
6.1 交换内存空间设置:
参考值:计算型服务器<=4*RAM
数据库服务器<=1G
web服务器>=0.5RAM
vm.swappiness={0..100}:使用交换分区的倾向性,值越大倾向性越高,默认 60。
[root@hadoop-master ~]# cat /proc/sys/vm/swappiness
60
6.2 物理内存过量使用
物理内存的过量使用是以swap为前提的:可以超出物理内存一部分,但一定不能超出物理内存+swap内存的总会。
overcommit_memory=2: 过量使用
overcommit_ratio=50:
Committed_As是已经分配的内存大小。
overcommit_memory参数就是控制分配内存是否可以超过CommitLimit,默认是0,即启
发式的overcommitting handle,会尽量减少swap的使用,root可以分配比一般用户略多的
内存。1表示允许超过CommitLimit,2表示不允许超过CommitLimit。
原来这种怀疑系统参数有问题的诊断一般就是比较和正常机器的sysctl.conf配置,下次要先比较避免武断下结论。。
swap+RAM*ratio
swap: 2G
RAM: 8G
memory=2G+4G=6G
充分使用物理内存的参数设置:
1、swap跟RAM一样大;swappiness=0;
2、 overcommit_memory=2, overcommit_ratio=100:swappiness=0;
memory: swap+ram
7.进程间通信管理类命令:
ipcs
[root@hadoop-master ~]# ipcs -l
------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 67108864
max total shared memory (kbytes) = 17179869184
min seg size (bytes) = 1
------ Semaphore Limits --------
max number of arrays = 128
max semaphores per array = 250
max semaphores system wide = 32000
max ops per semop call = 32
semaphore max value = 32767
------ Messages: Limits --------
max queues system wide = 2978
max size of message (bytes) = 65536
default max size of queue (bytes) = 65536
ipcrm
共享内存参数调整:
shm:
shmmni: 系统级别,所允许使用的共享内存段上限;
shmall: 系统级别,能够为共享内存分配使用的最大页面数;
shmmax: 单个共享内存段的上限;
消息调整参数
messages:
msgmnb: 单个消息队列的上限,单位为字节;
msgmni: 系统级别,消息队列个数上限;
msgmax: 单个消息大小的上限,单位为字节;
一般是将以上参数调大
8.pdflush进程:
简介 :由于页高速缓存的缓存作用,写操作实际上会被延迟。当页高速缓存中的数据比后台存储的数据
更新时,那么该数据就被称做脏数据。在内存中累积起来的脏页最终必须被写回磁盘。在以下两种情况
发生时,脏页被写回磁盘:
当空闲内存低于一个特定的阈值时,内核必须将脏页写回磁盘,以便释放内存。
当脏页在内存中驻留时间超过一个特定的阈值时,内核必须将超时的脏页写回磁盘,以确保脏页不会无限期地驻留在内存中。
上面两种工作的目的完全不同。实际上,在老内核中,这是由两个独立的内核线程分别完成的。但是在
2.6内核中,由一群内核线程—pdflush后台回写例程—统一执行两种工作。我们来看看这两个目标是如何具体实现的。
首先,当系统中的空闲内存低于一个特定的阈值时,pdflush线程将脏页刷新回磁盘。该后台回写例程的
目的在于在可用物理内存过低时,释放脏页以重新获得内存。特定的内存阈值可以通过dirty_background_ratio参数设置。
当空闲内存比阈值dirty_ background_ratio还低时,内核便会调用函数wakeup_bdflush()唤醒一个pdflush线程,
随后pdflush线程进一步调用函数background_writeout()开始将脏页写回磁盘。函数background_ writeout()需要
一个长整型参数,该参数指定试图回写的页面数目。函数background_writeout()会连续地写出数据,直到满足
以下两个条件:
已经有指定的最小数目的页被写出到磁盘。
空闲内存数已经回升,超过了阈值dirty_background_ratio。
上述条件确保了pdflush操作可以减轻系统中内存不足的压力。回写操作不会在达到这两个条件前停止,除非
pdflush写回了所有的脏页,没有剩下的脏页可再被写回了。要满足第二个目标,pdflush后台例程会被周期性
唤醒(和空闲内存是否过低无关),将那些在内存中驻留时间过长的脏页写出,确保内存中不会有长期存在
的脏页。加入系统发生崩溃,则内存会处于混乱之中,而那些在内存中还没来得及写回磁盘的脏页就会丢失,
所以周期性同步回写非常重要。在系统启动时,内核初始化一个定时器,让它周期地唤醒pdflush线程,随后
使其运行函数wb_kupdate()。该函数将把所有驻留时间超过百分之dirty_expire_centisecs秒的脏页写回。然后
定时器将再次被初始化为百分之dirty_expire_ centisecs秒后唤醒pdflush线程。总而言之,pdflush线程周期地
被唤醒并且把超过特定期限的脏页写回磁盘。
9.proc下的相关控制参数
系统管理员可以在/proc/sys/vm中设置回写相关的参数,也可以通过sysctl系统调用设置它们。
/proc/sys/vm/dirty_ratio
这个参数控制一个进程在文件系统中的文件系统写缓冲区的大小,单位是百分比,表示系统
内存的百分比,表示当一个进程中写缓冲使用到系统内存多少的时候,再有磁盘写操作时开
始向磁盘写出数据。增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写
性能。但是,当你需要持续、恒定的写入场合时,应该降低其数值,一般缺省是 20。
/proc/sys/vm/dirty_background_ratio
这个参数控制文件系统的pdflush进程,在何时刷新磁盘。单位是百分比,表示系统总内存的百
分比,意思是当磁盘的脏数据缓冲到系统内存多少的时候,pdflush开始把脏数据刷新到磁盘。
增大会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。但是,当你需要持
续、恒定的写入场合时,应该降低其数值,一般缺省是10。
/proc/sys/vm/dirty_writeback_centisecs
Pdflush写后台进程每隔多久被唤醒并执行把脏数据写出到硬盘。单位是 1/100 秒。缺省数值是
500,也就是 5 秒。如果你的系统是持续地写入动作,那么实际上还是降低这个数值比较好,
这样可以把尖峰的写操作削平成多次写操作。设置方法如下:
echo 200 >/proc/sys/vm/dirty_writeback_centisecs
/proc/sys/vm/dirty_expire_centisecs
这个参数声明Linux内核写缓冲区里面的脏数据多“旧”了之后,pdflush 进程就开始考虑写到磁盘中
去。单位是 1/100秒。缺省是 3000,也就是 30 秒的数据就算旧了,将会刷新磁盘。对于特别重
载的写操作来说,这个值适当缩小也是好的,但也不能缩小太多,因为缩小太多也会导致IO提高
太快。建议设置为 1500,也就是15秒算旧。
echo 1500 >/proc/sys/vm/ dirty_expire_centisecs
手动清写脏缓存和缓存:
sync
echo s > /proc/sysrq-trigger # 立即重新挂载所有的文件系统
回收:
echo 1 > /proc/sys/vm/drop_caches
0 – 不释放
1 – 释放页缓存
2 – 释放dentries和inodes
3 – 释放所有缓存
vfs_cache_pressure:文件节点缓存回收参数
0:不回收dentries和inodes;
1-99: 倾向于不回收;
100: 倾向性与page cache和swap cache相同;
100+:倾向于回收;
MIN_FREE_KBYTES的目的是保持物理内存有足够的空闲空间,防止突发性的换页。
Linux swapiness缺省为60,减少swapiness会使系统尽快通过swapout不使用的进程资源来释放更多的物理内存。
vfs_cache_pressure的缺省值是100,加大这个参数设置了虚拟内存回收directory和i-node缓冲的倾向,这个值越大,越倾向于内存回收。
调整这3个参数的目的就是让操作系统在平时就尽快回收缓冲,释放物理内存,这样就可以避免突发性的大规模换页。
sysctl -w vm.min_free_kbytes=409600
sysctl -w vm.vfs_cache_pressure=200
sysctl -w vm.swappiness=40(或者更低)
10.内存泄漏
10.1查看内存泄漏
valgrind --tool=memcheck cat /proc/372/root/etc/init.d/nginx #检查nginx启动文件是否内存泄漏
10.2内存泄漏处理
Linux 下有个特性叫作 OOM killer(Out of Memory),从字面的意思可以看出和内存溢出相关,当内存耗尽时,该问题就会出现。
在Linux2.6.内核中,当该功能打开后,在内存耗尽时,会根据一定的值计算出一个合适的用户空间的进程给kill掉,以便释放更多的
内存,保证整个系统的稳定运行。在系统的日志中通常会有下面的打印日志:Out of memory: kill process 959 (sshd) score 55 or a child。
OOM什么时候出现:
我们在用户空间申请内存时,一般使用的是malloc,是不是当malloc返回为空时,没有可以申请的内存空间了就会返回呢?答案是否定的。在关于malloc的申请内存的机制中有下面的一段描述:
Linux下有3种Overcommit的策略(参考内核文档:vm/overcommit-accounting),可以在/proc/sys/vm/overcommit_memory配置(取0,1和2三个值,默认是0)。
(1)0:启发式策略,比较严重的Overcommit将不能得逞,比如你突然申请了128TB的内存。而轻微的overcommit将被允许。另外,root能Overcommit的值比普通用户要稍微多
(2)永远允许overcommit,这种策略适合那些不能承受内存分配失败的应用,比如某些科学计算应用。
(3)永远禁止overcommit,在这个情况下,系统所能分配的内存不会超过swap+RAM*系数( /proc/sys/vm/overcommit_ratio,默认50%,你可以调整),如果这么多资源已经用光,
那么后面任何尝试申请内存的行为都会返回错误,这通常意味着此时没法运行任何新程序。
当然我可以修改proc//oom_adj的值,这里的默认值为0,当我们设置为-17时,对于该进程来说,就不会触发OOM机制,被杀掉。
echo -17 > /proc/$(pidof sshd)/oom_adj
这里为什么是-17呢?这和Linux的实现有关系。在Linux内核中的oom.h文件中,可以看到下面的定义:
/* /proc//oom_adj set to -17 protects from the oom-killer */
#define OOM_DISABLE (-17)
/* inclusive */
#define OOM_ADJUST_MIN (-16)
#define OOM_ADJUST_MAX 15
这个oom_adj中的变量的范围为15到-16之间。越大越容易被kill。oom_score就是它计算出来的一个值,就是根据这个值来选择哪些进程被kill掉的。
总之,通过上面的分析可知,满足下面的条件后,就是启动OOM机制。
我们先来看一下kernel提供给用户态的/proc下的一些参数:
/proc/[pid]/oom_adj ,该pid进程被oom killer杀掉的权重,介于 [-17,15]之间,越高的权重,意味着更可能被oom killer选中,-17表示禁止被kill掉。
/proc/[pid]/oom_score,当前该pid进程的被kill的分数,越高的分数意味着越可能被kill,这个数值是根据oom_adj运算后的结果,是oom_killer的主要参考。 (责任编辑:liangzh) |