1. 程式人生 > 實用技巧 >redis的過期策略以及記憶體淘汰機制

redis的過期策略以及記憶體淘汰機制

分析:這個問題其實相當重要,到底redis有沒有用到家,這個問題就可以看出來。比如你的redis只能儲存5G資料,課時你寫了10G,那會刪除5G的資料。怎麼刪的,則會個問題思考過嗎?還有,你的資料已經設定了過期時間了,記憶體佔有率還是比較高,有思考過嗎?且看我來講解:

redis是採用定期刪除+惰性刪除策略

為什麼不用定時刪除策略?:

定時刪除,用一個定時器來負責監視key,當這個key過期就自動刪除,雖然記憶體及時釋放,但是十分消耗CPU資源,在大併發請求下CPU要儘可能的把時間都用在處理請求,而不是刪除key,因此沒有采用這一策略

定期刪除+惰性刪除是如何工作的呢?

定時刪除,redis預設每100ms檢查是否有過期的key,有過期的key則刪除。需要說明的是redis不是每個100ms將所有的key檢查一次,而是隨機抽取進行檢查(如果每100ms,全部key進行檢查,redis豈不是卡死了)。因此,如果只採用定期策略,會導致很多key到時間沒有刪除

也就是使用定時刪除會導致刪除不完全,於是惰性刪除就登場了。

也就是說你在獲取key的時候,redis會檢查一下,這個key如果設定過期時間那麼是否過期了?如果過期 此時就刪除。

採用定期刪除+惰性刪除就沒問題了呢?

不是的如果定期刪除沒有刪除key,然後你也沒有及時去請求這個key,也就是說惰性刪除也沒有生效。這樣redis的記憶體會越來越高,那麼就應該採用記憶體淘汰機制。

在redis.conf中有一行配置

# maxmemory-policy volatile-lru

該配置就是配記憶體淘汰策略的(什麼,你沒配過?好好反省一下自己)
1)noeviction:當記憶體不足以容納新寫入資料時,新寫入操作會報錯。應該沒人用吧。


2)allkeys-lru:當記憶體不足以容納新寫入資料時,在鍵空間中,移除最近最少使用的key。推薦使用,目前專案在用這種。
3)allkeys-random:當記憶體不足以容納新寫入資料時,在鍵空間中,隨機移除某個key。應該也沒人用吧,你不刪最少使用Key,去隨機刪。
4)volatile-lru:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,移除最近最少使用的key。這種情況一般是把redis既當快取,又做持久化儲存的時候才用。不推薦
5)volatile-random:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,隨機移除某個key。依然不推薦
6)volatile-ttl:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,有更早過期時間的key優先移除。不推薦

ps:如果沒有設定 expire 的key, 不滿足先決條件(prerequisites); 那麼 volatile-lru, volatile-random 和 volatile-ttl 策略的行為, 和 noeviction(不刪除) 基本上一致。

Redis持久化原理及配置詳解

Redis的強大功能很大程度上是由於其將所有資料都儲存在記憶體中。為了使Redis在重啟後仍能保證資料不丟失,需要將資料從記憶體中以某種形式持久化到硬碟中。Redis支援兩種持久化方式,一種是RDB方式,一種是AOF方式。可以單獨使用其中一種或兩種結合使用。(持久化即將資料儲存到磁碟,機器宕機或者重啟資料不丟失,儲存到記憶體中的資料會丟失)


Redis有兩種持久化的方式:快照(RDB檔案)和追加式檔案(AOF檔案):

  • RDB持久化方式會在一個特定的間隔儲存那個時間點的一個數據快照。
  • AOF持久化方式則會記錄每一個伺服器收到的寫操作。在服務啟動時,這些記錄的操作會逐條執行從而重建出原來的資料。寫操作命令記錄的格式跟Redis協議一致,以追加的方式進行儲存。
  • Redis的持久化是可以禁用的,就是說你可以讓資料的生命週期只存在於伺服器的執行時間裡。
  • 兩種方式的持久化是可以同時存在的,但是當Redis重啟時,AOF檔案會被優先用於重建資料。

RDB概述:

RDB是在某個時間點將資料寫入一個臨時檔案,持久化結束後,用這個臨時檔案替換上次持久化的檔案,達到資料恢復。
優點:使用單獨子程序來進行持久化,主程序不會進行任何IO操作,保證了redis的高效能
缺點:RDB是間隔一段時間進行持久化,如果持久化之間redis發生故障,會發生資料丟失。所以這種方式更適合資料要求不嚴謹的時候
RDB是Redis預設的持久化方式,所以RDB是預設開啟的

redis.conf中的具體配置引數如下;