redis.conf之內存管理、惰性釋放

redis.conf之內存管理、惰性釋放


內存管理


redis.conf之內存管理、惰性釋放


將內存使用限制設置為指定的字節數。達到內存限制時,Redis將嘗試根據所選的逐出策略刪除密鑰(請參見maxmemory-policy)。

如果Redis無法根據該策略刪除鍵,或者如果該策略設置為'noeviction',則Redis將開始對將使用更多內存的命令(例如SET,LPUSH等)進行錯誤回覆,並將繼續回覆諸如GET之類的只讀命令。

當將Redis用作LRU或LFU緩存,或為實例設置硬盤限制(使用'noeviction'策略)時,此選項通常很有用。

警告:如果您將副本附加到實例,且該實例的maxmemory處於打開狀態,則從使用的內存數量中減去提供副本所需的輸出緩衝區的大小,以便網絡問題/重新同步不會觸發收回鍵的循環,並且反過來,副本的輸出緩衝區已滿,被逐出的DEL觸發了更多鍵的刪除,依此類推,直到數據庫完全清空。

簡而言之...如果您附加了副本,建議您為maxmemory設置一個下限,以便系統上有一些可用RAM用於副本輸出緩衝區(但是如果策略為'noeviction',則不需要這樣做)。

<code># maxmemory /<code>


MAXMEMORY POLICY:達到maxmemory時,Redis將如何選擇要刪除的內容。您可以選擇以下五種行為:

volatile-lru->使用設置了到期時間的密鑰中的近似LRU進行驅逐。

allkeys-lru->使用近似的LRU退出任何密​​鑰。

volatile-lfu->使用具有過期集的鍵中的近似LFU進行驅逐。

allkeys-lfu->使用近似的LFU退出任何密​​鑰。

volatile-random->從具有過期集的密鑰中刪除一個隨機密鑰。

allkeys-random->刪除隨機密鑰,任何密鑰。

volatile-ttl->刪除最接近到期​​時間(較小的TTL)的密鑰

noeviction->不要驅逐任何東西,只需在寫操作中返回錯誤。

LRU表示最近最少使用

LFU表示最少使用

LRU,LFU和volatile-ttl均使用近似隨機算法實現。

注意:

使用上述任何策略,當沒有合適的退出鍵時,Redis將在寫入操作中返回錯誤。

在撰寫本文時,這些命令是:set setnx setex append incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd interinterstore sunion sunionstore sdiff sdiffstore zadd zincrby zunionstore zinterstore hset hsetnx hmset hincrby mcrby decrby

默認值為:

<code># maxmemory-policy noeviction/<code>


LRU,LFU和最小TTL算法不是精確算法,而是近似算法(以節省內存),因此您可以針對速度或準確性進行調整。 對於默認情況,Redis將檢查五個鍵並選擇最近使用的鍵,您可以使用以下配置指令更改樣本大小。

默認值為5會產生足夠好的結果。 10非常接近真實的LRU,但是會花費更多的CPU。 3更快,但不是很準確。

<code># maxmemory-samples 5/<code>


從Redis 5開始,默認情況下,副本將忽略其maxmemory設置(除非在故障轉移後或手動提升為主副本)。這意味著密鑰的移出將僅由主機處理,將DEL命令作為副本在主機側逐出,將DEL命令發送到副本。

此行為可確保主副本和副本始終保持一致,這通常是您想要的,但是,如果副本是可寫的,或者您希望副本具有不同的內存設置,並且您確定對副本執行的所有寫操作都是冪等的,那麼您可以更改此默認設置(但請務必瞭解您的操作)。

請注意,由於默認情況下該副本不會退出,因此它可能會結束使用比通過maxmemory設置的內存更多的內存(某些緩衝區在副本上可能會更大,或者數據結構有時會佔用更多內存等等)。因此,請確保您監視副本,並確保副本具有足夠的內存,以免在主副本達到配置的最大內存設置之前就不會遇到真正的內存不足情況。

<code># replica-ignore-maxmemory yes/<code>

惰性釋放

Redis有兩個刪除鍵的原語。一種稱為DEL,它是對象的阻塞刪除。這意味著服務器停止處理新命令,以便以同步方式回收與對象關聯的所有內存。如果刪除的鍵與一個小對象相關聯,則執行DEL命令所需的時間將非常短,並且與Redis中的大多數其他O(1)或O(log_N)命令相當。但是,如果鍵與包含數百萬個元素的聚合值關聯,則服務器可能會阻塞很長時間(甚至幾秒鐘)以完成操作。

由於上述原因,Redis還提供了非阻塞刪除原語,例如UNLINK(非阻塞DEL)以及FLUSHALL和FLUSHDB命令的ASYNC選項,以便在後臺回收內存。這些命令在固定時間內執行。另一個線程將盡可能快地在後臺逐漸釋放對象。

用戶可以控制FLUSHALL和FLUSHDB的DEL,UNLINK和ASYNC選項。由應用程序的設計來決定何時使用一個或另一個是一個好主意。但是,Redis服務器有時必須刪除鍵或刷新整個數據庫,這是其他操作的副作用。特別是在以下情況下,Redis會獨立於用戶調用刪除對象:

1)在逐出時,由於maxmemory和maxmemory策略配置,為了在不超過指定的內存限制的情況下為新數據騰出空間。

2)由於過期:必須從內存中刪除具有相關生存時間的密鑰(請參閱EXPIRE命令)。

3)由於將數據存儲在可能已經存在的鍵上的命令的副作用。例如,當RENAME命令被另一舊密鑰內容替換時,它可能會刪除它。同樣,SUNIONSTORE或SORT with STORE選項可能會刪除現有密鑰。 SET命令本身會刪除指定鍵的所有舊內容,以便將其替換為指定的字符串。

4)在複製過程中,當副本與其主副本執行完全重新同步時,將刪除整個數據庫的內容,以便加載剛傳輸的RDB文件。

在上述所有情況下,默認設置都是以阻塞方式刪除對象,就像調用DEL一樣。但是,您可以專門配置每種情況,以便使用以下配置指令以非阻塞方式釋放內存,例如調用UNLINK的情況:

<code>lazyfree-lazy-eviction nolazyfree-lazy-expire nolazyfree-lazy-server-del noreplica-lazy-flush no/<code>


分享到:


相關文章: