首頁  >  文章  >  資料庫  >  redis中RDB持久化詳解

redis中RDB持久化詳解

尚
轉載
2019-11-30 16:08:461967瀏覽

redis中RDB持久化詳解

Redis 相對於 Memcache 等其他的快取產品,有一個比較明顯的優點就是Redis 不僅僅支援簡單的key-value類型的數據,同時還提供list,set,zset ,hash等資料結構的儲存。這幾種豐富的資料類型我們花了兩篇文章進行了詳細的介紹,接下來我們要介紹 Redis 的另外一大優點——持久化。 (建議:redis影片教學

由於Redis 是記憶體資料庫,所謂記憶體資料庫,就是將資料庫中的內容保存在記憶體中,這與傳統的MySQL,Oracle等關係型資料庫直接將內容儲存到硬碟相比,記憶體資料庫的讀寫效率比傳統資料庫要快的多(記憶體的讀寫效率遠大於硬碟的讀寫效率)。但是保存在記憶體中也隨之帶來了一個缺點,一旦斷電或宕機,那麼記憶體資料庫中的資料將會全部遺失。

為了解決這個缺點,Redis提供了將記憶體資料持久化到硬碟,以及用持久化檔案來恢復資料庫資料的功能。 Redis 支持兩種形式的持久化,一種是RDB快照(snapshotting),另外一種是AOF(append-only-file)。本篇部落格先對 RDB 快照進行介紹。

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

也可以通过命令:

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 数组将会是如下的样子:

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知识请关注redis数据库教程栏目。

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

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