Redis篇:持久化、淘汰策略,快取失效策略

潛行前行發表於2021-12-18

關注公眾號,一起交流,微信搜一搜: 潛行前行

redis 持久化

redis 的資料是儲存再系統記憶體裡面的。持久化就是把記憶體的資料轉移到磁碟中,redis 的持久化策略有兩種:RDB、AOF

RDB

  • RDB 是以快照的形式把記憶體裡的資料生成一個 RDB 格式備份檔案,定時儲存。儲存的是資料的壓縮過資料結構
  • 有兩個命令 SAVE、BGSAVE 可以生成 RDB 檔案,SAVE 會阻塞主服務程式,直到 RDB 檔案建立完畢。BGSAVE 則是派生一個子程式去執行 RDB 的生成
  • RDB 會在 redis 啟動時被載入,沒有特殊載入命令

RDB 的原理總結

  • 當 redis 需要做持久化時,redis 會 fork一個子程式,子程式將資料寫到磁碟上一個臨時 RDB 檔案中。當子程式完成寫臨時檔案後,將原來的 RDB 檔案替換掉,這樣的好處是可以copy-on-write

RDB 優缺點

  • 適合冷備份。對於災難恢復而言,RDB 是非常不錯的選擇。RDB 是經過壓縮的資料,體積小
  • 恢復更快。相比於 AOF 機制,RDB 的恢復速度更更快,更適合恢復資料,特別是在資料集非常大的情況
  • 系統一旦在定時持久化之前出現當機現象,此前沒有來得及寫入磁碟的資料都將丟失。所以,RDB 實際場景下,需要和 AOF 一起使用
  • 由於 RDB 是通過 fork 子程式來協助完成資料持久化工作的,因此,如果當資料集較大時,可能會導致整個伺服器卡頓

AOF

  • AOF 的實現可以分為三個步驟:命令追加(append)、檔案寫入、檔案同步(sync)
    • redis 執行一個寫命令時,會以協議格式將命令追加到 aof_buf 的緩衝區末尾
    • 在 redis 的事件迴圈執行週期,處理檔案事件時,則會考慮是否將 aof_buf 緩衝區的資料寫入到 AOF 檔案。這其中有三種策略:1-always aof_buf 資料全部同步到 AOF 檔案、2-everysec 每秒同步一次、3-no 不同步
    • 預設是 everysec 策略
  • 如果 AOF 日誌過大,redis 會啟用 rewrite 機制。在 rewrite log 時,會對其中的指令進行壓縮,建立出一份需要恢復資料的最小日誌出來。可使用 BGREWRITEAOF 命令 fork 子程式單獨處理,不會影響 redis 主程式
  • AOF 的同步頻率比 RDB 的同步頻率高,如果同時開啟 AOF 和 RDB,redis 優先選擇 AOF 同步檔案

AOF 優缺點

  • AOF 實時同步比 RDB 快 。該機制對日誌檔案的寫入操作採用的是 append 模式,因此在寫入過程中即使出現當機現象,也不會破壞日誌檔案中已經存在的內容
  • 如果本次操作只是寫入了一半資料就出現了系統崩潰問題也不用擔心,在 redis 下一次啟動之前,可以通過 redis-check-aof 工具來解決資料一致性的問題
  • 對於相同數量的資料集而言,AOF 檔案通常要大於 RDB 檔案。RDB 在恢復大資料集時的速度比 AOF 的恢復速度要快

redis 記憶體淘汰策略

  • no-eviction
    • redis 不再繼續提供寫請求 (DEL 請求可以,讀請求也可以)。這可以保證不會丟失資料,但是會讓線上的業務不能持續進行,這是預設的淘汰策略
  • volatile-lru
    • 嘗試淘汰設定了過期時間的 key,最近最少使用的 key 優先被淘汰。沒有設定過期時間的 key 不會被淘汰,這樣可以保證需要持久化的資料不會突然丟失(使用最多)
  • volatile-ttl
    • 跟上面一樣,只是優先淘汰剩餘過期時間 ttl 的最小的 key,ttl 越小越先被淘汰
  • volatile-lfu
    • 從所有配置了過期時間的 key 中淘汰使用頻率最少的鍵
  • volatile-random
    • 從設定了過期時間的 key 中淘汰資料
  • allkeys-lru
    • 區別於 volatile-lru,這個策略要淘汰的 key 物件是全體的 key 集合,而不只是過期的 key 集合
  • allkeys-random
    • 從所有鍵中隨機淘汰 key
  • allkeys-lfu
    • 從所有鍵中淘汰使用頻率最少的鍵

redis 過期鍵刪除策略

  • 定時刪除
    • 在設定鍵的過期時間的同時,建立一個定時器,讓定時器在講的過期時間來臨時,執行對鍵的刪除操作
    • 定時刪除會佔用CPU時間,響應伺服器的響應時間和吞吐量
  • 惰性刪除
    • 任由鍵過期先不刪除,但是每次從鍵空間中獲取鍵時都檢查取得的鍵是否過期,如果過期則刪除鍵
    • 惰性刪除浪費太多記憶體,有記憶體洩漏的危險
  • 定期刪除
    • 每隔一段時間,程式就對資料庫進行一次檢查,刪除裡面的過期鍵。至於刪除多少過期鍵,則根據多少個過期鍵和演算法決定
    • 定期刪除是前兩種策略的整合和折中。因為是批量操作,並限定了執行時長和頻率,可以有效減少刪除操作對CPU的響應,也避免了記憶體長久不刪除的導致的浪費

redis 的過期鍵刪除策略

  • redis 實際使用了惰性刪除和定期刪除兩種策略,合理地在CPU時間和避免浪費空間之中保持平衡
  • 惰性刪除的 set 等命令執行
    image.png
  • 惰性刪除的 get 等命令執行
    image.png

歡迎指正文中錯誤

參考文章

相關文章