Linux緩存調優實戰,讓服務器飛起來!
在深入探討 Linux 緩存調優之前,我們先來搞清楚緩存到底是什么。簡單來說,緩存是一種高速存儲機制,它就像是一個數據的臨時 “中轉站”,把經常訪問的數據存儲在其中 。當程序需要讀取數據時,會優先從緩存中查找,如果找到了,就可以直接使用,大大提高了數據的訪問速度。
在 Linux 系統中,緩存的重要性不言而喻。它就像是服務器性能的 “加速器”,能顯著提升服務器的響應速度和整體性能。我們知道,磁盤 I/O 操作相對較慢,而內存的讀寫速度則快得多。緩存的存在,就像是在慢速的磁盤和快速的 CPU 之間搭建了一座橋梁,通過將頻繁訪問的數據存儲在內存中,減少了對磁盤的 I/O 操作,從而加快了數據的訪問速度,提高了系統的整體性能 。例如,當我們的服務器需要頻繁讀取某個文件時,如果這個文件被緩存到內存中,下次讀取時就可以直接從內存中獲取,而不需要再從磁盤中讀取,大大縮短了讀取時間,提升了服務器的響應速度。
一、認識Linux緩存
在 Linux 系統中,緩存主要分為頁緩存(Page Cache)和 inode 緩存 ,它們在系統中起著不同但又至關重要的作用。
頁緩存是 Linux 緩存機制的核心,它主要緩存磁盤文件的內容 。簡單來說,當我們的程序讀取文件時,內核會先檢查頁緩存中是否有需要的數據。如果有,就直接從緩存中讀取,避免了從磁盤中讀取數據的開銷 。比如,我們有一個 Web 服務器,它需要頻繁讀取一些靜態資源文件,如圖片、CSS、JavaScript 等。這些文件在第一次被讀取后,就會被緩存到頁緩存中。
當后續有其他請求需要這些文件時,就可以直接從頁緩存中獲取,大大提高了文件的讀取速度,減少了磁盤 I/O 操作 。頁緩存的工作原理基于局部性原理,即當一個數據被訪問時,它附近的數據也很可能在不久的將來被訪問。因此,頁緩存會預讀一部分數據,將其存儲在緩存中,以提高后續數據訪問的命中率 。
inode 緩存則主要用于緩存文件系統的元數據,比如文件名、文件權限、文件大小、文件的創建時間和修改時間等 。當我們要訪問一個文件時,首先需要通過 inode 緩存找到文件的元數據,然后才能進一步讀取文件的內容 。例如,當我們在命令行中輸入ls命令查看目錄下的文件時,系統會先在 inode 緩存中查找該目錄下所有文件的元數據,然后將這些信息顯示出來。
如果沒有 inode 緩存,每次執行ls命令都需要從磁盤中讀取這些元數據,這將大大降低系統的響應速度 。inode 緩存通過將常用的元數據存儲在內存中,減少了對磁盤的訪問次數,提高了文件系統的性能 。
二、緩存性能指標
在評估 Linux 緩存的性能時,有幾個關鍵指標是我們必須要關注的,它們就像是服務器性能的 “晴雨表”,能幫助我們準確判斷緩存的工作狀態和性能優劣 。
緩存命中率是其中最為重要的指標之一,它是指直接通過緩存獲取數據的請求次數,占所有數據請求次數的百分比 。簡單來說,如果緩存命中率高,就意味著大部分的數據請求都可以直接從緩存中獲取數據,而不需要去訪問速度較慢的磁盤,這大大提高了數據的訪問效率,也就意味著緩存的利用效率高,系統性能好 。例如,一個 Web 服務器的緩存命中率如果能達到 90% 以上,那就說明它的緩存配置非常合理,大部分用戶請求的數據都能快速從緩存中獲取,用戶體驗自然就會很好 。
相反,如果緩存命中率很低,比如只有 30%,那就說明緩存沒有充分發揮作用,大部分數據請求都需要去磁盤中讀取,這會導致系統響應速度變慢,性能下降 。我們可以通過cachestat和cachetop等工具來查看緩存命中率 。其中,cachestat提供了整個操作系統緩存的讀寫命中情況,而cachetop則提供了每個進程的緩存命中情況 。
緩存大小也不容忽視,它主要由文件系統緩存和頁面緩存兩部分組成 。緩存大小的設置直接影響著系統的性能 。當緩存大小較小時,系統往往會頻繁地從磁盤中讀取數據,這會導致響應延遲增加 。而當緩存大小增加時,系統可以將更多的數據存儲在內存中,從而減少對磁盤的訪問次數,提高響應速度 。比如,對于一個需要頻繁讀取大量數據的數據庫管理系統,如果緩存大小設置得足夠大,就能將更多的數據庫數據緩存到內存中,大大提高數據的讀取速度 。
然而,緩存大小也不是越大越好,因為緩存占用了系統的內存資源,如果緩存大小設置過大,可能會導致系統內存不足,影響到其他任務的正常運行 。同時,緩存大小過大還可能會導致緩存命中率下降,因為系統可能會將更多的不常訪問的數據存儲在緩存中,導致熱門數據的緩存命中率下降 。我們可以使用free、vmstat等命令查看系統內存和緩存的使用情況 ,也可以通過/proc/meminfo文件查看系統內存信息,其中Cached字段表示頁緩存,Buffers字段表示緩沖區 。
緩存更新頻率同樣關鍵,它決定了緩存中的數據與磁盤中數據的一致性程度 。如果緩存更新頻率過低,可能會導致緩存中的數據過時,應用程序讀取到的數據不是最新的 。例如,對于一個實時更新的新聞網站,如果緩存更新頻率過低,用戶可能會看到舊的新聞內容 。而如果緩存更新頻率過高,雖然能保證數據的實時性,但會增加系統的開銷,因為每次更新緩存都需要進行數據的讀取和寫入操作 。
對于更新頻率較低的資源,如一些靜態的 CSS、JavaScript 和圖片文件,我們可以設置較長的緩存時間,以減少對服務器的請求;而對于更新頻繁的資源,如新聞內容、股票數據等,則需要設置較短的緩存時間,確保客戶端能夠獲取到最新的內容 。在 Linux 系統中,緩存更新頻率與具體的應用場景和配置有關 ,可以通過調整相關的配置參數來控制 。
三、緩存調優工具
“工欲善其事,必先利其器” ,在進行 Linux 緩存調優時,我們需要借助一些強大的工具,它們就像是我們的 “得力助手”,能幫助我們更好地了解系統的緩存狀態,從而進行有針對性的調優 。
sysctl 是一個非常重要的工具,它主要用于運行時配置內核參數,這些參數位于/proc/sys目錄下 。通過 sysctl,我們可以動態地調整內核參數,而不需要重啟系統,這為我們的緩存調優提供了極大的便利 。比如,我們可以使用sudo sysctl -w vm.swappiness=10命令來降低系統的交換傾向,減少不必要的磁盤 I/O 操作,提高緩存的使用效率 。
這里的vm.swappiness參數表示系統將內存數據交換到磁盤的傾向程度,取值范圍是 0 - 100,默認值一般是 60 。將其設置為 10,意味著系統會盡量避免將內存數據交換到磁盤,更多地利用內存緩存,從而提高系統性能 。如果我們想要永久保留這個配置,可以修改/etc/sysctl.conf文件,在文件中添加或修改vm.swappiness = 10這一行,然后執行sudo sysctl -p命令使配置生效 。
free 命令則是用于查看系統內存使用情況的常用工具 。它可以顯示系統的總內存、已使用內存、剩余內存、共享內存、緩存和緩沖區的使用情況等 。通過free -h命令,我們可以以人類可讀的方式查看內存信息,非常直觀 。例如,執行free -h后,可能會得到類似這樣的輸出:
total used free shared buff/cache available
Mem: 15Gi 4.0Gi 8.6Gi 100Mi 2.8Gi 11Gi
Swap: 2.0Gi 0B 2.0Gi
在這個輸出中,total表示系統總物理內存的大小,這里是 15Gi;used表示當前被使用的內存大小,為 4.0Gi;free表示當前完全未被使用的內存大小,是 8.6Gi;shared表示與多個進程共享的內存大小,為 100Mi;buff/cache表示由內核用于緩存的內存,包括文件系統緩沖區和文件緩存,這里是 2.8Gi;available表示可以立即分配給新進程的內存量,為 11Gi 。從這些信息中,我們可以快速了解系統內存的使用狀況,判斷是否存在內存不足的情況,以及緩存和緩沖區的使用情況 。
vmstat 也是一個強大的系統性能監控工具,它可以展示給定時間間隔的服務器的狀態值,包括進程、內存、虛擬內存交換情況、IO 讀寫情況等 。通過vmstat 1命令,我們可以每秒輸出一次系統性能數據 。例如,執行vmstat 1后,可能會得到如下輸出:
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 103388 145412 511056 0 0 18 60 1 1 2 1 96 0 0
在這個輸出中,r表示運行隊列中等待被運行的進程數量,b表示等待 IO 的進程數量;swpd表示虛擬內存已使用的大小,如果大于 0,表示機器物理內存不足;free表示空閑的物理內存的大小;buff表示用作緩沖的內存大小;cache表示用作緩存的內存大小;si表示每秒從磁盤讀入虛擬內存的大小;so表示每秒虛擬內存寫入磁盤的大小;bi表示塊設備每秒接收的塊數量;bo表示塊設備每秒發送的塊數量;in表示每秒 CPU 的中斷次數,包括時間中斷;cs表示每秒上下文切換次數;us表示用戶 CPU 時間;sy表示系統 CPU 時間;id表示空閑 CPU 時間;wa表示等待 IO CPU 時間 。通過分析這些數據,我們可以深入了解系統的性能瓶頸,判斷是否存在內存瓶頸、IO 瓶頸等問題,從而為緩存調優提供依據 。
cachestat 和 cachetop 是用于查看系統緩存命中情況的工具 。cachestat 提供了整個操作系統緩存的讀寫命中情況,而 cachetop 則提供了每個進程的緩存命中情況 。這兩個工具都是 bcc 軟件包的一部分,它們基于 Linux 內核的 eBPF(extended Berkeley Packet Filters)機制,來跟蹤內核中管理的緩存,并輸出緩存的使用情況 。在 Ubuntu 系統中,我們可以通過以下命令安裝 bcc 軟件包:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4052245BD4284CDD
echo "deb https://repo.iovisor.org/apt/xenial xenial main" | sudo tee /etc/apt/sources.list.d/iovisor.list
sudo apt-get update
sudo apt-get install -y bcc-tools libbcc-examples linux-headers-$(uname -r)
安裝完成后,我們可以使用cachestat命令查看系統緩存的讀寫命中情況 。例如,執行cachestat后,可能會得到如下輸出:
TOTAL MISSES HITS DIRTIES BUFFERS_MB CACHED_MB
2 0 2 1 17 279
在這個輸出中,TOTAL表示總訪問次數,MISSES表示緩存未命中次數,HITS表示緩存命中次數,DIRTIES表示新增到緩存中的臟頁數,BUFFERS_MB表示緩沖區大小,CACHED_MB表示緩存大小 。通過這些數據,我們可以計算出緩存命中率,評估系統對緩存的利用效率 。緩存命中率的計算公式為:緩存命中率 = HITS / TOTAL * 100% 。在這個例子中,緩存命中率為2 / (2 + 0) * 100% = 100% ,說明系統的緩存利用效率非常高 。
我們可以使用cachetop命令實時監控進程的緩存讀寫命中情況 。例如,執行cachetop后,可能會得到如下輸出:
11:58:50 Buffers MB:258 / Cached MB: 347 / Sort: HITS / Order: ascending
PID UID CMD HITS MISSES DIRTIES READ_HIT% WRITE_HIT%
13029 root python 1 0 0 100.0% 0.0%
在這個輸出中,PID表示進程 ID,UID表示用戶 ID,CMD表示進程命令,HITS表示緩存命中次數,MISSES表示緩存未命中次數,DIRTIES表示新增到緩存中的臟頁數,READ_HIT%表示讀緩存命中率,WRITE_HIT%表示寫緩存命中率 。通過這個輸出,我們可以看到每個進程的緩存命中情況,找出占用緩存較多的進程,從而有針對性地進行優化 。在這個例子中,python進程的讀緩存命中率為 100.0%,寫緩存命中率為 0.0%,說明該進程的讀操作較多,且緩存利用效率較高,但寫操作可能存在一些問題,需要進一步分析 。
四、實戰調優步驟
4.1查看當前緩存狀態
在進行緩存調優之前,我們首先要了解系統當前的緩存狀態,就像是醫生在給病人治病之前,需要先進行全面的檢查一樣 。通過查看緩存狀態,我們可以判斷系統是否需要進行調優,以及確定調優的方向和重點 。
我們可以使用free命令來查看系統內存的使用情況,包括緩存的使用情況 。例如,執行free -h命令,輸出結果如下:
total used free shared buff/cache available
Mem: 15Gi 4.0Gi 8.6Gi 100Mi 2.8Gi 11Gi
Swap: 2.0Gi 0B 2.0Gi
從這個輸出中,我們可以看到buff/cache這一列的值,它表示系統中用于緩存和緩沖區的內存大小 。通過觀察這個值的變化,我們可以了解緩存的使用情況 。如果buff/cache的值較大,說明系統緩存了較多的數據,這可能會提高系統的性能 。但如果buff/cache的值過大,導致系統內存不足,影響到其他任務的正常運行,就需要考慮進行緩存調優了 。
vmstat命令也是一個非常有用的工具,它可以提供系統的詳細性能信息,包括緩存的讀寫情況 。執行vmstat 1命令,每秒輸出一次系統性能數據,輸出結果如下:
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 103388 145412 511056 0 0 18 60 1 1 2 1 96 0 0
在這個輸出中,cache列表示用作緩存的內存大小,bi列表示塊設備每秒接收的塊數量,bo列表示塊設備每秒發送的塊數量 。通過分析這些數據,我們可以了解緩存的讀寫性能 。如果bi和bo的值較大,說明系統對磁盤的 I/O 操作頻繁,可能是緩存命中率較低,需要進一步優化緩存 。
我們還可以使用cachestat和cachetop工具來查看緩存命中率 。cachestat提供了整個操作系統緩存的讀寫命中情況,cachetop則提供了每個進程的緩存命中情況 。例如,執行cachestat命令,輸出結果如下:
TOTAL MISSES HITS DIRTIES BUFFERS_MB CACHED_MB
2 0 2 1 17 279
從這個輸出中,我們可以看到TOTAL表示總訪問次數,MISSES表示緩存未命中次數,HITS表示緩存命中次數 。通過計算HITS / TOTAL * 100%,我們可以得到緩存命中率 。在這個例子中,緩存命中率為2 / (2 + 0) * 100% = 100% ,說明系統的緩存利用效率非常高 。如果緩存命中率較低,比如低于 80%,就需要考慮優化緩存,提高命中率 。
4.2調整內核參數
在了解了系統當前的緩存狀態后,我們就可以根據實際情況調整內核參數,對緩存進行優化 。內核參數就像是系統的 “幕后指揮官”,它們控制著系統的各種行為,包括緩存的管理和使用 。通過調整這些參數,我們可以讓系統更好地適應不同的應用場景,提高緩存的性能 。
vm.swappiness是一個非常重要的內核參數,它表示系統將內存數據交換到磁盤的傾向程度,取值范圍是 0 - 100,默認值一般是 60 。當系統內存不足時,內核會根據vm.swappiness的值來決定是否將內存中的數據交換到磁盤的交換空間(Swap)中 。如果vm.swappiness的值設置得較高,比如 80,那么系統在內存不足時會更傾向于將內存數據交換到磁盤,這雖然可以暫時解決內存不足的問題,但會增加磁盤 I/O 操作,降低系統性能 。因為磁盤的讀寫速度遠遠低于內存,頻繁的磁盤 I/O 操作會導致系統響應變慢 。
相反,如果 vm.swappiness 的值設置得較低,比如 10,系統會盡量避免將內存數據交換到磁盤,更多地利用內存緩存,從而提高系統性能 。對于大多數服務器應用來說,建議將vm.swappiness的值設置在 10 - 30 之間 。我們可以使用sudo sysctl -w vm.swappiness=10命令來臨時調整vm.swappiness的值,也可以通過修改/etc/sysctl.conf文件,添加或修改vm.swappiness = 10這一行,然后執行 sudo sysctl -p 命令使配置永久生效 。
vm.dirty_ratio和vm.dirty_background_ratio這兩個參數則與臟頁的處理有關 。臟頁是指已經被修改但還沒有被寫入磁盤的內存頁 。vm.dirty_ratio表示當臟頁占內存的比例達到這個值時,系統會開始同步臟頁到磁盤 ,默認值一般是 20 。vm.dirty_background_ratio表示當臟頁占內存的比例達到這個值時,系統會在后臺開始同步臟頁到磁盤 ,默認值一般是 10 。如果vm.dirty_ratio設置得過高,臟頁在內存中積累的時間會變長,這可能會導致系統在同步臟頁時出現長時間的 I/O 阻塞,影響系統性能 。
而如果vm.dirty_background_ratio設置得過低,系統會頻繁地在后臺同步臟頁,增加磁盤 I/O 負載 。為了平衡系統性能和 I/O 負載,建議將vm.dirty_ratio設置在 5 - 10 之間,將vm.dirty_background_ratio設置在 1 - 5 之間 。同樣,我們可以使用sudo sysctl -w vm.dirty_ratio=5和sudo sysctl -w vm.dirty_background_ratio=1命令來臨時調整這兩個參數的值,也可以通過修改/etc/sysctl.conf文件使配置永久生效 。
4.3清理緩存
在某些情況下,我們可能需要手動清理緩存,以釋放內存資源,提高系統性能 。比如,當系統內存不足,而緩存中又占用了大量內存時,清理緩存可以讓系統有更多的內存用于其他任務 。
在 Linux 系統中,我們可以通過/proc/sys/vm/drop_caches這個接口來清理緩存 。具體來說,有以下三種清理方式:
- 僅釋放頁緩存(PageCache):執行echo 1 > /proc/sys/vm/drop_caches命令,或者sudo sysctl -w vm.drop_caches=1命令 。頁緩存主要用于緩存磁盤數據,清理頁緩存可以釋放用于緩存磁盤數據的內存 。
- 釋放目錄項(Dentries)和索引節點(Inodes)緩存:執行echo 2 > /proc/sys/vm/drop_caches命令,或者sudo sysctl -w vm.drop_caches=2命令 。目錄項緩存用于緩存目錄結構,索引節點緩存用于緩存文件元數據,清理這兩個緩存可以釋放用于緩存文件系統元數據的內存 。
- 釋放所有緩存(PageCache + Dentries + Inodes):執行echo 3 > /proc/sys/vm/drop_caches命令,或者sudo sysctl -w vm.drop_caches=3命令 。這將釋放所有類型的緩存,最大限度地釋放內存 。
需要注意的是,在清理緩存之前,建議先執行sync命令 。sync命令的作用是將所有緩存數據同步到磁盤,避免因清理緩存導致的數據丟失 。因為在清理緩存時,如果有未同步的臟頁,這些數據可能會丟失 。例如,我們可以執行sync && echo 3 > /proc/sys/vm/drop_caches命令,先同步數據,再清理所有緩存 。
清理緩存雖然可以釋放內存資源,但也可能會對系統性能產生一定的影響 。因為清理緩存后,系統在后續訪問數據時,可能需要重新從磁盤讀取數據,這會增加磁盤 I/O 操作,導致系統響應速度變慢 。所以,在清理緩存時,我們需要謹慎操作,根據實際情況選擇合適的清理方式和時機 。一般來說,只有在系統內存嚴重不足,或者需要強制刷新緩存時,才建議清理緩存 。
4.4優化應用程序
除了調整內核參數和清理緩存外,從應用程序層面進行優化也是提高系統性能的關鍵 。應用程序就像是系統的 “前臺演員”,它的性能直接影響著用戶的體驗 。通過優化應用程序,我們可以減少對緩存的不必要依賴,提高緩存的利用效率,從而提升系統的整體性能 。
從代碼層面來看,我們可以優化數據訪問模式,減少不必要的 I/O 操作 。比如,在讀取文件時,可以采用批量讀取的方式,而不是逐行讀取 。假設我們有一個程序需要讀取一個包含大量數據的文件,如果逐行讀取,每次讀取都會產生一次 I/O 操作,這會大大增加 I/O 開銷 。而采用批量讀取的方式,我們可以一次性讀取多個數據塊,減少 I/O 操作的次數 。例如,在 Python 中,我們可以使用readlines()方法一次性讀取文件的所有行,而不是使用readline()方法逐行讀取 。示例代碼如下:
# 逐行讀取
with open('large_file.txt', 'r') as f:
while True:
line = f.readline()
if not line:
break
# 處理每一行數據
# 批量讀取
with open('large_file.txt', 'r') as f:
lines = f.readlines()
for line in lines:
# 處理每一行數據
我們還可以緩存計算結果,避免重復計算 。比如,在計算斐波那契數列時,如果不進行緩存,每次計算都會重復計算很多中間結果,效率非常低 。而通過緩存已經計算過的結果,我們可以避免重復計算,提高計算效率 。以下是使用緩存優化后的計算斐波那契數列的代碼:
# 緩存字典
fib_cache = {}
def fib(n):
if n in fib_cache:
return fib_cache[n]
if n <= 1:
result = n
else:
result = fib(n - 1) + fib(n - 2)
fib_cache[n] = result
return result
從配置層面來看,我們可以為應用程序設置合理的緩存策略 。比如,對于一個 Web 應用程序,我們可以根據不同類型的資源設置不同的緩存時間 。對于更新頻率較低的靜態資源,如 CSS、JavaScript 和圖片文件,我們可以設置較長的緩存時間,以減少對服務器的請求 。而對于更新頻繁的資源,如新聞內容、股票數據等,則需要設置較短的緩存時間,確保客戶端能夠獲取到最新的內容 。在 Nginx 服務器中,我們可以通過配置expires指令來設置緩存時間 。例如,對于 CSS 和 JavaScript 文件,我們可以設置緩存時間為 1 周:
location ~ \.(css|js)$ {
expires 1w;
# 其他配置
}
對于圖片文件,我們可以設置緩存時間為 1 個月:
location ~ \.(jpg|jpeg|png|gif)$ {
expires 1M;
# 其他配置
}
通過以上從代碼層面和配置層面的優化,應用程序可以更好地利用緩存,減少對系統資源的消耗,提高系統的性能 。例如,一個經過優化的 Web 應用程序,在處理大量用戶請求時,響應速度可能會提高數倍,緩存命中率也會大幅提升,從而為用戶提供更加流暢的體驗 。
五、Linux緩存案例分析
5.1問題描述
那天剛到公司,就接到運營同事的緊急反饋:網站打開速度變得奇慢無比,原本秒開的頁面,現在加載要好幾秒,用戶投訴量直線上升。我心里 “咯噔” 一下,立刻登錄服務器查看。
通過top命令發現,CPU 和內存使用率看起來都還算正常,并沒有出現資源被占滿的情況。但使用vmstat命令觀察系統狀態時,發現bi(從塊設備讀入數據到系統的塊數)和bo(從系統寫入數據到塊設備的塊數)數值異常高,磁盤 I/O 負載明顯增大,這和平時穩定的狀態大相徑庭。
再用free -h查看內存使用情況,發現緩存(buff/cache)占用了大量內存,而且可用內存(free)所剩不多。這讓我初步懷疑,問題可能出在緩存上。難道是緩存沒有發揮作用,導致頻繁讀取磁盤數據,從而拖慢了整個系統?
5.2定位緩存 “罪魁禍首”
為了進一步確認問題,我使用cachestat工具來分析緩存的使用情況。這一查,果然發現了異常:緩存命中率低得可憐,大量的文件讀取操作都沒有命中緩存,直接從磁盤讀取,這無疑是導致磁盤 I/O 飆升、系統性能下降的關鍵原因。
那為什么緩存命中率會突然變得這么低呢?我決定從應用程序入手排查。檢查項目代碼和配置文件后發現,最近上線的一個新功能模塊,在數據處理過程中頻繁地創建和刪除臨時文件。這些臨時文件的生命周期很短,導致系統頻繁地將它們加載到緩存中,又很快因為文件被刪除而釋放緩存空間,使得緩存無法有效利用,一直處于 “無效更新” 的狀態。
此外,我還注意到服務器的內核參數vm.swappiness的值為 60(默認值)。這個參數控制著系統將內存數據交換到 swap 空間的傾向程度,數值越高,越容易將內存數據交換到 swap。由于服務器可用內存已經不多,較高的swappiness值使得系統開始頻繁進行內存交換操作,進一步加劇了系統性能的惡化。
5.3多管齊下解決問題
⑴優化應用程序
針對應用程序頻繁創建和刪除臨時文件的問題,我們對代碼進行了重構。將一些不必要的臨時文件操作進行合并和優化,減少臨時文件的創建頻率。同時,在文件使用完畢后,及時關閉文件句柄,并使用unlink函數刪除臨時文件,避免文件被刪除后,相關緩存數據仍占用內存空間。
⑵調整內核參數
為了減少內存交換操作,我將vm.swappiness的值調低至 10。通過修改/etc/sysctl.conf文件,添加或修改vm.swappiness = 10,然后執行sysctl -p使配置生效。這樣,系統在內存緊張時,不會輕易將內存數據交換到 swap,而是盡量利用已有的內存資源,提高系統整體性能。
⑶清理緩存
在完成上述優化和配置調整后,為了讓系統緩存快速恢復到正常狀態,我決定清理部分緩存。但需要注意的是,清理緩存操作可能會對正在運行的業務產生一定影響,所以我選擇在業務低峰期進行。
執行echo 3 > /proc/sys/vm/drop_caches命令,該命令會清除系統的頁緩存、dentries 和 inodes 緩存。執行完命令后,再次查看緩存命中率和磁盤 I/O 情況,發現緩存命中率明顯提升,磁盤 I/O 負載也逐漸恢復正常。