Linux 核心為提升 I/O 效能,會積極使用閒置實體記憶體作為 Page Cache (頁面快取)、Dentry Cache (目錄項快取)、Inode Cache (索引節點快取)。在效能測試、磁碟基準測試、記憶體壓力測試前,常需手動釋放快取以獲得可重現的基線。本文說明 /proc/sys/vm/drop_caches 三種模式、sync 先行必要性、自動化腳本與生產環境風險控制。
| 數值 | 釋放內容 | 適用場景 |
|---|---|---|
1 | Page Cache (檔案資料頁) | 僅釋放檔案資料快取,保留目錄/索引結構 |
2 | Dentry + Inode Cache | 釋放檔案系統元資料快取,保留檔案資料 |
3 | Page Cache + Dentry + Inode | 完整釋放 (最常用) |
# 1. 確認目前快取佔用
free -h
# total used free shared buff/cache available
# Mem: 31G 2.1G 25G 120M 4.2G 28G
# 2. 同步髒頁至磁碟 (關鍵!避免資料遺失)
sync
# 3. 釋放所有快取
echo 3 > /proc/sys/vm/drop_caches
# 4. 驗證釋放效果
free -h
# buff/cache 應大幅下降
#!/bin/bash
# drop_caches_safe.sh
# 用途:在負載低谷期釋放快取,避免衝擊線上服務
THRESHOLD_PCT=80 # 記憶體使用率超過 80% 才執行
MIN_FREE_GB=2 # 釋放後至少保留 2GB 可用
mem_info=$(free -b | awk '/^Mem:/ {print $2, $7}') # total, available
total=$(echo $mem_info | awk '{print $1}')
avail=$(echo $mem_info | awk '{print $2}')
usage_pct=$(( (total - avail) * 100 / total ))
if (( usage_pct > THRESHOLD_PCT )); then
sync
echo 3 > /proc/sys/vm/drop_caches
logger -t drop_caches "Released caches: usage was ${usage_pct}%"
else
logger -t drop_caches "Skipped: usage ${usage_pct}% <= ${THRESHOLD_PCT}%"
fi
加入 cron:0 3 * * * /usr/local/sbin/drop_caches_safe.sh (每日凌晨 3 點執行)。
| 風險 | 影響 | 緩解措施 |
|---|---|---|
| 後續讀取需重新從磁碟載入 | 延遲飆升、IOPS 瞬間暴增 | 僅在維護視窗/低峰期執行;分批釋放 (先 1 再 2) |
| 資料庫熱點資料被驅逐 | 查詢效能下降 10~50% | 資料庫啟用 O_DIRECT 繞過 Page Cache (InnoDB/MyRocks 預設) |
| Swap 使用率上升 | 匿名頁被換出 | 調整 vm.swappiness、vm.vfs_cache_pressure |
# /etc/sysctl.d/99-cache-pressure.conf
vm.vfs_cache_pressure = 100 # 預設 100,調大加速 dentry/inode 回收
vm.swappiness = 60 # 預設 60,資料庫建議 10~30
vm.dirty_ratio = 15 # 髒頁比例上限
vm.dirty_background_ratio = 5 # 背景回寫啟動閾值
套用:sysctl --system
# 查看快取佔用前幾大的檔案 (需 root)
find /proc/*/fd -type l -lname '/*' 2>/dev/null | \
xargs -r ls -l 2>/dev/null | awk '{print $9, $5}' | sort -k2 -nr | head -20
# 或使用 pcstat (golang 工具)
go install github.com/tobert/pcstat@latest
pcstat /var/lib/mysql /var/log /home
掌握 drop_caches 正確用法與風險控制,能在效能基準測試、記憶體壓力演練、容器資源配額驗證等場景獲得精準、可重現的實驗環境,同時避免對線上服務造成不可預期的衝擊。