【現場問題】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的問題

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM