技術分享 | Redis 持久化之 RDB 與 AOF

愛可生雲資料庫 發表於 2023-01-23
Redis

作者:賁紹華

愛可生研發中心工程師,負責專案的需求與維護工作。其他身份:柯基鏟屎官。

本文來源:原創投稿

*愛可生開源社群出品,原創內容未經授權不得隨意使用,轉載請聯絡小編並註明來源。


一、RDB(Redis Database)簡介

RDB持久化方式能夠在指定的時間間隔內(N秒內有M次改動時),對例項的資料進行快照儲存,也就是全備的意思。

二、RDB - 特性

2.1 優點

  • 單一檔案,方便傳輸,適合災備;
  • 恢復大資料集時效率會比AOF快一些;
  • 備份時會由fork出的子程式操作,父程式不需要其他IO操作,效能相對AOF來說佔優。

2.2 缺點

  • 在間隔其間發生意外當機,會造成資料大量丟失;
  • 資料量非常大時fork子程式非常耗時,可能會影響業務正常響應。

三、RDB - 策略

RDB的備份觸發方式有兩種型別,五種觸發條件,分別為:

3.1 自動觸發

  • 根據conf內配置的save規則進行儲存;
  • 執行FLUSHALL(刪除所有資料庫裡面的所有資料)命令會觸發;
  • 主動退出Redis會觸發。

3.2 手動觸發

  • SAVE「同步執行」(儲存資料至磁碟);
  • BGSAVE「非同步執行」(儲存資料至磁碟)。

3.3 操作流程

1.fork一個子程式,建立子程式時並不會發生資料複製,提高了複製速度降低了所需空間大小(核心級的系統呼叫:fork());

2.子程式獲得所有資料指向地址的指標;

3.此時如有資料繼續增加則觸發寫時複製,父程式指向新值地址,子程式依舊指向原值地址(COW(copy-on-write 寫時複製));

4.將指標指向的值寫入備份;

5.備份完成。

四、RDB - 配置

| 配置項 | 說明 |
| --- | --- |
| save | N秒內有M次改動時儲存(觸發的是BGSAVE非同步執行) |
| stop-writes-on-bgsave-error | 快照出錯時是否禁止寫入操作 |
| rdbcompression | 是否壓縮RDB檔案 |
| rdbchecksum | 是否開啟RC64校驗 |
| dbfilenameRDB | 檔案儲存名稱 |
| dirRDB | 檔案儲存目錄 |

五、RDB - 其他

5.1 時點性

當Redis在指定時間點觸發全備時如果此後資料庫依然有修改,則值還是會保留在未修改前的時間點,這樣保證了不會發生時點混亂。

5.2 閾值建議

建議Redis使用記憶體控制在10-15G以內,過大的話會影響RDB落盤的速度。

5.3 RDB檔案損壞該怎麼辦

在Redis的安裝目錄內,提供了redis-check-rdb工具用於對損壞的備份檔案進行修復。

六、AOF(Append Only File)簡介

AOF持久化方式即增備,記錄每次對伺服器寫的操作,當伺服器重啟的時候會重新執行這些命令來恢復原始的資料。

AOF命令以redis協議追加儲存每次寫的操作到檔案末尾。Redis還能對AOF檔案進行重寫壓縮,使得AOF檔案的體積不至於過大。

6.1 AOF檔案協議

下面列舉一段AOF檔案內容進行說明:

# 假設此時客戶端執行了語句SET KEY VALUE,則AOF內容如下
*3
$3
SET
$3
KEY
$5
VALUE

上述內容中,看似比較雜亂,但理解一下其實很簡單

*表示跳過$行時,往下一次讀幾行

$表示下一行有多少個字元

七、AOF - 特性

7.1 優點

  • 異常當機損失較小,能夠做到資料不丟失或最多丟失1秒

7.2 缺點

  • 對比RDB在恢復資料的效率上表現不高
  • AOF檔案會比RDB檔案更大
  • 根據所使用的 fsync 策略不同,AOF 的速度可能會慢於 RDB

八、AOF - 策略

AOF同樣分為兩種觸發方式,根據配置項appendfsync(AOF持久化策略)的不同對應的執行時機也不同:

8.1 自動觸發

  • no(從不 fsync,buffer寫滿了就落盤,速度快)
  • everysec「預設」(每一秒儲存一次)
  • always(每次都fsync,速度慢,可靠性高)

8.2 手動觸發

BGREWRITEAOF「非同步執行」(重寫AOF檔案)

九、AOF - 配置

| 配置項 | 說明 |
| --- | --- |
| appendonly | 是否開啟AOF |
| AOFappendfilename | AOF檔名 |
| appendfsync | AOF持久化策略 |
| no-appendfsync-on-rewrite | 在寫入時是否對新記錄暫緩追加 |
| auto-aof-rewrite-percentage | AOF檔案增長比例 |
| auto-aof-rewrite-min-size | 檔案重寫檔案大小 |
| aof-load-truncated | 是否末尾異常的AOF檔案 |
| aof-use-rdb-preamble | 是否使用RDB-AOF混合持久化模式(4.0版本之後)
在開啟了這個功能之後,AOF重寫產生的檔案將同時包含RDB格式的內容和AOF格式的內容,其中RDB格式的內容用於記錄已有的資料,而AOF格式的記憶體則用於記錄最近發生了變化的資料,這樣Redis就可以同時兼有RDB持久化和AOF持久化的優點(既能夠快速地生成重寫檔案,也能夠在出現問題時,快速地載入資料)發生重寫之後才能變成混合體 |

十、AOF - 其他

10.1 AOF重寫的版本差異性

  • 4.0之前:刪除可以相互抵消的命令,合併重複命令
  • 4.0之後:先將記憶體資料都資料成RDB,後續操作依舊記錄成AOF

10.2 AOF檔案損壞了該怎麼辦

由於是增備,在資料持續寫入時遇到意外當機時很容易造成AOF檔案的損壞,此時重啟Redis例項會無法載入該檔案。

解決的方式如下:

1.定時備份AOF檔案

2.在Redis的安裝目錄中,提供了redis-check-aof工具用於修復異常的AOF檔案,可以在修復完成後diff -u來對比一下修復前後檔案的差異性