0%

内核参数了解及优化

随着自己工作年限的增加,工作中并不是一味的部署服务,应用简单的操作,有的时候需要进行下内核参数调优,在此做下记录。。

一般我们会通过sysctl来进行参数更改,有的时候也会使用echo直接写到文件中。其实效果都是一样的。

所有我们能更改的内核参数控制都在/proc/sys这个目录下,我们可以看到有fs,net,vm等,对应文件系统(filesystem),网络,虚拟内存等。而这些文件下边都是一些空的文件,其实每个文件都是一个控制选项,具体我们可以参考官网的解释,https://www.kernel.org/doc/Documentation/sysctl/fs.txt这个是fs的解释,net我们只要把url中fs.txt换成net.txt即可

一般分为以下几种:

  1. network(网络)
  2. IO(输入输出子系统)
  3. process(进程)
  4. memory(内存)
  5. File System(文件系统)

最后说下内核参数调整需谨慎,大家操作小心,不要翻车。。

下边记录下平常使用过得调整,不定时更新。

内存相关

共享内存

属于ipc(InterProcess Communication 进程间通讯) 其中一种,ipc 包括 (消息队列,共享内存,信令,管道,sockets,streams

共享内存是一种比较高效的通讯方式,几乎是最快的ipc 方式。很多有名服务都在使用比如kafka。
但是使用门槛比较高,处理不好问题会比较麻烦。

##实现方式##

释放cached缓存

sysctl -w vm.drop_caches=1|2|3

可以设置的值分别为1、2、3。它们所表示的含义为:

1 = 表示清除pagecache
2 = 表示清除回收slab分配器中的对象(包括目录项缓存和inode缓存)。
    slab分配器是内核中管理内存的一种机制,其中很多缓存数据实现都是用的pagecache。
3 = 表示清除pagecache和slab分配器中的缓存对象。

适用场景:
我们查看内存的时候,经常使用free -m

1
2
3
4
5
[root@k8337v /home/fanquanqing]# free -m
total used free shared buffers cached
Mem: 3865 3728 136 0 10 52
-/+ buffers/cache: 3665 199
Swap: 8191 1314 6877

发现很多used free的很少,其实我们可用内存不只有136,可用内存应该是free+buffers+cached也就说可用内存为198M

科普下:
buffers

A buffer is something that has yet to be “written” to disk.

cached

A cache is something that has been “read” from the disk and stored for later use ;

这个时候如果cached很多,例如像mangoDB ES这种数据库cached不用想都会有很多,我们可以手动释放一下

限制swap

  • sysctl -w vm.swappiness=0

很多人会把虚拟内存和Swap混为一谈,实际上Swap只是虚拟内存引申出的一种技术而已:操作系统一旦物理内存不足,为了腾出内存空间存放新内容,就会把当前物理内存中的内容放到交换分区里,稍后用到的时候再取回来,需要注意的是,Swap的使用可能会带来性能问题,偶尔为之无需紧张,糟糕的是物理内存和交换分区频繁的发生数据交换,这被称之为Swap颠簸,一旦发生这种情况,先要明确是什么原因造成的,如果是内存不足就好办了,加内存就可以解决,不过有的时候即使内存充足也可能会出现这种问题,比如MySQL就有可能出现这样的情况,解决方法是限制使用Swap,如上所示。

关闭swap

swapoff -a (记得置到后台,回收比较慢)

ulimit

/etc/security/limits.conf
/etc/security/limits.d/90-nproc.conf

1
2
*          soft    nproc     10240
* hard nproc 10240

dirty page(脏页)

因为团队最近搞kafka所以对这个参数最近有一些研究。

查看脏页相关配置
sysctl -a| grep vm.dirty
vm.dirty_background_ratio = 10
vm.dirty_background_bytes = 0
vm.dirty_ratio = 30
vm.dirty_bytes = 0
vm.dirty_writeback_centisecs = 500
vm.dirty_expire_centisecs = 500

以上的显示基本是默认值(注意vm.dirty_bytes 与vm.dirty_ratio 设置一个 另一个会被覆盖 所以一般只设置一个,vm.dirty_background_ratio 与 vm.dirty_background_bytes 也是同样)

vm.dirty_background_ratio
当系统脏页的比例或者所占内存数量超过 dirty_background_ratio(百分数)/dirty_background_bytes(字节) 设定的
阈值时,启动相关内核线程(pdflush/flush/kdmflush)开始将脏页写入磁盘。

vm.dirty_ratio
当系统pagecache的脏页达到系统内存 dirty_ratio(百分数)/dirty_bytes字节)阈值时,系统就会阻塞新的写请求,
直到脏页被回写到磁盘,此值过低时,遇到写入突增时,会造成短时间内pagecache脏页快速上升,造成写请求耗时增加。

dirty page什么时候写回到磁盘?这个是由dirty_writeback_centisecs和dirty_expire_centisecs两个参数控制的。

dirty_writeback_centisecs 默认500 (5s )

控制 pdflush/flush/kdmflush等进程的唤醒时间,隔5s 检查有没有cache 需要被刷到盘上。

dirty_expire_centisecs 默认3000 (30s)

控制dirty page刷盘时间点。

如果 iowait 比较多 可以减小这两个值

tips :

for((;;));do cat /proc/vmstat | egrep 'dirty|writeback' ; echo ------------;sleep 1s;done

可以用上面命令动态查看脏页状态

网络相关

  • tcp_tw_reuse default:0

1表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;前提是tcp_timestamps=1 ,timeout连接才能被重用。

  • tcp_tw_recycle default:0

与tcp_tw_reuse 效果一致 回收更粗暴

  • tcp_max_syn_backlog default:各个版本有差异

半连接队列

  • tcp_max_syn_backlog default:12

全连接队列

  • tcp_abort_on_overflow default:0

这个配置当队列满了的时候被使用
全连接 取决于 min(backlog, somaxconn) . backlog是在socket创建的时候传入的,somaxconn是一个os级别的系统参数
半连接 取决于 max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog)

0 表示:如果三次握手第三步的时候全连接队列满了那么server扔掉client 发过来的ack(在server端认为连接还没建立起来)如果tcp_abort_on_overflow为0,则srver直接忽略收到的ACK,之后server端会不断的重发SYNC+ACK。其中tcp_synack_retries参数决定了重试几次才放弃。 tcp_synack_retries的默认值是5

1 表示:第三步的时候如果全连接队列满了,server发送一个reset包给client,表示废掉这个握手过程和这个连接(本来在server端这个连接就还没建立起来)。

  • tcp_max_tw_buckets default: 180000

timewait 连接上限 ,如果超限,系统会把多的destory

当队列满的时候排查过程

  1. 如果是因为服务进程繁忙引起的应用程序没有办法正常accept ,因为这个队列里面是已经建立好的连接(经过三次握手成功,状态为ESTABLISHED)。如果是应用程序繁忙,无暇顾及。判断是否应用程序有bug 或者 真的负载到了极限。
  2. 如果服务正常,负载也不高,请考虑稍微加大队列
  3. 如果是半连接可以减小tcp_synack_retries 减少半连接server重试次数

当timeout 连接数过多

尽量不要重用tw连接,主要是如果是重用两个client在一个nat网络(只有一个外网IP出口)里面,或者正好触发了ip 重新分配