Redis從入門到放棄系列(七) 過時、內存淘汰策略

Redis從入門到放棄系列(七) 過時、內存淘汰策略

本文例子基於:5.0.4redis

過時策略

Redis對於設置了過時時間的key的過時策略有兩種數據庫

  • 惰性刪除
  • 定時隨機刪除

惰性刪除

惰性刪除的時機在於當你要獲取該key的時候再去作判斷.這裏我以String類型做爲演示畫圖: 服務器

string獲取key流程
GitHub,Social Coding

int expireIfNeeded(redisDb *db, robj *key) {
    if (!keyIsExpired(db,key)) return 0;

    /* If we are running in the context of a slave, instead of * evicting the expired key from the database, we return ASAP: * the slave key expiration is controlled by the master that will * send us synthesized DEL operations for expired keys. * * Still we try to return the right information to the caller, * that is, 0 if we think the key should be still valid, 1 if * we think the key is expired at this time. */
    if (server.masterhost != NULL) return 1;

    /* Delete the key */
    server.stat_expiredkeys++;
    propagateExpire(db,key,server.lazyfree_lazy_expire);
    notifyKeyspaceEvent(NOTIFY_EXPIRED,
        "expired",key,db->id);
    return server.lazyfree_lazy_expire ? dbAsyncDelete(db,key) :
                                         dbSyncDelete(db,key);
}
複製代碼

咱們發現,當key有設置了過時時間,而後key已通過期的話,那麼redis會判斷是否開啓了lazyfree_lazy_expire ,若是開啓的話,那麼異步刪除.沒有則同步直接刪除.(4.0以後的特性,當大key刪除的時候很是有用)dom

定時隨機刪除

當有了惰性刪除以後,知足了一部分的需求,但是在實際應用中,會存在有過時而沒有被訪問到的key,這樣就會平白的佔據着內存.那麼redis是經過怎樣去解決的呢?異步

redis會有一個定時任務,每秒跑10次。性能

  • 隨機選擇設置了過時時間的20個key進行過時檢測
  • 刪除全部已通過期的keys
  • 若是超過25%的密鑰過時,請從步驟1從新開始。

因爲redis是單線程,若是任由上面定時隨機刪除策略的話,那麼當有大量的key過時的時候,redis會存在沒法處理客戶端請求的狀況?不不不,其實redis在作定時隨機刪除的時候,有一個限制,就是設置掃描時間的上限,默認至多爲25ms(timelimit = 1000000*ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC/server.hz/100;),因此當客戶端請求到來時,服務器正處於過時掃描期間,客戶端會等到至多25ms而後進行其業務處理.this

那麼若是redis設置超時時間太短的話,有可能出現大量超時鏈接,爲了不這個問題,建議是在設置過時時間是時候,加多一個隨機範圍,避免大量的key同時過時~spa

當有作主從的時候,從庫是不會開啓定時隨機刪除的,都是依賴master開啓的aof文件中增長一條del命令,而後從庫去執行該語句實現刪除該過時key線程

內存淘汰策略

咱們知道redis是純內存數據庫,若是redis使用超出了內存限制的時候,便會產生swap行爲. 使用磁盤來操做相比內存來講,性能降低的不是一丁半點。 這時候咱們須要設置redis最大使用內存code

maxmemory <bytes>
複製代碼

經過設置maxmemory,當使用內存超過maxmemory的時候,redis提供了幾種可選的策略來控制內存的使用量

  • noeviction (當內存不足以容納新寫入數據時,新寫入操做會報錯)
  • allkeys-lru (當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的key)
  • allkeys-random (當內存不足以容納新寫入數據時,在鍵空間中,隨機移除某個key)
  • volatile-lru (當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,移除最近最少使用的key)
  • volatile-random (當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,隨機移除某個key)
  • volatile-ttl (當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,有更早過時時間的key優先移除)

寫在最後

端午三天就這樣過去啦~願各位看官好好休息,而後繼續起來搬磚~hhhhh

相關文章
相關標籤/搜索