首頁  >  文章  >  資料庫  >  Redis中RDB持久化的範例分析

Redis中RDB持久化的範例分析

PHPz
PHPz轉載
2023-05-28 18:11:17934瀏覽

1、RDB 簡介

  RDB是Redis用來進行持久化的一種方式,是把目前記憶體中的資料集快照寫入磁碟,也就是Snapshot 快照(資料庫中所有鍵值對數據)。恢復時是將快照檔案直接讀到記憶體裡。

2、觸發方式

  RDB 有兩種觸發方式,分別是自動觸發和手動觸發。

①、自動觸發

  在 redis.conf 設定檔中的 SNAPSHOTTING 下,在這篇文章中我們介紹過。

  Redis中RDB持久化的範例分析

  ①、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 指令

  Redis中RDB持久化的範例分析

4、停止RDB 持久化

##  有些情況下,我們只想利用Redis的快取功能,並不像使用Redis 的持久化功能,那麼這時候我們最好停掉RDB 持久化。可以透過上面講的在設定檔redis.conf 中,可以註解掉所有的save 行來停用儲存功能或直接一個空字串來實現停用:save ""

  也可以透過指令:

#

5、RDB 的優勢和劣勢

  ①、優勢

Redis的資料集在特定時間點上保存在RDB檔案中,這個檔案非常緊湊。這種文件非常適合用於進行備份和災難復原。

  2.產生RDB檔案的時候,redis主程序會fork()一個子程序來處理所有保存工作,主程序不需要進行任何磁碟IO操作。

  3.RD​​B 在復原大資料集時的速度比 AOF 的復原速度還要快。

  ②、劣勢

  1、RDB方式資料沒辦法做到即時持久化/秒級持久化。因為bgsave每次運行都要執行fork操作創建子進程,屬於重量級操作(內存中的數據被克隆了一份,大致2倍的膨脹性需要考慮),頻繁執行成本過高(影響性能)

  2、RDB檔案使用特定二進位格式儲存,Redis版本演進過程中有多個格式的RDB版本,存在舊版Redis服務無法相容新版RDB格式的問題(版本不相容)

3.在一定間隔時間做一次備份,所以如果redis意外down掉的話,就會丟失最後一次快照後的所有修改(數據有丟失)

6、RDB 自動保存的原理

  Redis有個伺服器狀態結構:

1

#redis-cli config set save " "

#1

2

3

4

5

6

7

8

#9

struct redisService{

     struct saveparam *saveparams;

    ##long long dirty;

#     time_t#lastsave;

}

#  ①、先看記錄保存save條件的陣列saveparam,裡面每個元素都是一個saveparams 結構:

  前面我們在redis.conf 設定檔中進行了關於save 的設定:
1

#2

3

##4

5

6

struct

saveparam{

     

time_t seconds;

     

int changes;

#};

1  那麼伺服器狀態中的saveparam 數組將會是如下的樣子:

2

3

#save 900 1:表示900 秒內如果至少有1 個key 的值變化,則儲存

save 300 10:表示300 秒內如果至少有10 個key 的值變化,則儲存

save 60 10000:表示60 秒內如果至少有10000 個key 的值變化,則保存

  

Redis中RDB持久化的範例分析  ②、dirty 計數器和lastsave 屬性

  dirty 計數器記錄距離上一次成功執行save 指令或bgsave 指令之後,Redis伺服器了多少次修改(包括寫入、刪除、更新等操作)。

  lastsave 屬性是一個時間戳,記錄上一次成功執行 save 指令或 bgsave 指令的時間。

  通過這兩個命令,當伺服器成功執行一次修改操作,那麼dirty 計數器就會加1,而lastsave 屬性記錄上一次執行save或bgsave的時間,Redis 伺服器還有一個週期性操作函數severCron ,預設每隔100 毫秒就會執行一次,函數會遍歷並檢查saveparams 陣列中的所有儲存條件,只要有一個條件被滿足,那麼就會執行bgsave 指令。

  執行完成之後,dirty 計數器更新為 0 ,lastsave 也更新為執行指令的完成時間。

以上是Redis中RDB持久化的範例分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除