2011-12-28 59 views
27

我完全可以關閉,但是在開始添加持久性功能之前,緩存存儲的工作原理是,物品基於其ttl將過期。如果商店開始填充可用的RAM,他們每個人都有自己的算法,用於過期商店中最不「重要」的密鑰。當RAM開始填滿時,Redis如何工作?

現在我讀了Redis有持久性功能。但是你可以關閉它們。假設你關閉持久性,當RAM填滿時會發生什麼? Redis如何決定要過期的內容?

我希望在沒有TTL的情況下擁有大量數據,並且要確保Redis能夠確定要過期的數據是否安全。

回答

35

我不認爲這個問題是有關虛擬內存管理,但更多的項目在Redis的到期,這是一個完全不同的主題。

與memcached相反,Redis不僅是一個緩存。因此,用戶應該使用各種機制來選擇物品驅逐策略。你可以驅逐你所有的物品,或者只是其中的一部分。

的一般策略應與maxmemory和maxmemory策略參數在配置文件中進行選擇,下面描述下:

# Don't use more memory than the specified amount of bytes. 
# When the memory limit is reached Redis will try to remove keys with an 
# EXPIRE set. It will try to start freeing keys that are going to expire 
# in little time and preserve keys with a longer time to live. 
# Redis will also try to remove objects from free lists if possible. 
# 
# If all this fails, Redis will start to reply with errors to commands 
# that will use more memory, like SET, LPUSH, and so on, and will continue 
# to reply to most read-only commands like GET. 
# 
# WARNING: maxmemory can be a good idea mainly if you want to use Redis as a 
# 'state' server or cache, not as a real DB. When Redis is used as a real 
# database the memory usage will grow over the weeks, it will be obvious if 
# it is going to use too much memory in the long run, and you'll have the time 
# to upgrade. With maxmemory after the limit is reached you'll start to get 
# errors for write operations, and this may even lead to DB inconsistency. 
# 
maxmemory <bytes> 

# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory 
# is reached? You can select among five behavior: 
# 
# volatile-lru -> remove the key with an expire set using an LRU algorithm 
# allkeys-lru -> remove any key accordingly to the LRU algorithm 
# volatile-random -> remove a random key with an expire set 
# allkeys->random -> remove a random key, any key 
# volatile-ttl -> remove the key with the nearest expire time (minor TTL) 
# noeviction -> don't expire at all, just return an error on write operations 
# 
# Note: with all the kind of policies, Redis will return an error on write 
#  operations, when there are not suitable keys for eviction. 
# 
#  At the date of writing this commands are: set setnx setex append 
#  incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd 
#  sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby 
#  zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby 
#  getset mset msetnx exec sort 
# 
# The default is: 
# 
maxmemory-policy volatile-lru 

# LRU and minimal TTL algorithms are not precise algorithms but approximated 
# algorithms (in order to save memory), so you can select as well the sample 
# size to check. For instance for default Redis will check three keys and 
# pick the one that was used less recently, you can change the sample size 
# using the following configuration directive. 
# 
maxmemory-samples 3 

然後個別項目到期可以使用下面的命令來設置: EXPIRE EXPIREAT 每項到期屬性對volatile- *策略很有用。 到期也可以使用PERSIST刪除。

過期屬性會增加一些內存開銷,所以應該只在需要時使用它。

最後,值得一提的是,一個對象的一部分不能過期,只有整個對象本身。例如,對應於密鑰的整個列表或集合可以過期,但是單個列表或集合項目不能。

+0

非常好,謝謝。所以默認的LRU算法正是我想要的。只需要將其設置爲「狀態」服務器即可。 – joedevon 2011-12-28 21:31:40

2

請閱讀Redis文檔中的Virtual Memory一章。 相關部分:

虛擬機,最大內存設置 虛擬機,最大內存設置指定Redis的多少內存是免費的磁盤啓動交換值之前使用。

基本上,如果未達到此內存限制,將不會交換對象,Redis將像往常一樣處理內存中的所有對象。然而,一旦這個限制被擊中,足夠的對象被換出以將內存返回到剛好在限制之下。

被交換的對象主要是具有最高「年齡」的那些對象(即沒有被使用過的秒數),但是對象的「可交換性」也與其大小的對數成比例在記憶中。因此,雖然較舊的對象是首選,但較大的對象在大約相同的年齡時會先換出。

警告:由於密鑰無法換出,因此如果單獨使用密鑰的空間大於限制,Redis將無法遵守vm-max-memory設置。

該設置的最佳值是足以容納「工作集」數據的RAM。實際上,只要給Redis儘可能多的內存,交換就會更好。

UPDATE 至於Redis的2.4(好像在Redis的網站的官方文檔不會更新到版本),它不建議使用虛擬機。

redis.conf說:

### WARNING! Virtual Memory is deprecated in Redis 2.4 
### The use of Virtual Memory is strongly discouraged. 
+0

由於虛擬內存已被棄用,當RAM內存限制命中時,使用磁盤內存的最佳方式是什麼? – harsimranb 2017-04-12 05:51:48

+1

@harsimranb不要。如果你到了需要磁盤的階段,你已經誤用了Redis(或者你應該增加內存,取決於你的用例)。 – 2017-04-12 07:54:53

2

要麼設置TTL(並讓Redis爲您處理過期),要麼將您的項目與您自己的老化數據一起發佈,可能存儲爲(timestamp,key)元組的ZSET,您可以根據這些元組執行自己的緩存清理你自己的需求。

8

Didier正在說明如何完成這項工作。只是說明了一些附加元素(其中一個似乎是從他的崗位省略):

  1. 指定最大內存大小佔用該節點上大部分的可用內存(留下一些對操作系統和其他進程和一些緩衝區)。這將確保內容不會被分頁,因此操作是FAST。
    1. 如果您沒有通過應用程序設置TTL /過期的密鑰,那麼使用「allkeys-lru」方法很重要。否則,Redis不會過期任何事情(因爲沒有任何密鑰是易失性的),並且一旦所有內存都用完了,你就會開始出錯 - 基本上,你將無法再進行更多的設置操作。

maxmemory樣本10

這是Redis的將採取,然後刪除的樣本的數目:

  • 當使用LRU用於去除鍵,它設置以下設置是重要從這些之中的LRU密鑰。默認值是3,但實際上這個值太低 - 可能意味着舊鍵可能仍然存活。將此設置得太高將會成爲Redis的開銷。 在設置之前,您可能需要稍微嘗試一下此設置。我們使用的值爲10.

  • +0

    感謝您的有益補充。 – joedevon 2012-01-04 22:55:20

    +0

    你完全正確@Gur,我只是用不同的maxmemory和maxmemory-policy值來測試它。 – 2016-04-26 21:55:25