您好,登錄后才能下訂單哦!
Redis 相對于 Memcache 等其他的緩存產品,有一個比較明顯的優勢就是 Redis 不僅僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。這幾種豐富的數據類型我們花了兩篇文章進行了詳細的介紹,接下來我們要介紹 Redis 的另外一大優勢——持久化。
由于 Redis 是一個內存數據庫,所謂內存數據庫,就是將數據庫中的內容保存在內存中,這與傳統的MySQL,Oracle等關系型數據庫直接將內容保存到硬盤中相比,內存數據庫的讀寫效率比傳統數據庫要快的多(內存的讀寫效率遠遠大于硬盤的讀寫效率)。但是保存在內存中也隨之帶來了一個缺點,一旦斷電或者宕機,那么內存數據庫中的數據將會全部丟失。
為了解決這個缺點,Redis提供了將內存數據持久化到硬盤,以及用持久化文件來恢復數據庫數據的功能。Redis 支持兩種形式的持久化,一種是RDB快照(snapshotting),另外一種是AOF(append-only-file)。本篇博客先對 RDB 快照進行介紹。
1、RDB 簡介
RDB是Redis用來進行持久化的一種方式,是把當前內存中的數據集快照寫入磁盤,也就是 Snapshot 快照(數據庫中所有鍵值對數據)。恢復時是將快照文件直接讀到內存里。
回到頂部
2、觸發方式
RDB 有兩種觸發方式,分別是自動觸發和手動觸發。
①、自動觸發
在 redis.conf 配置文件中的 SNAPSHOTTING 下
①、save:這里是用來配置觸發 Redis的 RDB 持久化條件,也就是什么時候將內存中的數據保存到硬盤。比如“save m n”。表示m秒內數據集存在n次修改時,自動觸發bgsave(這個命令下面會介紹,手動觸發RDB持久化的命令)
默認如下配置:
save 900 1:表示900 秒內如果至少有 1 個 key 的值變化,則保存 save 300 10:表示300 秒內如果至少有 10 個 key 的值變化,則保存 save 60 10000:表示60 秒內如果至少有 10000 個 key 的值變化,則保存
當然如果你只是用Redis的緩存功能,不需要持久化,那么你可以注釋掉所有的 save 行來停用保存功能。可以直接一個空字符串來實現停用:save ""
②、stop-writes-on-bgsave-error :默認值為yes。當啟用了RDB且最后一次后臺保存數據失敗,Redis是否停止接收數據。這會讓用戶意識到數據沒有正確持久化到磁盤上,否則沒有人會注意到災難(disaster)發生了。如果Redis重啟了,那么又可以重新開始接收數據了
③、rdbcompression ;默認值是yes。對于存儲到磁盤中的快照,可以設置是否進行壓縮存儲。如果是的話,redis會采用LZF算法進行壓縮。如果你不想消耗CPU來進行壓縮的話,可以設置為關閉此功能,但是存儲在磁盤上的快照會比較大。
④、rdbchecksum :默認值是yes。在存儲快照后,我們還可以讓redis使用CRC64算法來進行數據校驗,但是這樣做會增加大約10%的性能消耗,如果希望獲取到最大的性能提升,可以關閉此功能。
⑤、dbfilename :設置快照的文件名,默認是 dump.rdb
⑥、dir:設置快照文件的存放路徑,這個配置項一定是個目錄,而不能是文件名。默認是和當前配置文件保存在同一目錄。
也就是說通過在配置文件中配置的 save 方式,當實際操作滿足該配置形式時就會進行 RDB 持久化,將當前的內存快照保存在 dir 配置的目錄中,文件名由配置的 dbfilename 決定。
②、手動觸發
手動觸發Redis進行RDB持久化的命令有兩種:
1、save
該命令會阻塞當前Redis服務器,執行save命令期間,Redis不能處理其他命令,直到RDB過程完成為止。
顯然該命令對于內存比較大的實例會造成長時間阻塞,這是致命的缺陷,為了解決此問題,Redis提供了第二種方式。
2、bgsave
執行該命令時,Redis會在后臺異步進行快照操作,快照同時還可以響應客戶端請求。具體操作是Redis進程執行fork操作創建子進程,RDB持久化過程由子進程負責,完成后自動結束。阻塞只發生在fork階段,一般時間很短。
基本上 Redis 內部所有的RDB操作都是采用 bgsave 命令。
ps:執行執行 flushall 命令,也會產生dump.rdb文件,但里面是空的,無意義
3、恢復數據
將備份文件 (dump.rdb) 移動到 redis 安裝目錄并啟動服務即可,redis就會自動加載文件數據至內存了。Redis 服務器在載入 RDB 文件期間,會一直處于阻塞狀態,直到載入工作完成為止。
獲取 redis 的安裝目錄可以使用 config get dir 命令
4、停止 RDB 持久化
有些情況下,我們只想利用Redis的緩存功能,并不像使用 Redis 的持久化功能,那么這時候我們最好停掉 RDB 持久化。可以通過上面講的在配置文件 redis.conf 中,可以注釋掉所有的 save 行來停用保存功能或者直接一個空字符串來實現停用:save ""
也可以通過命令:
redis-cli config set save " "
回到頂部
5、RDB 的優勢和劣勢
①、優勢
1.RDB是一個非常緊湊(compact)的文件,它保存了redis 在某個時間點上的數據集。這種文件非常適合用于進行備份和災難恢復。
2.生成RDB文件的時候,redis主進程會fork()一個子進程來處理所有保存工作,主進程不需要進行任何磁盤IO操作。
3.RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快。
②、劣勢
1、RDB方式數據沒辦法做到實時持久化/秒級持久化。因為bgsave每次運行都要執行fork操作創建子進程,屬于重量級操作(內存中的數據被克隆了一份,大致2倍的膨脹性需要考慮),頻繁執行成本過高(影響性能)
2、RDB文件使用特定二進制格式保存,Redis版本演進過程中有多個格式的RDB版本,存在老版本Redis服務無法兼容新版RDB格式的問題(版本不兼容)
3、在一定間隔時間做一次備份,所以如果redis意外down掉的話,就會丟失最后一次快照后的所有修改(數據有丟失)
回到頂部
6、RDB 自動保存的原理
Redis有個服務器狀態結構:
struct redisService{ //1、記錄保存save條件的數組 struct saveparam *saveparams; //2、修改計數器 long long dirty; //3、上一次執行保存的時間 time_t lastsave; }
①、首先看記錄保存save條件的數組 saveparam,里面每個元素都是一個 saveparams 結構:
struct saveparam{ //秒數 time_t seconds; //修改數 int changes; };
前面我們在 redis.conf 配置文件中進行了關于save 的配置:
save 900 1:表示900 秒內如果至少有 1 個 key 的值變化,則保存 save 300 10:表示300 秒內如果至少有 10 個 key 的值變化,則保存 save 60 10000:表示60 秒內如果至少有 10000 個 key 的值變化,則保存
那么服務器狀態中的saveparam 數組將會是如下的樣子:
②、dirty 計數器和lastsave 屬性
dirty 計數器記錄距離上一次成功執行 save 命令或者 bgsave 命令之后,Redis服務器進行了多少次修改(包括寫入、刪除、更新等操作)。
lastsave 屬性是一個時間戳,記錄上一次成功執行 save 命令或者 bgsave 命令的時間。
通過這兩個命令,當服務器成功執行一次修改操作,那么dirty 計數器就會加 1,而lastsave 屬性記錄上一次執行save或bgsave的時間,Redis 服務器還有一個周期性操作函數 severCron ,默認每隔 100 毫秒就會執行一次,該函數會遍歷并檢查 saveparams 數組中的所有保存條件,只要有一個條件被滿足,那么就會執行 bgsave 命令。
執行完成之后,dirty 計數器更新為 0 ,lastsave 也更新為執行命令的完成時間。
以上就是redis中RDB持久化詳解的詳細內容,更多請關注億速云其它相關文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。