Redis刪除大量key後,佔用的系統記憶體卻沒有釋放?
我們首先來看看官方關於Redis記憶體管理的說明。
原文如下:https://redis.io/topics/memory-optimization#memory-allocation
Memory allocation
To store user keys, Redis allocates at most as much memory as the setting enables (however there are small extra allocations possible).maxmemory
The exact value can be set in the configuration file or set later via CONFIG SET (see Using memory as an LRU cache for more info). There are a few things that should be noted about how Redis manages memory:
Redis will not always free up (return) memory to the OS when keys are removed. This is not something special about Redis, but it is how most malloc() implementations work. For example if you fill an instance with 5GB worth of data, and then remove the equivalent of 2GB of data, the Resident Set Size (also known as the RSS, which is the number of memory pages consumed by the process) will probably still be around 5GB, even if Redis will claim that the user memory is around 3GB. This happens because the underlying allocator can't easily release the memory. For example often most of the removed keys were allocated in the same pages as the other keys that still exist.
The previous point means that you need to provision memory based on your peak memory usage. If your workload from time to time requires 10GB, even if most of the times 5GB could do, you need to provision for 10GB.However allocators are smart and are able to reuse free chunks of memory, so after you freed 2GB of your 5GB data set, when you start adding more keys again, you'll see the RSS (Resident Set Size) stay steady and not grow more, as you add up to 2GB of additional keys. The allocator is basically trying to reuse the 2GB of memory previously (logically) freed.Because of all this, the fragmentation ratio is not reliable when you had a memory usage that at peak is much larger than the currently used memory. The fragmentation is calculated as the physical memory actually used (the RSS value) divided by the amount of memory currently in use (as the sum of all the allocations performed by Redis). Because the RSS reflects the peak memory, when the (virtually) used memory is low since a lot of keys / values were freed, but the RSS is high, the ratio will be very high.RSS / mem_used If is not set Redis will keep allocating memory as it finds fit and thus it can (gradually) eat up all your free memory. Therefore it is generally advisable to configure some limit. You may also want to set to (which is not the default value in some older versions of Redis).maxmemorymaxmemory-policynoeviction.It makes Redis return an out of memory error for write commands if and when it reaches the limit - which in turn may result in errors in the application but will not render the whole machine dead because of memory starvation.
翻譯如下:
記憶體分配
為了儲存使用者金鑰,Redis最多分配設定允許的記憶體(但是也有少量的額外分配),確切的值可以在配置檔案中設定,也可以在以後通過配置集進行設定(有關更多資訊,請參閱將記憶體用作LRU快取)。
關於Redis如何管理記憶體,需要注意以下幾點:當金鑰被移除時,Redis並不總是將記憶體釋放(返回)給作業系統。這並不是Redis的獨特之處,它是大多數malloc()實現的工作方式。例如,如果您用5GB的資料填充一個例項,然後刪除相當於2GB的資料,則駐留集大小(Resident Set Size)(也稱為RSS,即程式消耗的記憶體頁數)可能仍將在5GB左右,即使Redis會聲稱使用者記憶體約為3GB。發生這種情況是因為底層分配器無法輕鬆釋放記憶體。例如,通常大多數被移除的鍵與仍然存在的其他鍵分配在同一頁中。前一點意味著您需要根據峰值記憶體使用情況來配置記憶體。如果您的工作負載不時需要10GB,即使大多數情況下5GB都可以,您也需要為10GB進行調配。不過,分配器是智慧的,能夠重用空閒記憶體塊,因此,當您釋放了2GB的5GB資料集後,當您再次開始新增更多金鑰時,您將看到RSS(駐留集大小)保持穩定,而不會增加,因為您新增了2GB的額外金鑰。分配器基本上是在嘗試重用先前(邏輯上)釋放的2GB記憶體。
正因為如此,當記憶體使用率峰值遠大於當前使用的記憶體時,碎片率是不可靠的。碎片計算為實際使用的實體記憶體(RSS值)除以當前使用的記憶體量(作為Redis執行的所有分配的總和)。因為RSS反映了峰值記憶體,當(實際上)使用的記憶體很低,因為釋放了很多鍵/值,但是RSS很高,那麼這個比率會非常高。如果RSS/mem_used沒有設定,Redis將繼續分配它認為合適的記憶體,因此它可以(逐漸)吃掉你所有的空閒記憶體。因此,通常建議配置一些限制。您可能還需要設定為(這不是某些舊版本的Redis的預設值)
它使Redis在達到限制時返回write命令的記憶體不足錯誤-這反過來可能導致應用程式出錯,但不會因為記憶體不足而導致整個機器當機。
綜上所述(官方說明),我們不用再擔心這個問題了。其實這樣也有個好處,就是如果再有key寫入,則無需再去申請系統記憶體,來減少記憶體申請操作。如果非要把這些Redis空閒空間返還作業系統可以執行命令MEMORY PURGE來進行空間整理,或者開啟activedefrag,進行熱碎片整理(該操作在主執行緒執行,會佔用CPU,可以設定CPU佔用率)。
相關文章
- Redis的資料被刪除,佔用記憶體咋還那麼大?Redis記憶體
- Redis 檢視所有 key 的 value 值所佔記憶體大小Redis記憶體
- Redis刪除大KeyRedis
- [Redis]過期刪除和記憶體淘汰Redis記憶體
- Chrome 再次最佳化記憶體佔用問題,新增記憶體釋放開關Chrome記憶體
- 【Redis】 redis-cluster刪除指定的keyRedis
- Redis 實用小技巧——批次刪除指定的 keyRedis
- Linux系統手動釋放記憶體快取Linux記憶體快取
- Win10系統下taobaoprotect.exe程式佔記憶體高怎麼刪除Win10記憶體
- vector 的記憶體釋放記憶體
- XCode釋放記憶體XCode記憶體
- SHARED POOL中KGH: NOACCESS佔用大量記憶體的問題分析記憶體
- 記憶體的分配與釋放,記憶體洩漏記憶體
- Redis 實戰 —— 12. 降低記憶體佔用Redis記憶體
- 【Redis】過期鍵刪除策略和記憶體淘汰策略Redis記憶體
- Redis 中的過期刪除策略和記憶體淘汰機制Redis記憶體
- redis的記憶體滿了之後,redis如何回收記憶體嗎Redis記憶體
- Redis Quicklist 竟讓記憶體佔用狂降50%?RedisUI記憶體
- win10記憶體佔用過高程式沒多少怎麼辦 win10記憶體佔用過高的方法Win10記憶體
- python物件的記憶體佔用Python物件記憶體
- win10有哪些佔記憶體又沒必要的服務 win10佔記憶體又沒必要的服務怎麼關閉Win10記憶體
- win10怎麼刪除虛擬記憶體 刪除win10虛擬記憶體的方法Win10記憶體
- Redis刪除特定字首key的優雅實現Redis
- Redis 刪除1.2億指定字首的keyRedis
- win10如何設定自動釋放記憶體_win10怎麼設定自動清理系統垃圾釋放記憶體Win10記憶體
- Redis詳解(十一)------ 過期刪除策略和記憶體淘汰策略Redis記憶體
- golang 釋放記憶體機制的探索Golang記憶體
- 如何主動釋放 HeapIdle 的記憶體API記憶體
- win10記憶體佔用高怎麼解決_win10系統記憶體佔用高解決步驟Win10記憶體
- YOLO例項分割預測後刪除視訊記憶體YOLO記憶體
- influxdb記憶體佔用剖析UX記憶體
- 資源記憶體佔用記憶體
- 面試官:Redis中大Key怎麼刪除?面試Redis
- Mysql InnoDB刪除資料後釋放磁碟空間的方法MySql
- C# 垃圾回收釋放記憶體C#記憶體
- MySQL 5.7的表刪除資料後的磁碟空間釋放MySql
- win10系統快速啟動佔用記憶體如何解決_win10快速啟動佔用記憶體高的解決教程Win10記憶體
- .Net記憶體管理釋放的兩種方式記憶體