redis 系列16 持久化 RDB
一.概述
Redis是記憶體資料庫,一旦伺服器程序退出,伺服器中的資料庫記憶體資料狀態也會消失。為了解決這個問題,Redis提供了RDB 持久化功能,這個功能可以將redis在記憶體中的資料庫狀態儲存到磁碟中,避免資料意外丟失。
RDB持久化可以手動執行,也可以根據伺服器配置選項定期執行,是在指定的時間間隔,對你的資料進行快照儲存。該RDB檔案快照是一個經過壓縮的二進位制檔案。檔名為dump.rdb,該檔案儲存在redis目錄下,當redis伺服器停機後,只要RDB檔案存在,下次重啟Redis服務時就會自動還原資料庫資料狀態。
1.1 RDB檔案的建立
通過Redis兩個命令來生成RDB檔案,一是SAVE,另一個是BGSAVE。SAVE命令是會阻塞Redis伺服器程序,直到RDB檔案建立完畢為止,在阻塞期間,伺服器不能處理任何命令請求。
127.0.0.1:6379> save-- 等待RDB檔案建立完畢 OK
與SAVE不同,BGSAVE命令會派生出一個子程序,然後由子程序負責建立RDB檔案,伺服器程序(父程序)繼續處理命令請求。當BGSAVE命令在執行期間,客戶端再發送BGSAVE命令會被伺服器拒絕,因為同時執行兩個GBSAVE命令也會產生競爭條件。最後BGREWRITEAOF和GBSAVE兩個命令也不能同時執行。
127.0.0.1:6379> bgsave--派生子程序,並由子程序建立RDB檔案 Background saving started
1.2 RDB檔案載入
和建立檔案不同,RDB檔案的載入是在伺服器啟動時自動執行的,並沒有用於載入RDB檔案的命令,只要Redis伺服器在啟動時檢測到RDB檔案的存在,它就會自動載入RDB檔案。能過啟動時日誌記錄可以檢視。需要注意的是,如果打開了AOF持久化,那麼伺服器會優先使用AOF檔案來還原資料庫狀態。
1.3 自動間隔性儲存
檔案的建立除了SAVE和GBSAVE儲存RDB 檔案,還可以通過配置SAVE選項,讓伺服器每隔一段時間自動執行一次BGSAVE命令。可以配置SAVE選項設定多個儲存條件,只要任意一個條件被滿足,伺服器就會執行BGSAVE命令。
--預設配置的SAVE選項,儲存方式有三種條件,滿足任意一種就可以,如下: 127.0.0.1:6379> config get save 1) "save" 2) "900 1 300 10 60 10000"
(1) 伺服器在900秒之內,對資料庫進行了至少1次修改。
(2) 伺服器在300秒之內,對資料庫進行了至少10次修改。
(3) 伺服器在60秒之內,對資料庫進行了至少10000次修改。
1.4 檢查儲存條件是否滿足
Redis的伺服器週期性操作預設每隔100毫秒就會檢查執行一次,用於對正在執行的伺服器進行維護,其中一項工作是檢查save 選項所設定的儲存條件是否已經滿足,如果滿足就呼叫BGSAVE命令。
1.5 RDB工作方式
當Redis需要儲存dump.rdb檔案時,伺服器執行以下操作:
(1)Redis呼叫forks. 同時擁有父程序和子程序。
(2)子程序將資料集寫入到一個臨時 RDB 檔案中。
(3)當子程序完成對新 RDB 檔案的寫入時,Redis用新 RDB 檔案替換原來的 RDB 檔案,並刪除舊的 RDB 檔案。
1.6 RDB 檔案結構
下面簡單瞭解一下RDB檔案結構,這裡不再深入瞭解。下面指令碼顯示了本機dump.rdb檔案的位置。該rdb檔案結構中各部分 如下圖表格所示:
[root@xuegod64 redis]# pwd /usr/local/redis [root@xuegod64 redis]# ls -l -rwxrwxrwx 1 root root1687 11月 22 10:03 dump.rdb
檔案結構各部份 |
描述 |
redis |
RDB檔案最開頭是REDIS部分,儲存五個字元,程式在載入檔案時,快速檢查所載入的檔案是否是RDB檔案 |
Db_version |
一個字串表示的整數,4個位元組,記錄了RDB檔案的版本號 |
databases |
該部份包含著0個或任意多個數據庫,以及各資料庫中的鍵值對資料 |
Eof |
佔1個位元組,標誌著RDB檔案正文內容的結束,當程式遇到這個值的時候,就知道所有資料庫的所有鍵值對都已經載入完畢了 |
Check_sum |
佔8位元組的無符號整數,儲存一個校驗和,通過前四部分內容進行計算得出。用來檢查RDB檔案是否出錯或者損壞 |
下面通過linux的od命令來檢視redis伺服器產生的RDB 檔案,並指定-c引數可以以ASCII編碼方式列印資訊。資訊中能直接看到的資訊是:第一部分是redis, Db_version部分是0008, Eof部分是372 。
1.7 RDB優勢
(1) RDB是一個非常緊湊的檔案,它儲存了某個時間點得資料集,非常適用於資料集的備份,比如你可以在每個小時報儲存一下過去24小時內的資料,同時每天儲存過去30天的資料,這樣即使出了問題你也可以根據需求恢復到不同版本的資料集。
(2)RDB是一個緊湊的單一檔案,很方便傳送到另一個遠端資料中心,非常適用於災難恢復。
(3)RDB在儲存RDB檔案時父程序唯一需要做的就是fork出一個子程序,接下來的工作全部由子程序來做,父程序不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的效能。
(4)與AOF相比,在恢復大的資料集的時候,RDB方式會更快一些。
1.8 RDB缺點
(1)如果資料不允許任何丟失,那麼RDB不適合(雖然可以配置不同的save時間點)。
(2)經常fork子程序來儲存資料集到硬碟上,當資料集比較大的時候,fork的過程是非常耗時的,可能會導致Redis在一些毫秒級內不能響應客戶端的請求。
二. RDB持久化測試
(1) 首先關閉redis服務。當關閉服務時報錯,首先檢查一下是否是許可權的問題,因為在shutdown命令的時候,會進行save操作,而save需要操作dump.rdb檔案,如果沒有許可權則會報這個錯。
[root@xuegod64 redis]# redis-cli shutdown (error) ERR Errors trying to SHUTDOWN. Check logs -- 需要放開對dump.rdb檔案的寫入許可權,服務關閉成功 [root@xuegod64 redis]# redis-cli shutdown [root@xuegod64 redis]# redis-cli
(2) 服務啟動,首先set 寫入一條資料,然後關閉服務程序。
[hsr@xuegod64 redis]$ redis-serverredis.conf 127.0.0.1:6379> set name "test" OK 127.0.0.1:6379> get name "test" 127.0.0.1:6379> exit [hsr@xuegod64 redis]$ redis-cli shutdown
(3)重次重啟服務,檢視持久化
檢視剛才的鍵值對,發現鍵值對已存在,說明資料持久化儲存到了磁碟中,原理是在關閉服務時,會先呼叫save操作,儲存到dump.rdb檔案中,在重啟服務後,載入dump.rdb檔案。
[hsr@xuegod64 redis]$ redis-serverredis.conf [hsr@xuegod64 redis]$ redis-cli 127.0.0.1:6379> get name "test"