Redis 數據持久化方案

作爲內存數據庫,Redis 在數據存儲與讀取上的速度是毫不遜色的,這點毋庸置疑。但是對於內存來說,斷電或遇到故障後數據就會丟失,這卻是一個無法迴避的問題。令人欣慰的是,基於這樣的缺點,Redis 也提供了不同的持久化方案。

圖注:思維導圖

RDB持久化

對於 Redis 持久化來說,其實就是將存儲在內存中的數據寫入到磁盤裏,只不過寫入的方式是有一定策略的。
在這裏插入圖片描述
那麼我們先來看下第一種持久化,首先出場的是 RDB。

1、什麼是RDB持久化

英文名稱是 Redis DataBase,它還有一個常用的名字:快照持久化。所謂快照,在這裏指的是某一時刻的內存數據,而持久化則是將這一時刻的數據以二進制形式寫入到磁盤裏。

2、手動觸發機制

(1)save 命令

你可能會問了,那我通過什麼樣的方式來實現持久化呢?不知道你有沒有用過 save 這個命令,在 Redis裏擔任的角色是用來手動觸發持久化的。也就是說在 Redis 客戶端操作 save 命令就可以將內存數據寫入到磁盤裏。
在這裏插入圖片描述
不過你可千萬不要好奇,生產環境要是這麼玩兒的話,數據量少還行,數量大的話那估計八成得涼涼。爲什麼這麼說呢?你稍微瞭解下它的運行原理就知道了。

前面的文章中,我們提到了 Redis 處理命令的方式是以單線程形式來進行的。客戶端的請求都會放入一個隊列裏。當執行 save 命令時,如果執行時間很長的話,後面的請求就會被阻塞,客戶端發送的所有命令都會被拒絕。

這種方式生產場景要慎用!

(2)bgsave 命令

還有一個 bgsave 命令。與 save 不同的是,執行過程中它並不會阻塞客戶端的請求。而是將持久化工作交給子進程來執行,主進程仍負責客戶端請求的處理工作。
在這裏插入圖片描述

3、自動觸發機制

RDB 持久化既可以通過手動觸發,也可以通過服務器配置項來定期執行。

自動觸發通常是 Redis 中配置文件來執行的。有這麼個配置你需要了解下:

save m n
其中 m 代表秒數,n 代表次數,放在一起表示的是 m 秒內發生 n 次變化時,會觸發 bgsave。

瞭解了自動化配置,我們再來看下 Redis 配置文件 redis.conf 中的三個默認配置項:
在這裏插入圖片描述
save 900 1 表示的是時間900秒內,如果 Redis 中數據至少發生一次變化,就會執行 bgsave。後邊兩個就不用介紹了,一樣的原理。

看到這三個配置項,不知道你會不會有疑問,這三個到底該執行哪一個?答案是設置多個 save m n 命令時,滿足任何一個條件都會觸發持久化。

4、RDB 文件恢復

前面我們提到過了,持久化的目的就是爲了解決內存異常導致的數據丟失問題。那麼倘若如果真遇到了這樣的情況,RDB 文件如何來實現數據恢復呢?

在這裏插入圖片描述
開啓自動持久化後,數據會存儲到名爲 dump.rdb 的文件中。當 Redis 服務器重啓時,檢測到 dump.rdb 文件後,會自動加載進行數據恢復。

AOF持久化

介紹完了 RDB 後,我們再來看一種叫作 AOF 的持久化方式。

1、什麼是AOF持久化

英文名稱是 Append Only File。同樣地,它也有一個常用的名字:文件追加持久化。與RDB 不同的是,它是通過保存所執行的寫命令來實現的,並且保存的數據格式是客戶端發送的命令。
在這裏插入圖片描述

2、AOF 實現方式

想要使用 AOF 持久化方式,需要啓用配置文件中的 appendonly 參數。默認情況下,Redis 是不開啓的。
在這裏插入圖片描述
開啓 AOF 持久化後每執行一條修改數據的命令,Redis 就會將該命令寫入 aof_buf 緩衝區。後續寫入 AOF 文件中的操作是由下面的配置來控制的:
在這裏插入圖片描述
這三個配置項分別表示:

appendfsync always:每次寫入都進行刷盤操作,對性能影響最大,佔用磁盤 IO 較高,數據安全性最高。

appendfsync everysec:1秒刷一次盤,對性能影響相對較小。

appendfsync no:按照操作系統的機制進行刷盤,對性能影響最小,數據安全性低。

3、AOF 重寫機制

隨着命令的不斷寫入,AOF 文件會變得越來越大,這時候該如何是好呢?別急,Redis 中提供了瘦身功能,也就是重寫機制。
在這裏插入圖片描述
Redis 配置文件中有兩個對應的參數是來決定重寫機制的觸發時機的。

auto-aof-rewrite-percentage:AOF 文件距離上次文件增長超過多少百分比

auto-aof-rewrite-min-size:AOF 文件體積最小多大以上觸發

滿足所設置的條件時,會自動觸發 AOF 重寫,此時 Redis 會掃描整個實例的數據,重新生成一個 AOF 文件來達到瘦身的效果。

4、AOF 文件恢復

在這裏插入圖片描述
同樣地,我們也需要對 AOF 文件進行恢復。和 RBD 不同的是,Redis 中是通過創建一個不帶網絡連接的僞客戶端來進行實現的。爲什麼要創建僞客戶端呢?你想想 AOF 文件中的數據格式,都是由命令組成的。通過客戶端直接執行每條命令就可以將數據進行恢復。

在這裏需要注意的是,如果服務器開啓了 AOF 持久化功能,會優先使用 AOF 文件來進行恢復。只有在 AOF 關閉狀態下,服務器纔會使用 RDB 文件來進行還原。
在這裏插入圖片描述

兩種持久化的優/缺點

到這裏,對兩種持久化也有了一定的認識,那麼我們來看看它們分別有什麼優點和缺點:

1、RDB 優點與缺點

(1)優點

文件體積小:RDB 的文件內容是二進制格式,因此體積比實例內存小。恢復速度快:當 Redis 實例恢復時,加載 RDB 文件速度很快,能在很短時間內迅速恢復數據。

(2)缺點

數據缺失:RDB 保存的是某一時刻的數據,當 Redis 實例某一時刻異常時,會導致數據丟失。消耗資源:RDB 文件的生成會消耗大量的 CPU 和內存資源,有一定代價。

2、AOF 優點與缺點

(1)優點

數據更完整:AOF 中是及時寫入的方式,數據保存更完整。恢復時降低數據的損失率

易讀性強:AOF 中保存的數據格式是客戶端的寫入命令,可讀性性強。

(2)缺點

文件體積大:AOF 中存儲客戶端所有的寫命令,未經壓縮,隨着命令的寫入,文件會越來越大。增加磁盤IO:AOF 文件刷盤如果採用每秒刷一次的方式會導致磁盤IO升高,影響性能。

混合持久化

既然 RDB 與 AOF 持久化都存在各自的缺點,那麼有沒有一種更好的持久化方式?
接下來要介紹的是混合持久化。其實就是 RDB 與 AOF 的混合模式,這是 Redis4 之後新增的。

1、持久化方式

混合持久化是通過 aof-use-rdb-preamble 參數來開啓的。它的操作方式是這樣的,在寫入的時候先把數據以 RDB 的形式寫入文件的開頭,再將後續的寫命令以 AOF 的格式追加到文件中。這樣既能保證數據恢復時的速度,同時又能減少數據丟失的風險。

2、文件恢復

那麼混合持久化中是如何來進行數據恢復的呢?在 Redis 重啓時,先加載 RDB 的內容,然後再重放增量 AOF 格式命令。這樣就避免了 AOF 持久化時的全量加載,從而使加載速率得到大幅提升。

總結

RDB持久化

  • 將某一時刻的數據以二進制形式寫入到磁盤裏,服務重啓時檢測到對應文件自動加載進行數據恢復。
  • 有手動觸發和自動觸發兩種機制。

AOF持久化

  • 以文件追加的方式寫入客戶端執行的寫命令。
  • 數據恢復時,通過創建僞客戶端的方式執行命令,直到恢復完成。

混合持久化

  • 在寫入的時候先把數據以 RDB 的形式寫入文件的開頭,再將後續的寫命令以 AOF 的格式追加到文件中。