有什么正規(guī)的網(wǎng)站做代加工百度問答庫
哈嘍大家好,我是咸魚。
今天收到了一個(gè)告警,說有臺服務(wù)器上的 swap 過高,已經(jīng)用了 50% 以上了。
登錄機(jī)器查看一下內(nèi)存以及 swap 的使用情況。
[root@localhost ~]# free -h
total used free shared buff/cache available
Mem: 62G 27G 2.9G 568M 32G 33G
swap: 16G 8.3G 8.1G
可以看到還有 2.9G 的空閑物理內(nèi)存,但是系統(tǒng)已經(jīng)開始使用 swap 了,初步判斷是機(jī)器上面的程序內(nèi)存需求比較大,但物理內(nèi)存不夠用所以開始使用 swap 來存儲部分?jǐn)?shù)據(jù)。
什么是 swap
swap 顧名思義指的是 Linux 上的交換分區(qū),有點(diǎn)像 Windows 的虛擬內(nèi)存,說白了就是把一塊磁盤空間或者一個(gè)本地文件當(dāng)成內(nèi)存來使用。
在早期內(nèi)存價(jià)格昂貴的時(shí)代,swap 的出現(xiàn)解決了物理內(nèi)存不足導(dǎo)致無法運(yùn)行程序的問題。
swap 包含換出和換入兩個(gè)過程:
- 換出:把進(jìn)程暫時(shí)不用的內(nèi)存數(shù)據(jù)存儲到磁盤中,并釋放這些數(shù)據(jù)占用的內(nèi)存。
- 換入:進(jìn)程再次訪問這些內(nèi)存數(shù)據(jù)時(shí),把它們從磁盤讀到內(nèi)存來。
那現(xiàn)在隨著內(nèi)存越來越便宜,服務(wù)器上面的內(nèi)存也越來越大,swap 是不是就沒啥作用了呢?
不是的,對于程序來說,內(nèi)存再大也有不夠用的時(shí)候。比如說內(nèi)存不足的時(shí)候,有些程序不希望被 OOM 殺死,而是希望等待一段時(shí)間讓人工來處理,或者等系統(tǒng)自動釋放其他進(jìn)程的內(nèi)存之后再分配給它。
又比如我們常見的筆記本電腦的休眠和快速開機(jī)的功能確實(shí)是基于 swap 的。在休眠時(shí),操作系統(tǒng)會將當(dāng)前內(nèi)存的狀態(tài)保存到交換空間或者稱為休眠文件中,然后關(guān)閉計(jì)算機(jī)。當(dāng)再次開機(jī)時(shí),系統(tǒng)可以直接從休眠文件中恢復(fù)內(nèi)存狀態(tài),而不需要重新加載應(yīng)用程序和初始化系統(tǒng),從而實(shí)現(xiàn)了快速開機(jī)的功能。
在 Linux 中,/proc/sys/vm/swappiness
用來調(diào)整使用 swap 的積極程度。swappiness 的范圍是 0-100,數(shù)值越大,越積極使用 swap。一般來講默認(rèn)值是 60 。
需要注意的是:這個(gè)范圍是 swap 積極程度的權(quán)重,即使我們設(shè)置成 0,在某些情況下(例如進(jìn)程可用內(nèi)存耗盡了)還是會使用 swap 的。
排查過程
首先我們來看下 swap 的積極程度。
[root@localhost ~]# cat /proc/sys/vm/swappiness
60
swappiness 顯示的是默認(rèn)值 60,這是一個(gè)相對中和的配置,所以系統(tǒng)會根據(jù)實(shí)際情況來選擇是回收可用緩存以增加可用內(nèi)存空間,還是使用交換空間來增加可用內(nèi)存空間。
接下來我們要找出是哪些進(jìn)程使用到了 swap。在 Linux 中,可以用 proc 文件系統(tǒng)來查看進(jìn)程 swap 換出的虛擬內(nèi)存大小,它保存在 /proc/pid/status
的 Vmswap 字段中。
但是一臺服務(wù)器中有這么多進(jìn)程,一個(gè)一個(gè)找太麻煩了,所以我們可以使用下面的命令來找出當(dāng)前系統(tǒng)中 swap 占用最大的幾個(gè)進(jìn)程,并列出它們的進(jìn)程號、進(jìn)程名和 swap 大小。
[root@localhost ~]# for file in /proc/*/status ; do awk '/Vmswap|Name|^Pid/{printf $2 " " $3}END{ print ""}' $file; done | sort -k 3 -n -r | head
java 153707 3245376 kB
java 153544 1757916 kB
java 172612 732100 kB
java 323072 339756 kB
java 172807 161988 kB
for file in /proc/*/status ; do ... done
:這是一個(gè) for 循環(huán),它遍歷了/proc
目錄下的所有子目錄,每個(gè)子目錄都包含一個(gè)名為status
的文件,其中包含了該進(jìn)程的一些狀態(tài)信息。awk '/VmSwap|Name|^Pid/{printf $2 " " $3}END{ print ""}' $file
:對于每個(gè)/proc/*/status
文件,awk 命令用于匹配VmSwap
、Name
或者Pid
這幾個(gè)關(guān)鍵字,并輸出它們的值。這些關(guān)鍵字分別表示交換空間、進(jìn)程名和進(jìn)程號。sort -k 3 -n -r
:對輸出的結(jié)果進(jìn)行排序。-k 3
表示按第三列進(jìn)行排序,即按照交換空間大小排序;-n
表示按照數(shù)字順序排序;-r
表示逆序排序,即從大到小排序。head -5
:輸出排序后的前5行。
從輸出的結(jié)果可以看到,使用 swap 比較多的是 java 進(jìn)程。
如何解決
在定位到是哪些進(jìn)程使用 swap 比較高之后,我們找到對應(yīng)的開發(fā)同事進(jìn)行討論,最后**決定把 swap 關(guān)掉。**通常來講,降低 swap 的使用,可以提高系統(tǒng)的整體性能。
一方面是因?yàn)轭l繁地進(jìn)行 swap 操作,會導(dǎo)致大量的磁盤讀寫操作,降低系統(tǒng)的響應(yīng)速度和整體性能。
另一方面是因?yàn)轭l繁地將數(shù)據(jù)從內(nèi)存交換到 swap 空間,并在需要時(shí)再次交換回來時(shí),會增加 CPU 和內(nèi)存的負(fù)擔(dān)。
如何關(guān)閉 swap ?
首先使用 swapoff
命令關(guān)閉當(dāng)前正在使用的交換空間。
[root@localhost ~]# swapoff -a
然后我們看下 swap 空間是否已經(jīng)關(guān)閉,如果輸出為空則表示 swap 成功關(guān)閉。
[root@localhost ~]# cat /proc/swaps
需要注意的是,前面的 swap 關(guān)閉操作只是臨時(shí)關(guān)閉,如果機(jī)器重啟是會重新開啟 swap 的。
所以為了下一次重啟機(jī)器后 swap 還是關(guān)閉狀態(tài)我們還要編輯 /etc/fstab
文件,將其中關(guān)于 swap 的配置注釋掉或者刪除掉。
# 找到以 swap 標(biāo)識的行,然后注釋
[root@localhost ~]# vim /etc/fstab
# /dev/mapper/centos-swap swap swap
這樣如果機(jī)器后面要是重啟了,swap 依舊是關(guān)閉狀態(tài)。