Redis 刪除數據后不能自動釋放內存的問題


Redis做系統緩存,歷史原因緩存策略和緩存內容不太適應增長的業務量,死皮賴臉扛着dba各種dissN個日日夜夜后決定清理一波僵屍。

但將無用的key刪除后,並沒有真正的釋放內存,查看Redis的相關文檔,也沒有釋放內存的相關命令。看着儀表盤的百分比甚是撓頭。。。

查了些資料了解了下,改日再請教請教dba大大們。。。

官方已經說了具體原因
https://redis.io/topics/memory-optimization
概括了點內容:

這不是Redis本身的問題,Redis本身確實已經調用free釋放這些內存。這應該是使用的底層C運行時的問題。

當鍵被刪除時,Redis並不總是釋放(返回)內存到操作系統。這並不是Redis的特別之處,但大多數malloc()實現都是這樣工作的。

例如一個實例有5gb的數據,然后刪除相當於2gb的數據,used_memory_rss可能仍會5 gb左右。這是因為底層分配器不能輕松地釋放內存。例如,通常將刪除的大多數鍵分配到與其他仍然存在的鍵相同的頁面中。

然而分配器是聰明和能夠重用空閑塊的內存,所以在你釋放2 gb的5 gb的數據集,當你開始再次增加鍵,您將看到used_memory_rss保持穩定而不會再增加很多。分配器基本上是嘗試重用以前(邏輯上)釋放的2GB內存。

就glibc來說,在分配大於128k的內存時使用mmap,而使用brk/sbrk在heap中分配小內存。通過mmap申請的內存在調用free后能馬上返還給系統,而heap中的內存就不一定,除非釋放的內存是heap中連續的大塊。

Redis本身沒有內存管理機制,只有一個使用量的統計功能 。每次需要創建對象,都是直接調用malloc申請,而Redis中的對象基本都比較小,所以基本都是在heap中的內存。

mark一個鏈接,全英文,改日研讀 http://goog-perftools.sourceforge.net/doc/tcmalloc.html
 
 

解決方案
通過原因可以知道,我們其實不用去關注。
特別是我們定義了maxmemory后,並且定義了maxmemory_policy,那么即使內存滿了,redis也會按照淘汰機制方案,清除一些不需要的key,來存放新的key。

但是如果已經影響到系統內存使用了,也有下面三種方案:

  • 可以通過 MEMORY PURGE命令進行內存整理。(瞬時,能稍微騰出rss內存空間)
  • 開啟activedefrag,熱碎片整理。(會占用CPU,在主線程執行,可以設置CPU占用率)
  • 重啟。

看了解決方案,然后還是去請教dba大大吧。。。。

 

 

 


免責聲明!

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



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