1. 程式人生 > >redis 系列16 持久化 RDB

redis 系列16 持久化 RDB

服務 負責 表示 保存數據 不同版本 正在運行的服務 記錄 bubuko alt

一.概述

  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 root    1687 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"

   

  總結:作為RDB快照持久化,如果是正常關閉redis服務,再重啟後數據是不會丟失的,但如果系統崩潰或者強殺,用戶將會丟失最近一次生成快照之後更改的所有數據。

  

  

redis 系列16 持久化 RDB