Redis - 緩存持久化原理以及數據過期策略

Redis - 緩存持久化原理以及數據過期策略

1.RDB持久化原理

1.1 RDB是什麼?

RDB(Redis DataBase)是將Redis指定的時間間隔內將內存中的數據集快照寫入磁盤,也是默認的持久化方式,這種方式是就是將內存中數據以快照的方式寫入到二進制文件中,默認的文件名爲dump.rdbRedis在進行數據持久化的過程中,會先將數據寫入到一個臨時RDB文件中,持久化過程結束後會將這個臨時文件替換上次持久化好的文件。通過這種特性我們可以隨時來進行備份,因爲快照文件總是完整可用的。

1.2 RDB持久化配置

 我們找到redis.conf文件,修改以下配置:

# 時間策略
save 900 1     # 表示900s內有1條寫入命令,就觸發產生一次快照,可以理解爲就進行一次備份
save 300 10    # 表示300s內有10條寫入命令,就產生快照
save 60 10000  # 表示60s內有10000條寫入命令,就產生快照
# save "" 禁用RDB
# redis servercron 類似於linux的crontab,默認每隔100毫秒執行一次,用於檢測上述配置規則是否觸發快照備份

# 文件名稱
dbfilename dump.rdb

# 如果持久化出錯,主進程是否停止寫入
stop-writes-on-bgsave-error yes

# 是否壓縮
rdbcompression yes

# 導入時是否檢查
rdbchecksum yes

# 文件保存路徑
dir /usr/local/redis/redis-4.0.6

 修改配置後啓動Redis服務,可以看到這裏就是加載RDB文件的過程,並且在當前目錄下我們可以看到用於持久化的RDB文件。並且在關閉時也會進行RDB持久化操作。
在這裏插入圖片描述
在這裏插入圖片描述
 實際生產環境中每個時段的讀寫請求肯定不是均衡的,爲此Redis提供一種根據規定時間內操作次數來觸發一次備份到磁盤的操作,這就是上面配置文件中save配置的含義。

1.3 RDB持久化觸發方式

 RDB持久化觸發方式主要分爲兩種:

  1. 手動觸發:手動觸發主要涉及兩個命令
     a) save:阻塞當前Redis服務器,直到持久化完成,線上應該禁止使用。
     b) bgsave:該觸發方式會fork一個子進程,由子進程負責持久化過程,所以阻塞只會發生在fork子進程而不是阻塞Redis服務。
  2. 自動觸發:
     a) 根據save m n配置規則自動觸發。
     b) 節點全量複製時,主節點發送rdb文件給從節點完成複製操作,主節點會觸發bgsave。
     c) 執行debug reload時。
     d) 執行shutdown時,若未開啓AOF持久化方式也會自動觸發。

2.AOF持久化原理

2.1 AOF是什麼?

AOF(Append Only File)是將執行過的寫指令記錄下來,在數據恢復時按照從前到後的順序再將指令都執行一遍。

2.2 AOF持久化配置

 同樣修改的是redis.conf文件:

# 是否開啓aof
appendonly yes

# 文件名稱
appendfilename "appendonly.aof"

# 同步方式
appendfsync everysec

# aof重寫期間是否同步
no-appendfsync-on-rewrite no

# 重寫觸發配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 文件重寫策略
aof-rewrite-incremental-fsync yes

# 加載aof時如果有錯如何處理
aof-load-truncated yes # yes表示如果aof尾部文件出問題,寫log記錄並繼續執行。no表示提示寫入等待修復後寫入

2.3 AOF同步模式

AOF主要是通過appendfsync配置同步模式,主要有三種:

  1. always:每個時間事件循環都將AOF_BUF緩衝區的所有內容寫入到AOF文件,並且同步AOF文件,這是最安全的方式,但磁盤操作和阻塞延遲,是IO開支較大。
  2. everysec:每秒同步一次,性能和安全都比較折中的方式,也是Redis推薦的方式。如果遇到物理服務器故障,有可能導致最近一秒內aof記錄丟失(可能爲部分丟失)。
  3. no:Redis不直接調用文件同步,而是交給操作系統來處理。操作系統根據buffer填充情況/通道空閒時間等擇機觸發同步。這是一種普通的文件操作方式,性能較好。在物理服務器故障時,數據丟失量會因OS配置有關。處於no模式下的flushAppendOnlyFile調用無須執行同步操作

2.4 AOF重寫

 我們可以發現之前的配置文件中有一個機制相關的配置rewrite,這裏關於AOF重寫的運行原理我們可以做一個大概的瞭解。
 在重寫即將開始時,Redis會創建(fork)一個重寫子進程。這個子進程會讀取現有的AOF文件,並將其包含的指令進行分析壓縮寫入到一個臨時文件中。與此同時,主進程會將新接收到的寫指令一邊添加進內存緩衝區中,一邊寫入到原有的AOF文件中,這樣做可以保證原有的AOF文件的可用性。當重寫子進程完成重寫工作後,會通過給主進程發送信號讓主進程將內存中緩存中寫指令追加到新AOF文件中。追加結束後,Redis就會將新AOF文件代替舊AOF文件,之後再有新的寫指令重複整個流程。

3.RDB與AOF持久化方案比較以及選擇

3.1 RDB與AOF持久化方案比較

 上面我們瞭解了Redis提供的兩種持久化方案:

  1. RDB持久性以指定的時間間隔執行數據集的時間點快照。
  2. AOF持久性記錄服務器接收的每個寫操作,在服務器啓動時再次執行,重建原始數據集。使用與Redis協議本身相同的格式以僅追加方式記錄命令。


 既然有兩種持久化方案,那我們就來比較一下兩種方案的優缺點。
RDB

  1. 優點:
     a) RDB最大限度地提高了Redis的性能,生成RDB文件時父進程只需fork子線程去處理保存工作,父進程不需要參與磁盤I/O。
     b) 恢復大數據集時速度比AOF更快。
     c) RDB是快照文件,數據緊湊體積小。
  2. 缺點:
     a) 由於備份頻率低,則服務出現故障時數據丟失的概率更大。
     b) RDB經常需要fork才能使用子進程持久存儲在磁盤上。數據集很大時fork可能會非常耗時。

AOF

  1. 優點:
     a) 可自定義配置同步模式,備份頻率更高,數據更加安全。默認採用everysec策略,在保持良好性能的同時即使服務故障也只會丟失一秒鐘的數據。
     b) AOF文件有序地保存了對數據庫執行的所有寫入操作,這些寫入操作以Redis協議的格式保存,可讀性更高。
     c) 當AOF文件太大時,Redis能夠在後臺自動重寫。 重寫後的新AOF文件包含了恢復當前數據集所需的最小命令集合。(例如:INCR 1 執行1萬次 => INCRBY 10000 執行一次)
  2. 缺點:
     a) 相同數據集的情況下,AOF文件通常比RDB文件大(RDB備份數據,AOF備份寫命令)
     b) 根據不同的fsync策略,AOF可能比RDB慢。默認情況下,每秒fsync性能很高。但是在大量寫命令載入時,RDB效率可能更高。

3.2 RDB與AOF持久化方案選擇

 我們先看一下Redis故障數據恢復的一個流程。
在這裏插入圖片描述
 對於RDBAOF如何選擇這個問題,其實一般來說若我們需要達到更高的數據安全性,可同時啓用兩種持久化方式。如果可以能夠接收分鐘單位級別的數據丟失,則只需啓用RDB。另外RDB生成的快照文件也更利於數據備份,恢復效率也更高。
 在真正使用時我們可以採用RDB和AOF持久化同時啓用,當然如果我們擁有補回丟失數據的途徑可以關閉持久化通過其他方式去重寫數據。

4.數據過期清除策略

4.1 Redis提供的三種過期策略

 在我們使用Redis時,很多時候都會給緩存Key設置上Expire過期時間,那麼當緩存過期後Redis是否會清理當前Key所佔有的內存空間?若不會,那麼數據量一直增加之後空間佔用過大或者慢了的問題如何解決?若會,那是如何去清理這些過期數據的呢?其實Redis對於過期數據是會進行清除的,它提供了三種過期策略,這裏我們詳細瞭解下。

  1. 惰性刪除 :Key過期時不進行刪除操作,每次獲取Key時會先檢查是否過期,若已經過期則刪除。
     優點:這種方式本質就是不會主動去管理過期Key,當Key過期後下次還有操作對當前Key進行操作再去檢查是否過期之後刪除。這種方式對CPU十分友好,不會浪費過多的CPU資源去主動處理這些過期數據資源。
     缺點:若一個Key不再使用,這種Key數量變多後則會造成大量的內存浪費甚至內存泄漏。
  2. 定時刪除:設置Key過期時間的同時,創建一個定時器(Timer)。定時器會在鍵過期時間到達時立即對鍵進行刪除。
     優點:內存會及時得到釋放。
     缺點:爲每一個Key都創建定時器,量多之後嚴重影響性能。
  3. 定期刪除:每隔一段時間對數據庫進行一次檢查,刪除裏面的過期Key。至於刪除多少過期鍵以及要檢查多少個數據庫,則由算法決定。 即設置一個定時任務,比如10分鐘刪除一次過期的key。間隔小則佔用CPU,間隔大則浪費內存。定期刪除可通過redis.conf配置文件修改執行週期以及觸發界值(hz:默認10,即10次/s ,100ms一次。值越大頻率越快消耗性能越大;maxmemory:當內存佔用超過該值設定,主動觸發清除策略)。
     優點:通過限制刪除操作的週期頻率,來減少刪除操作對CPU的佔用。
     缺點:比較折中的方案,內存友好方面不如定時刪除,CPU消耗方面不如惰性刪除。需合理設置操作週期。
    定期刪除處理流程大致如下:
      a) 每秒對隨機的20個Key進行過期檢測。
      b) 刪除所有已經過期的Key。
      c) 若多於25%的Key過期,則重複步奏a。.

4.2 Redis採用的過期策略

Redis服務實際是採用惰性刪除定期刪除兩種策略:通過這兩種刪除策略配合使用,服務器可以更好地在合理使用CPU和避免內存浪費之間維持平衡。這裏大致瞭解一下這兩種過期策略的流程。

  1. 惰性刪除流程:在進行getsetnx等操作時,會先檢查Key是否過期。若過期則刪除Key,然後執行相應操作;若未過期則直接執行相應操作。(實現:通過expireIfNeeded函數,當我們操作key的時候進行判斷key是否過期)

  2. 定期刪除流程:首先遍歷每個Redis數據庫(redis.conf中配置的"database"數量,默認爲16),然後檢查當前庫中指定個數Key(默認是每個庫檢查20個Key)。若當前庫中沒有任何Key設置過期時間,直接執行下一個庫的遍歷,若有則隨機獲取一個設置了過期時間的Key並檢查該Key是否過期,如果過期刪除當前Key。同時會判斷定期刪除操作是否已經達到指定時長,若已經達到則直接退出定期刪除任務。(實現:通過activeExpireCycle函數,serverCron函數執行時,activeExpireCycle函數就會被調用,規定的時間裏面分多次遍歷服務器的expires字典隨機檢查一部分Key的過期時間,並刪除其中的過期Key)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章