1. 程式人生 > >Redis數據過期和淘汰策略詳解(轉)

Redis數據過期和淘汰策略詳解(轉)

group all res val for 手動 鍵值對 and 所有

原文地址:https://yq.aliyun.com/articles/257459#

背景

Redis作為一個高性能的內存NoSQL數據庫,其容量受到最大內存限制的限制。

用戶在使用Redis時,除了對性能,穩定性有很高的要求外,對內存占用也比較敏感。在使用過程中,有些用戶會覺得自己的線上實例內存占用比自己預想的要大。

事實上,實例中的內存除了保存原始的鍵值對所需的開銷外,還有一些運行時產生的額外內存,包括:

  1. 垃圾數據和過期Key所占空間
  2. 字典漸進式Rehash導致未及時刪除的空間
  3. Redis管理數據,包括底層數據結構開銷,客戶端信息,讀寫緩沖區等
  4. 主從復制,bgsave時的額外開銷
  5. 其它

本文主要分析第一項Redis過期策略對內存的影響

Redis過期數據清理策略

過期數據清理時機

為了防止一次性清理大量過期Key導致Redis服務受影響,Redis只在空閑時清理過期Key

具體Redis逐出過期Key的時機為:

  1. 訪問Key時,會判斷Key是否過期,逐出過期Key;
  2. CPU空閑時在定期serverCron任務中,逐出部分過期Key;
  3. 每次事件循環執行的時候,逐出部分過期Key;

過期數據清理算法

Redis過期Key清理的機制對清理的頻率和最大時間都有限制,在盡量不影響正常服務的情況下,進行過期Key的清理,以達到長時間服務的性能最優.

Redis會周期性的隨機測試一批設置了過期時間的key並進行處理。測試到的已過期的key將被刪除。具體的算法如下:

  1. Redis配置項hz定義了serverCron任務的執行周期,默認為10,即CPU空閑時每秒執行10次;
  2. 每次過期key清理的時間不超過CPU時間的25%,即若hz=1,則一次清理時間最大為250ms,若hz=10,則一次清理時間最大為25ms;
  3. 清理時依次遍歷所有的db;
  4. 從db中隨機取20個key,判斷是否過期,若過期,則逐出;
  5. 若有5個以上key過期,則重復步驟4,否則遍歷下一個db;
  6. 在清理過程中,若達到了25%CPU時間,退出清理過程;

這是一個基於概率的簡單算法,基本的假設是抽出的樣本能夠代表整個key空間,redis持續清理過期的數據直至將要過期的key的百分比降到了25%以下。這也意味著在長期來看任何給定的時刻已經過期但仍占據著內存空間的key的量最多為每秒的寫操作量除以4.

  • 由於算法采用的隨機取key判斷是否過期的方式,故幾乎不可能清理完所有的過期Key;
  • 調高hz參數可以提升清理的頻率,過期key可以更及時的被刪除,但hz太高會增加CPU時間的消耗;Redis作者關於hz參數的一些討論

Redis數據逐出策略

數據逐出時機

數據逐出算法

在逐出算法中,根據用戶設置的逐出策略,選出待逐出的key,直到當前內存小於最大內存值為主.

可選逐出策略如下:

  • volatile-lru:從已設置過期時間的數據集(server.db[i].expires)中挑選最近最少使用 的數據淘汰
  • volatile-ttl:從已設置過期時間的數據集(server.db[i].expires)中挑選將要過期的數 據淘汰
  • volatile-random:從已設置過期時間的數據集(server.db[i].expires)中任意選擇數據 淘汰
  • allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰
  • allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰
  • no-enviction(驅逐):禁止驅逐數據(默認

相關最佳實踐優化配置

    • 不要放垃圾數據,及時清理無用數據
      實驗性的數據和下線的業務數據及時刪除;
    • key盡量都設置過期時間
      對具有時效性的key設置過期時間,通過redis自身的過期key清理策略來降低過期key對於內存的占用,同時也能夠減少業務的麻煩,不需要定期手動清理了.
    • 單Key不要過大
      給用戶排查問題時遇到過單個string的value有43M的,也有一個list 100多萬個大成員占了1G多內存的。這種key在get的時候網絡傳輸延遲會比較大,需要分配的輸出緩沖區也比較大,在定期清理的時候也容易造成比較高的延遲. 最好能通過業務拆分,數據壓縮等方式避免這種過大的key的產生。
    • 不同業務如果公用一個業務的話,最好使用不同的邏輯db分開
      從上面的分析可以看出,Redis的過期Key清理策略和強制淘汰策略都會遍歷各個db。將key分布在不同的db有助於過期Key的及時清理。另外不同業務使用不同db也有助於問題排查和無用數據的及時下線.

Redis數據過期和淘汰策略詳解(轉)