同樣是持久化,竟然有這麼大的差別!

語言: CN / TW / HK

作為記憶體資料庫,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 的格式追加到檔案中。

關於作者

作者:大家好,我是萊烏,BAT搬磚工一枚。從小公司進入大廠,一路走來收穫良多,想將這些經驗分享給有需要的人,因此建立了公眾號「IT界農民工」。定時更新,希望能幫助到你。