# 第 20 章:刪除數據後,為什麼內存佔用率還是很高? 當你從 Redis 中刪除大量資料後,卻發現 **內存佔用率並沒有明顯下降**,這其實是 Redis 設計上的行為。以下是重點整理: --- ### 1. 內存管理方式:惰性回收(Lazy Freeing) - Redis 採用 jemalloc 作為記憶體配置器,當刪除鍵時,只是「標記」為無效,**實際的記憶體不一定會立刻歸還給系統**。 - jemalloc 會將這些空間保留給 Redis 未來的物件重複使用,而不是立即釋放。 ### 2. fork 操作會保留頁面(Copy-on-Write) - 在執行 RDB 或 AOF 的 fork 操作時,會複製整個進程記憶體,Redis 為了效率,在此期間會**保留這些頁面不被釋放**,導致內存暫時居高不下。 ### 3. 內存碎片 - jemalloc 的分配策略之一,是按照一系列固定的大小劃分內存空間。例如,Redis 申請一個 20 字節的空間保存數據,jemalloc 就會分配 32 字節 - Redis 使用 jemalloc 管理記憶體,當大小不一的記憶體塊反覆分配與釋放時,就可能導致 **記憶體碎片**。 例:  ## 如何判斷是否有內存碎片? ### 使用 `INFO memory` ```bash INFO memory ``` #### 重點欄位: | 欄位名稱 | 說明 | | ------------------------- | ---------------------------------------------- | | `used_memory` | Redis 實際使用的記憶體(bytes) | | `used_memory_rss` | 作業系統分配給 Redis 的實體記憶體(bytes) | | `mem_fragmentation_ratio` | 記憶體碎片率 (`used_memory_rss / used_memory`) | #### 判讀碎片率: | 碎片率 (`mem_fragmentation_ratio`) | 狀況說明 | | ---------------------------------- | -------------------- | | 約 1.0 ~ 1.2 | 正常範圍 | | 約 1.3 ~ 1.5 | 輕度碎片,可觀察 | | > 1.5 | 有明顯碎片,建議清理 | | > 2.0 | 嚴重碎片,需優先處理 | ## 🧹 如何清理內存碎片? ### ✅ 方法一:使用 `MEMORY PURGE`(Redis 6.0+) ```bash MEMORY PURGE ``` - 主動讓 jemalloc 將未使用的記憶體歸還給作業系統。 - 不會中斷服務,但釋放效率不一定高,依實際情況而定。 --- ### 🔄 方法二:重啟 Redis ```bash redis-cli shutdown # 然後重新啟動 Redis 服務 ``` - 完全釋放記憶體,是最有效的碎片清理方式。 - 有短暫停機風險,建議搭配 Redis Sentinel、Cluster 或 proxy 工具。 --- ### 🔄 方法三:啟用背景內存碎片整理(active defrag) ```bash CONFIG SET activedefrag yes CONFIG SET active-defrag-threshold-lower 10 CONFIG SET active-defrag-threshold-upper 100 ``` - Redis 會在背景自動進行碎片整理。 - 不影響主線程,適合長期執行的 Redis 服務。 - Redis 4.0 起支援,建議 Redis 5.0+ 開啟。 --- ### 📊 清理方式比較 | 方法 | 即時性 | 是否會中斷服務 | 適合情境 | | --------------- | -------- | -------------- | -------------------- | | `MEMORY PURGE` | 中等 | ❌ 不會中斷 | 輕度碎片 | | 重啟 Redis | 高 | ✅ 會中斷 | 嚴重碎片或記憶體異常 | | `active defrag` | 緩慢進行 | ❌ 不會中斷 | 長時間運行的服務 | ## ⚙️ active-defrag 參數說明與差異 Redis 提供多個 `active-defrag-*` 參數來微調內存碎片整理行為,以下是各參數的比較與使用情境: ### 📋 參數功能表 | 參數名稱 | 功能 | 說明 | | ------------------------------- | ------------------ | -------------------------------------- | | `active-defrag-threshold-lower` | 碎片啟動門檻(低) | 碎片率超過此值時,開始啟動 defrag | | `active-defrag-threshold-upper` | 碎片啟動門檻(高) | 超過此值時會使用最大 defrag 強度 | | `active-defrag-ignore-bytes` | 忽略碎片最小體積 | 若碎片少於此值(bytes),則不進行整理 | | `active-defrag-cycle-min` | 最小 defrag 負載 | Redis 至少花多少 CPU 百分比處理 defrag | | `active-defrag-cycle-max` | 最大 defrag 負載 | Redis 最多允許的 defrag CPU 百分比 | --- ### 🧠 使用說明與建議設定 ```bash CONFIG SET active-defrag-threshold-lower 10 CONFIG SET active-defrag-threshold-upper 100 CONFIG SET active-defrag-ignore-bytes 1048576 CONFIG SET active-defrag-cycle-min 5 CONFIG SET active-defrag-cycle-max 75 ``` 這表示: - 當 `mem_fragmentation_ratio > 1.1` 且碎片量 > 1MB 時啟動 defrag。 - 當碎片率 > 2.0(100)時,以最大 75% CPU 比例進行整理。 - 即使在低碎片情況也保留 5% CPU 整理。 --- ### 📌 小提醒 - 這些設定適合 Redis 長時間運行的環境(如快取伺服器)。 - 若對記憶體管理非常敏感,建議搭配監控系統觀察調整效果。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up