Redis 實戰 —— 06. 持久化選項

持久化選項簡介 P61

Redis 提供了兩種不同的持久化方法來將數據存儲到硬碟裡面。

  • RDB(redis database):可以將某一時刻的所有數據都寫入硬碟裡面。(保存的是數據本身)
  • AOF(append only file):會在執行命令時,將被執行的寫命令複製到硬碟裡面。(保存的是數據的變更記錄)

兩種持久化方法既可以同時使用,又可以單獨使用,在某些情況下甚至可以兩種方法都不使用,具體選擇哪種持久化方法需要根據數據以及應用來決定。

快照持久化 P62

配置選項
# 持久化觸發條件:seconds 秒內至少有 changes 個鍵被更改
# save <seconds> <changes> 
# 
# 默認配置以下三個觸發持久化的條件
# 【注】注釋掉所有 save 的配置,就不會開啟快照持久化
#
# 900 秒(15 分鐘)內至少有 1 個鍵被更改
# 300 秒(5 分鐘)內至少有 10 個鍵被更改
# 60 秒(1 分鐘)內至少有 10000 個鍵被更改
save 900 1
save 300 10
save 60 10000

# 如果快照持久化開啟
# yes:後台持久化操作失敗時,Redis 就會停止接受更新操作(默認 yes)
# no :後台持久化操作失敗時,Redis 仍然可以繼續正常工作
stop-writes-on-bgsave-error yes

# 在進行鏡像備份時,是否進行壓縮
# yes:壓縮,會有更多 cpu 消耗,時間會更長(默認 yes)
# no :不壓縮,需要更多磁碟空間
rdbcompression yes

# 資料庫文件的文件名
dbfilename dump.rdb

# 工作目錄,資料庫文件的位置
# AOF(append only file)也會在此目錄創建 
dir ./

如果新的快照文件創建完成之前,Redis 、 系統或者硬體這三者之中的任意一個崩潰了,那麼 Redis 將丟失最近一次成功創建快照之後寫入的所有數據。快照持久化只適用於那些即使丟失一部分數據也不會造成問題的程式,而不接受數據損失的程式可以考慮使用 AOF 持久化。 P63

創建快照的方法 P63
  • 客戶端可以通過向 Redis 發送 BGSAVE 命令來主動創建快照。對於支援 BGSAVE 命令的平台(除了 Windows 平台)來說,由 fork 創建出的子進程負責將快照寫入硬碟,父進程繼續處理命令請求。

  • 客戶端可以通過向 Redis 發送 SAVE 命令來主動創建快照,接到 SAVE 命令的 Redis 伺服器在快照創建完畢之前不會響應任何命令。

  • 設置了 save 配置選項,那麼當任意一個條件滿足時, Redis 就會自動觸發一次 BGSAVE 命令。

  • 當 Redis 通過 SHUTDOWN 命令接收到關閉伺服器的請求時,或者接收到標準 TERM 訊號時,會執行一個 SAVE 命令,阻塞所有客戶端,不再執行客戶端發送的任何命令,並在 SAVE 命令執行完畢之後關閉伺服器。

  • 當一個 Redis 伺服器連接另一個 Redis 伺服器,並向對方發送 SYNC 命令來開始一次複製操作的時候,如果主伺服器目前沒有在執行 BGSAVE 操作,或者並非剛剛執行完 BGSAVE 操作,那麼主伺服器就會執行 BGSAVE 命令。

    the master Redis server will start a BGSAVE operation if one isn』t already executing or recently completed.

    斜體加粗的部分感覺有點難理解,第二個就已經包含在第一個條件里了,然後找到英文原文還有點懵。

不同場景下的使用 P64
  • 個人開發:主要考慮儘可能地降低快照持久化帶來的資源消耗,只設置 save 900 1 這一條規則。 P64
  • 對日誌進行聚合計算:主要考慮 Redis 因為崩潰而未能成功創建新的快照,那麼我們能承受丟失多長時間以內產生的新數據。還需要設計如何恢復被中斷的聚合計算,可以記錄每次處理的日誌文件名及偏移量,恢復時按升序從記錄處開始處理。 P64
  • 大數據:當 Redis 存儲的出具了達到即使 GB 時,執行 BGSAVE 可能會導致系統長時間地停頓,也可能引發系統大量地使用虛擬記憶體,從而導致 Redis 的性能降低至無法使用的程度。 可以考慮手動發送 BGSAVE 或者 SAVE 來進行持久化,避免自動執行而造成停頓。P65
RDB 的優點
  • 非常緊湊
  • 適合用於災難恢復
  • 可以最大化 Redis 的性能
  • 恢復大數據集時的速度比 AOF 的恢復速度要快
RDB 的缺點
  • 宕機時丟失數據可能較多
  • 每次持久化時都要 fork() 一個子進程,當數據集比較龐大時可能非常耗時

AOF 持久化 P66

配置選項
# AOF 持久化是否開啟
# yes:開啟 AOF 持久化,Redis 在啟動時會載入 AOF,而忽略快照持久化文件
# no :不開啟 AOF 持久化(默認不開啟)
appendonly no

# AOF 文件名(默認為 appendonly.aof)
appendfilename "appendonly.aof"

# Redis 支援三種不同的回寫模式
# always  :每次寫操作都調用 fsync(),立刻寫入 AOF 文件。非常慢但是很安全。
# everysec:每秒調用一次 fsync()。折衷方案。(默認為 everysec)
# no	  :不調用 fsync(),等待作業系統刷數據。很快。
# appendfsync always
appendfsync everysec
# appendfsync no

# 如果有延遲問題就將該選項設置為 yes
# 否則就保持 no,這是最安全的方式
no-appendfsync-on-rewrite no

# 自動重寫 AOF 文件,若百分比設置為 0,則表示禁用自動重寫 AOF 文件
# 如果當前 AOF 文件大小以及比上次 AOF 文件大小大了 指定的百分比,則會重寫 AOF 文件
# 同時需要指定 AOF 文件重寫的最小大小,以避免百分比過小而頻繁重寫 AOF 文件
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
重寫 AOF 文件 P67

Redis 會不斷地將被執行的寫命令記錄到 AOF 文件裡面,AOF 文件會不斷增大,可能會用完硬碟的所有可用空間,重啟之後還原操作也可能執行很長時間。 P68

為了解決 AOF 文件不斷增大的問題,用戶可以向 Redis 發送 BGREWRITEAOF 命令,這個命令會通過移除 AOF 文件中冗餘命令來重寫 AOF 文件,使 AOF 文件變得儘可能地小。BGREWRITEAOF 的工作原理和 BGSAVE 創建快照的工作原理非常相似: Redis 會創建一個子進程, 然後由子進程負責對 AOF 文件進行重寫。P68

重寫 AOF 文件是從數據集中讀取鍵當前的值,然後用一條命令取記錄鍵值對,代替之前記錄該鍵值對的多個命令,最終生產一個新的 AOF 文件,這個文件包含重建當前數據集所需的最少命令。

AOF 的優點
  • AOF 文件只追加,所以寫入時不需要進行 seek
  • AOF 文件過大時,後台會自動對 AOF 文件進行重寫
  • 有序地保存了資料庫執行的所有寫入操作,易讀懂,也能輕鬆分析文件
AOF 缺點
  • 相同數據集時,AOF 文件的體積通常大於 RDB 文件的體積
  • 根據所使用的 fsync 策略,AOF 的速度可能會慢於 RDB
  • 個別命令(例如:BRPOPLPUSH source destination timeout)會導致 AOF 文件在重新載入時,無法將數據集恢復成保存時的原樣

本文首發於公眾號:滿賦諸機(點擊查看原文) 開源在 GitHub :reading-notes/redis-in-action