redis基礎系列二:淘汰策略

笨小孩發表於2021-08-30
[TOC]
  • 問:redis記憶體溢位後怎麼辦?

    答:當然是清除無效記憶體

  • 問:清除記憶體需要手動清除嗎?這會不會太低效了在叢集當中?

    答:手動清除當然低效且不安全,當然不可取

  • 問:如果不手動清除,那麼redis會自動清除嗎

    答:redis內部已經實現了自動清除功能–淘汰策略,只需要簡單配置幾個引數,redis根據引數執行相應淘汰策略進行自動淘汰掉無效資料;

  • 問:那是那幾個關鍵引數呢?

    答:hz(自動清除頻率);max_memory(最大記憶體)+maxmemory-policy(最大記憶體策略)

  • 問:那我只瞭解這幾個引數就行了吧,沒必要再浪費時間往下看了吧?

    答:從實戰角度你知道這幾個引數確實就夠了,但是作為一個愛顯擺(面試時候)的程式設計師,你是不是應該瞭解實現原理以及其中的利害關係(閉坑大法),這樣是不是出問題排查的時候也是有理有據(哈哈)


  • redis內部針對記憶體溢位有兩方面的治理:時間+空間
    下面針對兩種時間清除快取和超過空間實體記憶體進行清除的策略進行說明
  • 如果長時間不清理過期時間段的key,那麼會存在記憶體溢位的壞場景,這種情況是不被允許的
  • 常見清楚過期key的方式有兩種:惰性清除和定時清除(非佇列,佔用資源)

惰性清除

  • key被呼叫的時候進行清除
  • 這種情況,隨著時間推移,key會越來越多,有可能發生記憶體溢位,因此redis提供另外一種方式:定時清除作為輔助

定時清除

  • 非連結串列(redis單執行緒,連結串列相較比較消耗CPU資源,對效能大打折扣)
  • 通過配置hz生效
  • 預設開啟,並且hz=10
  • hz範圍1-500
  • hz越大,資料延遲性越低,響應越慢,(對效能影響較大)
  • hz越小,資料延遲性越高,響應越快
  • hz科學的範圍為1-100
  • 如果對資料實時性要求比較高的場景,建議提高,否則建議預設
  • 定時刪除採用的是自適應的演算法進行刪除
  • 所謂自適應就是開啟了動態修改hz的演算法(dynamic-hz yes

自適應演算法流程

  • 定時隨機檢測每個庫的20個key,並執行過期刪除
  • 如果檢測過的1/4(25%)已經過期則進行繼續刪除直到:過期key低於檢測key的25%或超時為止,慢模式下超時時間為25ms
  • 如果慢模式超時,則在Redis觸發內部事件之前再次以快模式執行回收過期鍵任務
  • 快模式過期時間為1ms,且2s內只能執行一次
  • 快慢模式內部刪除邏輯相同,只是超時時間不同
  • 記憶體大於最大設定記憶體max_memory進行觸發
  • 記憶體大於最大設定記憶體,或出現報錯(預設情況下)
  • 對於記憶體溢位淘汰有六種策略

六種記憶體淘汰策略

  • noeviction(不淘汰)
    • 預設策略
    • 當記憶體不足以容納新寫入資料時,新寫入操作會報錯
    • 此方案實際當中沒人用
  • allkeys-lru(最近最少使用key)
    • 當記憶體不足以容納新寫入資料時,在鍵空間中,移除最近最少使用的 Key,推薦使用
  • allkeys-random(隨機淘汰)
    • 當記憶體不足以容納新寫入資料時,在鍵空間中,隨機移除某個 Key。
    • 應該也沒人用吧,你不刪最少使用 Key,去隨機刪
  • volatile-lru(有過期時間的最近最少使用)
    • 當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,移除最近最少使用的 Key。
    • 這種情況一般是把 Redis 既當快取,又做持久化儲存的時候才用。不推薦
  • volatile-random(有過期時間的隨機淘汰)
    • 當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,隨機移除某個 Key。
    • 依然不推薦
  • volatile-ttl(有過期時間的淘汰更早過期的)
    • 當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,有更早過期時間的 Key 優先移除。如果沒有對應的鍵,則回退到noeviction策略
    • 不推薦

六種記憶體淘汰策略使用場景

  • allkeys-lru :如果我們的應用對快取的訪問符合冪律分佈,也就是存在相對熱點資料,或者我們不太清楚我們應用的快取訪問分佈狀況,我們可以選擇 allkeys-lru策略

  • allkeys-random :如果我們的應用對於快取key的訪問概率相等,則可以使用這個策略。

  • volatile-ttl:這種策略使得我們可以向Redis提示哪些key更適合被eviction

  • volatile-lru策略和volatile-random策略適合我們將一個Redis例項既應用於快取和又應用於持久化儲存的時候,然而我們也可以通過使用兩個Redis例項來達到相同的效果,值得一提的是將key設定過期時間實際上會消耗更多的記憶體,因此我們建議使用allkeys-lru策略從而更有效率的使用記憶體

    注意:頻繁執行回收記憶體成本很高,主要包括查詢可回收鍵和刪除鍵的開銷,如果當前redis有從節點,回收記憶體操作對應的刪除命令會同步到從節點,導致寫放大的問題(主從架構當中)

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章