Redis:持久化之RDB

Redis高性能的背後很大程度上是因爲其將所有數據都存儲在內存,然而當Redis重啓後,所有存儲在內存中的數據就會丟失。

這時我們希望Redis能將數據從內存中以某種形式同步到磁盤中,使得重啓後可以根據磁盤中的記錄恢復數據,這一過程稱之爲持久化。

Redis支持兩種方式的持久化:一種是RDB方式,另一種是AOF方式。前者根據指定的規則“定時”將內存中的數據存儲在磁盤上,而後者在每次執行命令後將命令本身記錄下來。

兩種持久化方式可以單獨使用其中一種,但更多場景下都是將兩者一起使用。今天先說說RDB這種持久化方式。

1. RDB簡介

RDB方式的持久化是通過快照完成的,當符合一定條件時Redis會自動將內存中的所有數據生成一份副本並存儲在磁盤上,這個過程即爲“快照”。

2. 觸發方式

觸發Redis進行快照主要有兩種方式,分別是自動觸發和手動觸發。

2.1 自動觸發

自動觸發是指當滿足符合規則條件時,Redis服務自動進行快照。自動觸發的條件由redis.conf配置文件的以下配置決定:

在這裏插入圖片描述

save m n表示m秒內數據集存在n次修改時,自動觸發bgsave。

2.2 手動觸發

手動觸發Redis進行RDB持久化的命令有兩種:

(1)save:執行該命令時 ,Redis服務器會被阻塞,不能再接收和處理其它命令,直到整個RBD持久化過程結束爲止。

(2)bgsave:執行該命令時,Redis會在後臺異步進行快照,此時Redis仍可對外響應來自客戶端的請求。實際上Redis的大部分RDB操作都是基於bgsave命令。

3. 相關配置

除了上面自動觸發的save m n的配置,在redis.conf配置文件中還有其它一些跟RDB相關的配置。主要有以下幾個:

(1)stop-writes-on-bgsave-error:默認值爲yes。當啓用了RDB並且最後一次保存數據失敗時,Redis是否停止寫入數據。

(2)rdbcompression:默認值是yes。用於表示持久化時,寫入磁盤的快照文件是否需要壓縮處理。

(3)rdbchecksum:默認值是yes。在存儲快照後,我們還可以讓redis進行數據校驗,但這樣做會增加更多的性能消耗,如果希望獲取到最大的性能提升,可以關閉此功能。

(4)dbfilename:設置快照的文件名,默認是dump.rdb

(5)dir:設置快照文件的存放路徑。

4. 恢復數據

接下來我們通過手動觸發快照的方式來演示RDB持久化的過程。

場景一:在redis中保存幾條數據,立即停掉redis進程,然後重啓redis,看看剛纔插入的數據還在不在。

(1)首先我們進入redis的dir配置對應的路徑,可以看到此時該目錄下還沒有rdb文件。

在這裏插入圖片描述

(2)進入redis cli交互命令行,並設置一個鍵值對,然後立即停掉redis進程。

在這裏插入圖片描述

(3)重啓redis服務,看看剛剛的鍵值對是否被持久化。

在這裏插入圖片描述

可以看到k1的值還在,爲什麼?理論上來說,我們在設置了k1的值後是立即停掉redis進程的,還沒到snapshotting檢查點,但是我們可以看到在dir配置的目錄下,確實生成了一個dump.rdb文件。

在這裏插入圖片描述

其實,在這裏我們通過redis-cli SHUTDOWN方式去停掉redis進程,這是一種安全退出的模式,redis在退出的時候會將內存中的數據立即生成一份完整的rdb快照。請看場景二的演示。

場景二:在redis中再保存幾條新的數據,立即用kill -9粗暴殺死redis進程,模擬redis故障異常退出,導致內存數據丟失的場景。

(1)此時dump.rdb中有一個k1鍵值對,我們現在增加一個k2鍵值對,然後通過kill -9命令直接殺死進程。

在這裏插入圖片描述

(2)重啓redis服務, 看看剛剛的k2是否被持久化。可以看到k2的值沒有被持久化,由於k1已經在dump.rdb中被持久化,所以k1的值仍然在。

在這裏插入圖片描述

場景三:手動設置一個save檢查點,然後通過kill -9粗暴殺死redis進程,模擬redis故障異常退出。

(1)我們設置一個檢查點,每5s有一個值發生變更,就生成一個新的dump.rdb文件。

save 900 1
save 300 10
save 60 10000
save 5 1

(2)刪除已經存在dump.rdb文件,並重啓redis。

在這裏插入圖片描述

(3)設置k1的值,然後過5s後,通過kill -9殺死進程。

在這裏插入圖片描述

(4)重啓redis服務, 看看剛剛的k1是否被持久化。可以看到k1的值在5s後被持久化,即使通過kill -9暴力停止redis服務,仍然被寫入dump.rdb中。

在這裏插入圖片描述

5. 停止RDB持久化

如果我們只想將Redis作爲緩存系統使用,並不需要考慮數據的持久化,那麼我們如何關閉RDB持久化呢?很簡單,只需要將redis.conf配置文件的所有save行註釋掉即可。

6. 快照原理

Redis默認會將快照文件存儲在Redis當前進程的工作目錄的dump.rdb文件中,當然我們也可以通過配置dir和dbfilename兩個參數分別指定快照文件的存儲路徑和文件名。其快照的過程如下:

(1)Redis使用fork函數複製一份當前進程(父進程)的副本(子進程);

(2)父進程繼續接收並處理客戶端請求,而子進程開始講內存中的數據寫入磁盤中的臨時文件;

(3)當子進程寫入完所有數據後會用該臨時文件替換舊的RDB文件,至此一次快照操作完成。

整個快照過程中Redis不會修改RDB文件,只有快照結束後纔會將舊的文件替換成新的,也就是說RDB文件在任何時候都是完整的,這使得我們可以通過定時備份RDB文件來實現Redis數據庫的備份。

通過RDB方式實現持久化,一旦Redis發送異常退出,就會丟失最後一次快照以後更改的所有數據。這就需要根據實際使用場景通過組合設置自動快照條件的方式來將可能發生的數據損失控制在可接受範圍內。如果無法忍受近幾秒或者更長的數據丟失,則可以考慮使用AOF方式進行持久化。

——End——
更多精彩分享,可掃碼關注微信公衆號哦。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章