swap 频繁交换导致系统CPU过高

问题描述:

Zabbix告警Postgres VMCPU使用率过高

进入系统查看TOP

查看内存使用:

 进入Postgres看到真正运行的SQL总共有105个,其中还有全表扫描

 分析kswapd0进程CPU过高原因:由于数据库在同一时刻点大量SQL扫描同一张表,虽然有索引,但还是触发大量数据加载到内存,并且期间还有vacuum操作,导致系统缓存不足,系统频繁进行数据交换。 

SWAP交换分区:

swap分区的作用是当物理内存不足时,会将一部分硬盘当做虚拟内存来使用。
kswapd0 占用过高是因为 物理内存不足,使用swap分区与内存换页操作交换数据,导致CPU占用过高。
  可以通过修改  /etc/sys/vm/swappiness  里面的数值来修改swap分区使用与否,默认 60,数值越大表示更多的使用swap分区
swap 分区和内存 都有缓存区,缓存的内容为之前使用过的数据,用于加快第二次打开时访问速度。
swap分区 可以使用多个交换区(使用多硬盘?) 来加快swap访问速度
swap 分区使用的为硬盘的内容,速度比直接访问内存慢几千倍

kswapd0的作用:

 kswapd0进程的作用:它是虚拟内存管理中,负责换页的,操作系统每过一定时间就会唤醒kswapd ,看看内存是否紧张,如果不紧张,则睡眠,在 kswapd 中,有2 个阀值,pages_hige 和 pages_low,当空闲内存页的数量低于 pages_low 的时候,kswapd进程就会扫描内存并且每次释放出32 个free pages,直到 free page 的数量到达pages_high。通过阻止kswapd0进程过渡活跃地消耗CPU的方法是设置大页内存。
————————————————
版权声明:本文为CSDN博主「幸福丶如此」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_37886429/article/details/78487324

常用排查方法

一、检查共享内存,查看是否有 locked 的情况

[root@iZ23hh6yk41Z ~]# ipcs -m

二、检查物理内存是否有空闲,以及swap使用情况

[root@iZ23hh6yk41Z ~]# free -m
[root@iZ23hh6yk41Z ~]# vmstat -s | grep -i page

三、为避免kswapd0进程进行的无谓扫描,来检测是否有能被swap out的页,按照如下步骤启用大内存页(大内存页好处是永远不会被swap out)

1、设定/etc/security/limits.conf

[root@iZ23hh6yk41Z ~]# cat >> /etc/security/limits.conf < END
* soft memlock unlimited
* hard memlock unlimited
END

[root@iZ23hh6yk41Z ~]# ulimit -Hl
unlimited
[root@iZ23hh6yk41Z ~]# ulimit -Sl
unlimited

2、设置大内存页,计算大内存页的数量,注意执行这一步的时候必须保证实例至少启动到nomount状态

[root@iZ23hh6yk41Z ~]# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status 
0x00000000 1402961920 root 600 524288 17 dest 
0x68013082 993165313 zabbix 600 16777216 29 locked 
0x68011f60 1529741314 zabbix 600 1560281088 29 locked 
0x48013082 993198083 zabbix 600 4194304 29 locked
[root@iZ23hh6yk41Z ~]# cat /proc/meminfo | grep Hugepagesize
Hugepagesize: 2048 kB
最终需要的hugepages=(16777216/2048/1024+1)+(1560281088/2048/1024+1)+(4194304/2048/1024+1)=757
[root@iZ23hh6yk41Z ~]# echo "vm.nr_hugepages=757" >> /etc/sysctl.conf
[root@iZ23hh6yk41Z ~]# sysctl -p
[root@iZ23hh6yk41Z ~]# sysctl -n vm.nr_hugepages
757
[root@iZ23hh6yk41Z ~]# grep HugePages /proc/meminfo
AnonHugePages: 45056 kB
HugePages_Total: 757
HugePages_Free: 757
HugePages_Rsvd: 0
HugePages_Surp: 0
[root@iZ23hh6yk41Z ~]# ipcs -m #重新检查共享内存,发现locked已经没有了
[root@iZ23hh6yk41Z ~]# grep HugePages /proc/meminfo
AnonHugePages: 75776 kB
HugePages_Total: 757
HugePages_Free: 624 
HugePages_Rsvd: 621
HugePages_Surp: 0

备注:Free < Total,说明已经有huge page被使用了
扩展

问题:events/0 大量消耗CPU

中断的底半部机制有三种:软中断、tasklet和工作队列。其中软中断很少使用,内核中只有网络在使用,它的延时是最小的。

tasklet是软中断的一个应用,所有线程注册的tasklet都会顺序被执行。因此tasklet的执行环境是软中断上下文,所以不能阻塞或者睡眠。一般情况下,tasklet的延迟也很小,可以满足大部分需求。

要是底半部中可能睡眠,那么只好使用工作队列了。工作队列其实是把要做的底半部的函数交给内核的专门线程去调用。这样工作队列就运行于线程环境了,不怕睡眠。当然,睡眠会影响注册到同一线程的其它底半部的执行,但不会引起大的问题。每个CPU都有一个线程(events/n,n是编号)负责执行工作队列,第一个CPU的线程是events/0,如果是双核的,还会有一个events/1线程。程序使用了工作队列,所以每次执行都会多出一个events/0(第一个CPU上工作线程)。

内核的软中断辅助处理线程ksoftirqd/n(n是CPU编号),它们负责出发软中断中触发的软中断。它们将重新触发软中断放在系统空闲时调用,而不是马上。这样用户空间不至于饥饿,重新触发的软中断也得以尽快执行。

物理内存不足,引起 swap 频繁。其实这也是 VPS 使用上的一个常见的问题了,通常是由 Apache/Nginx 占用内存过多引起的。kswapd0 是系统的虚拟内存管理程序,如果物理内存不够用,系统就会唤醒 kswapd0 进程,由 kswapd0 分配磁盘交换空间作缓存,因而占用大量的 CPU 资源。重启Apache/Nginx,释放内存,问题就会消失。但这不是长久之计,最好的方法还是花点钱升级下内存。


————————————————
版权声明:本文为CSDN博主「幸福丶如此」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_37886429/article/details/78487324

vm.min_free_kbytes 设置过高,导致 kswapd0 消耗大量 CPU

Linux上设置大内存页解决kswapd0进程过渡消耗cpusys的问题

猜你喜欢

转载自www.cnblogs.com/tben/p/12449787.html