【Redis 系列】redis 學習八,redis 持久化 RDB 和 AOF

小魔童哪吒發表於2022-03-31

Redis 持久化

redis 是記憶體資料庫,如果不將記憶體中資料庫儲存到磁碟上,那麼伺服器一旦當機,或者 redis 程式退出,不僅資料會被丟失,伺服器中的資料庫狀態也會被丟失

因此 redis 提供了持久化的功能

redis 的持久化分為 RDB 和 AOF

RDB (Redis DatabBase)

在主從複製中,rdb檔案都作為備用的,放在從機上面

在指定時間間隔內將記憶體中的資料集快照寫入到磁碟中,這就是快照 snapshot ,恢復快照的時候,是把快照檔案讀入到記憶體中。

redis 通過 fork 的方式建立一個子程式來專門做持久化的動作,

  • 先將資料寫入到一個臨時檔案中,待持久化過程結束,再用這個臨時檔案替換上一次的持久化好的檔案

整個過程中,主程式是不進行任務 IO 操作的,這就保障了極高的效能

如果需要進行大規模的資料恢復,且對於資料的完整性要求不那麼敏感和嚴格,選擇 RDB 的持久化方式比 AOF 的持久化方式更優,更加高效。

RDB 雖然效能高,但是在 最後一次持久化後的資料可能會被丟失,redis 預設就是使用的 RDB 持久化方式,一般情況下也不需要修改

save 60 3

# The filename where to dump the DB
dbfilename dump.rdb

dir ./

我們設定 60s 內若 有操作 redis 3 次,那就做一次持久化

127.0.0.1:6379> ping
PONG
127.0.0.1:6379> config get dir
1) "dir"
2) "/root"
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK

dump.db 檔案是生成在 dir 目錄下的,我們這裡的 dir 目錄是 /root

進行上述操作之後,我們發現 /root 生成了 dump.rdb 檔案 ,我們們將該檔案刪除掉,再嘗試一次

root@iZuf66y3tuzn4wp3h02t7pZ:~# rm dump.rdb -rf
root@iZuf66y3tuzn4wp3h02t7pZ:~# redis-cli
127.0.0.1:6379> set p1 1
OK
127.0.0.1:6379> set p2 1
OK
127.0.0.1:6379> set p3 3
OK
root@iZuf66y3tuzn4wp3h02t7pZ:~# ls
dump.rdb

果然也是正常生成的

持久化的觸發機制

  • 按照 save 的規則滿足的情況下,就會觸發持久化,例如上述的 60s 操作 redis 3 次就會觸發 1 次持久化
  • 執行 flushall 命令的時候,也會觸發持久化,生成 dump.db 檔案
  • 退出 redis 的時候, 也會觸發持久化,生成 dump.db 檔案

備份就會自動生成一個 dump.db 檔案

如何恢復持久化檔案

1、只需要將 dump.db 檔案放到 redis 的啟動目錄即可,redis 啟動的時候會將該檔案讀入到記憶體中,進行資料恢復

2、檢視 redis 的啟動目錄可以這樣做

127.0.0.1:6379> config get dir
1) "dir"
2) "/root"

這一塊的配置,我們基本上不需要修改太多,預設的配置基本就夠用了

RDB 的優勢

  • 適合大規模的資料恢復
  • 對資料的完整性要求不高

RDB 的劣勢

  • 需要在一定的時間間隔進行操作,如果 redis 意外當機,最後一次寫入的資料就會丟失
  • fork 子程式的時候需要佔用一定的空間

AOF 持久化方式

AOF 是什麼?

將我們的寫命令全部記錄下來,恢復的時候,將檔案中的記錄全部執行一遍

AOF 是 redis 的另外一種持久化方式,以日誌的形式記錄每一個寫操作,將 redis 執行過的寫操作全部記錄下來,只允許追加檔案,不允許改寫檔案

redis 啟動的時候就會讀取這個 aof 檔案重建資料庫,也就是說,redis 重啟的時候,就會根據日誌檔案的內容將寫指令按照寫入順序執行,完成資料恢復

aof 儲存的是 appendonly.aof 檔案

# Please check https://redis.io/topics/persistence for more information.

appendonly no

# The name of the append only file (default: "appendonly.aof")

appendfilename "appendonly.aof"

# appendfsync always
appendfsync everysec
# appendfsync no

no-appendfsync-on-rewrite no

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

auto-aof-rewrite-min-size 64mb

當 aof 檔案大於 64 mb 的時候,就會再建立一個子程式來寫一個新的 aof 檔案

關於 aof 的配置基本上其他的都是使用預設的配置即可,我們只需要把 aof 模式開啟即可

appendonly yes

預設 appendonly 是不開啟的,我們修改了配置之後,重啟 redis-server 就會馬上生效

重寫規則說明

aof 預設是對檔案無限追加,檔案必然會越來越大

修改 redis.conf 為 aof 模式後,重啟 redis-server 可以看到 appendonly.aof 檔案

redis 客戶端連線 server 進行操作 redis ,簡單的設定幾個值

root@iZuf66y3tuzn4wp3h02t7pZ:/# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set name xiaozhu
OK
127.0.0.1:6379> set age 19
OK
127.0.0.1:6379> set hobby play
OK
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK
127.0.0.1:6379> shutdown
not connected>

檢視 appendonly.aof 檔案

appendonly.aof 檔案裡面存放的就是我們操作 redis 的寫命令的記錄

這個時候,我們認為的在 appendonly.aof 檔案中修改一些值

set
$2
k2
$2
v2
*3
$3
set
$2
k3
$2
ashdkklasdjkkv3        # 修改了這一行

啟動 redis-server ,檢視是否可以恢復資料

root@iZuf66y3tuzn4wp3h02t7pZ:/# redis-server /usr/local/redis/redis-6.2.5/redis.conf
root@iZuf66y3tuzn4wp3h02t7pZ:/# redis-cli
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected>
root@iZuf66y3tuzn4wp3h02t7pZ:/# ps axu |grep redis
root      1251  0.0  0.0  14436  1048 pts/0    S+   14:55   0:00 grep --color=auto redis
root@iZuf66y3tuzn4wp3h02t7pZ:/#

發現 redis-server 啟動失敗,是因為我們們的 appendonly.aof 檔案被人為的修改過,此時我們們需要修復該檔案,redis 有提供工具修改 aof 檔案,redis-check-aof

使用指令:

redis-check-aof --fix appendonly.aof

# redis-check-aof --fix appendonly.aof
0x              ce: Expected \r\n, got: 6864
AOF analyzed: size=223, ok_up_to=181, ok_up_to_line=47, diff=42
This will shrink the AOF from 223 bytes, with 42 bytes, to 181 bytes
Continue? [y/N]: y
Successfully truncated AOF
root@iZuf66y3tuzn4wp3h02t7pZ:/# redis-server /usr/local/redis/redis-6.2.5/redis.conf
root@iZuf66y3tuzn4wp3h02t7pZ:/# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> get k1
"v1"

修復 aof 檔案後,我們們再次啟動 redis-server 來回復磁碟資料,恢復成功,nice

aof 的優勢和劣勢

優勢

  • 每一次操作 reids 都會被記錄,檔案的完整性好
  • 每秒同步一次,可能會丟失一秒的資料
  • 從不同步,這個效率是最高的

劣勢

  • 相對於資料檔案來說,aof 檔案會遠大於 rdb 檔案,修復的速度也比 rdb 檔案慢
  • aof 執行的效率比 rdb 慢,所以 redis 預設的配置是 rdb 持久化

小結

兩種持久化方式簡述

  • RDB 持久化的方式能夠在指定的時間間隔內對資料進行快照儲存
  • AOF 持久化的方式記錄每次對伺服器的寫操作,當伺服器重啟或者當機的時候,會重新執行這些記錄裡面的寫操作命令來恢復資料,AOF 命令以 redis 協議追加儲存每次寫操作到檔案末尾,redis 還能對 aof 檔案進行後臺重寫,是的 AOF 檔案的體積不至於過大
  • 如果需求是隻做快取,只期望伺服器執行的時候資料存在,那麼不用做持久化

兩種持久化方式的開和不開

  • 可以同時開啟兩種持久化方式

    • 這種情況下,redis 重啟會先載入 aof 檔案來恢復資料,因為通常情況下 aof 檔案儲存的資料集比 rdb 的資料集要完整
    • rdb 資料集不是實時的,同時使用兩種方式時,伺服器重啟有隻會找 aof 檔案,那麼要不要只使用 aof 檔案呢?

    redis 的作者建議是不要只使用 aof 檔案,因為 rdb 更加適合用於備份資料庫,因為 aof 在不斷的變化,不好備份,快速重啟的時候,rdb 不會有 aof 可能潛在的 bug,留著 rdb 做一個兜底的機制

效能上的建議

對於 rdb 持久化

  • 由於 rdb 檔案只用於備份資料,建議只在 slave 上面持久化 rdb 檔案,15 分鐘持久化一次就夠了,也就是這一條指令 save 900 1
  • 如果開啟 aof 持久化,好處就是在極端情況下丟失資料也不會超過 2s 的資料,啟動指令碼就簡單的載入自己的 aof 檔案即可,這樣做也是有代價的

    • 代價之一就是 這樣做帶來了持續的 IO 操作
    • 代價之二就是 AOF 重寫的最後將重寫過程產生新資料寫入到新檔案造成的阻塞是不可避免的,只要硬碟許可,應該要儘量的減少 aof 重寫的頻率

對於 aof 持久化

  • aof 重寫的基礎大小值是 64 mb,我們可以設定成 5g 以上,預設超過原大小 100% 大小重寫,這個引數可以設定成一個合理的引數
  • 如果不開啟 aof 模式,僅僅靠主從複製實現高可用也是可以的,能夠省掉一大筆 IO 消耗,也減少了重寫帶來系統的效能波動,這樣做仍然是有代價的

    • 代價之一就是 如果主備 redis 同時掛掉(例如斷電),會丟失十幾分鐘的資料,啟動指令碼也要比較主備的 rdb 檔案,載入較新的那個 rdb 檔案

參考資料:

redis_doc

歡迎點贊,關注,收藏

朋友們,你的支援和鼓勵,是我堅持分享,提高質量的動力

好了,本次就到這裡

技術是開放的,我們的心態,更應是開放的。擁抱變化,向陽而生,努力向前行。

我是小魔童哪吒,歡迎點贊關注收藏,下次見~

相關文章