目錄
- 前言
- Redis 持久化機制
- RDB 持久化機制
- RDB 機制觸發(fā)條件
- 自動觸發(fā)
- RDB 機制相關(guān)配置文件
- RDB 機制優(yōu)點
- RDB 機制缺點
- AOF 持久化機制
- AOF 機制如何開啟
- AOF 機制數(shù)據(jù)是否實時寫入磁盤
- AOF 文件重寫
- AOF 重寫緩沖區(qū)
- AOF 機制觸發(fā)條件
- AOF 機制機制優(yōu)點
- AOF 機制機制缺點
- 總結(jié)
前言
Redis
作為一款內(nèi)存數(shù)據(jù)庫,被廣泛使用于緩存,分布式鎖等場景,那么假如斷電或者因其他因素導(dǎo)致 Reids
服務(wù)宕機,在重啟之后數(shù)據(jù)會丟失嗎?
Redis 持久化機制
Redis
雖然是定義為一個內(nèi)存數(shù)據(jù)庫,但是其也支持?jǐn)?shù)據(jù)的持久化,在 Redis
中提供了兩種持久化機制:RDB
持久化和 AOF
持久化。
RDB 持久化機制
RDB
全稱為:Redis DataBase
,是 Redis
當(dāng)中默認(rèn)的持久化方案。當(dāng)觸發(fā)持久化條件時,Redis
默認(rèn)會生成一個 dump.rdb
文件,Redis
在重啟的時候就會通過解析 dump.rdb
文件進行數(shù)據(jù)恢復(fù)。
RDB 機制觸發(fā)條件
RDB
持久化機制有兩種觸發(fā)方式:自動觸發(fā)和手動觸發(fā)。
自動觸發(fā)
自動觸發(fā)方式也可以分為三種:
- 執(zhí)行
flushall
命令(flushdb
命令不會觸發(fā))時,不過此時生成的 dump
文件內(nèi)的數(shù)據(jù)是空的(dump
文件還會存儲一些頭信息,所以文件本身是有內(nèi)容的,只是沒有數(shù)據(jù)),沒有什么太大的實際意義。
- 執(zhí)行
shutdown
命令時會觸發(fā)生成 dump
文件。
- 通過配置文件自動生成,
Redis
中配置文件默認(rèn)配置如下,只要達到這三個條件中的任意一個,就會觸發(fā) Redis
的RDB
持久化機制。
save 900 1 //900秒內(nèi)至少有1個key被添加或者更新
save 300 10 //300秒內(nèi)至少有10個key被添加或者更新
save 60 10000 //60秒內(nèi)至少有10000個key被添加或者更新
手動觸發(fā)
除了自動觸發(fā),Redis
中還提供了 2
個手動觸發(fā) RDB
機制的命令(這兩個命令不能同時被執(zhí)行,一旦一個命令正在執(zhí)行中,另一個命令會被拒絕執(zhí)行):
save
:這個命令會阻塞 Redis
服務(wù)器進程,直到成功創(chuàng)建 RDB
文件,也就是說在生成 RDB
文件之前,服務(wù)器不能處理客戶端發(fā)送的任何命令。
bgsave
:父進程會執(zhí)行 fork
操作來創(chuàng)建一個子進程。RDB
文件由子進程來負(fù)責(zé)生成,父進程可以正常處理客戶端發(fā)送的命令(這里也是 Redis
不僅僅只是單線程的一個體現(xiàn))。
如果想要知道上一次成功執(zhí)行 save
或者 bgsave
命令的時間,可以執(zhí)行 lastsave
命令進行查看,lastsave
命令返回的是一個 unix
時間戳。
RDB 機制相關(guān)配置文件
除了上面提到的觸發(fā)生成 rdb
文件的配置參數(shù),RDB
持久化機制還有如下一些相關(guān)命令:
dir
:rdb
文件生成目錄。默認(rèn)是 ./
(當(dāng)前目錄),可以執(zhí)行命令 config get dir
進行查看,如下圖所示說明當(dāng)前 dump
文件生成目錄為 /usr/local/redis-5.0.5/bin
:
dbfilename
:rdb
文件名。默認(rèn)是 dump.rdb
。
rdbcompression
:rdb
文件是否是 LZF
壓縮文件。默認(rèn)是 yes
。
rdbchecksum
:是否開啟數(shù)據(jù)校驗。默認(rèn)是 yes
。
RDB 機制優(yōu)點
RDB
是一個非常緊湊的壓縮文件,保存了不同時間點上的文件,非常適合用來災(zāi)備和數(shù)據(jù)恢復(fù)。
RDB
最大限度地提高了 Redis
的性能,因為 Redis
父進程需要做的唯一的工作就是派生一個子進程來完成剩下的工作,父進程永遠(yuǎn)不會執(zhí)行磁盤 I/O
或類似的耗時操作。
- 與后面介紹的
AOF
持久化機制比較,RDB
方式恢復(fù)數(shù)據(jù)的速度更快。
RDB 機制缺點
RDB
無法做到實時備份,所以如果 Redis
因異常停止工作而沒有正確的關(guān)機,那么從上一次備份的到異常宕機的這一段時間的數(shù)據(jù)將會丟失。
RDB
通常需要父進程來執(zhí)行 fork
操作創(chuàng)建子線程,所以如果頻繁執(zhí)行 fork
操作而 CPU
性能又不是很高的話可能會造成短時間內(nèi)父進程不可用。
AOF 持久化機制
AOF
全稱為:Append Only File
,是 Redis
當(dāng)中提供的另一種持久化機制。AOF
采用日志的形式將每個寫操作追加到文件中。開啟 AOF
機制后,只要執(zhí)行更改 Redis
數(shù)據(jù)的命令時,命令就會被寫入到 AOF
文件中。在 Redis
重啟的時候會根據(jù)日志內(nèi)容依次執(zhí)行 AOF
文件中的命令來恢復(fù)數(shù)據(jù)。
AOF
和 RDB
最大的不同是:AOF
記錄的是執(zhí)行命令(類似于 MySQL
中 binlog
的 statement
格式),而RDB
記錄的是數(shù)據(jù)(類似于 MySQL
中 binlog
的 row
格式)。
需要注意的是:假如同時開啟了 RDB
和 AOF
兩種機制,那么 Redis
會優(yōu)先選擇 AOF
持久化文件來進行數(shù)據(jù)恢復(fù)。
AOF 機制如何開啟
AOF
機制默認(rèn)是關(guān)閉的,可以通過以下配置文件進行修改
appendonly no //是否開啟AOF機制,默認(rèn)是no表示關(guān)閉,修改為yes則表示開啟
appendfilename "appendonly.aof" //AOF文件名
PS:和 RDB
機制一樣,其生成文件的路徑也是通過 dir
屬性進行配置。
AOF 機制數(shù)據(jù)是否實時寫入磁盤
AOF
機制下數(shù)據(jù)是否實時寫入磁盤,這個和 MySQL
的 redo log
機制很類似,也是需要通過參數(shù)來進行控制。
AOF
數(shù)據(jù)何時寫入磁盤由參數(shù) appendfsync
來進行控制:
appendfsync |
描述 |
備注 |
always |
寫入緩存的同時通知操作系統(tǒng)刷新(fsync)到磁盤(但是也可能會有部分操作系統(tǒng)只是盡快刷盤,而不是實時刷盤) |
Slow, Safest |
everysec |
先寫入緩存,然后每秒中刷一次盤(默認(rèn)值),這種模式極端情況可能會丟失 1s 的數(shù)據(jù) |
Compromise |
no |
只寫入緩存,什么時候刷盤由操作系統(tǒng)自己決定 |
Faster |
AOF 文件重寫
AOF
機制主要是通過記錄執(zhí)行命令的方式來實現(xiàn)的,那么隨著時間的增加,AOF
文件不可避免的會越來越大,而且可能會出現(xiàn)很多冗余命令。比如同一個 key
值執(zhí)行了 10000
次 set
操作,實際上前面 9999
次對恢復(fù)數(shù)據(jù)來說都是沒用的,只需要執(zhí)行最后一次命令就可以把數(shù)據(jù)恢復(fù),正是為了避免這種問題,AOF
機制就提供了文件重寫功能。
重寫原理分析
AOF
重寫時 Redis
并不會去分析原有的文件,因為如果原有文件過大,分析也會很耗時,所以 Redis
選擇的做法就是重新去 Redis
中讀取現(xiàn)有的鍵值對,然后用一條命令記錄鍵值對的值。
只使用一條命令也有一個前提,那就是一個集合鍵或者列表鍵或者哈希鍵內(nèi)包含的元素不能超過 64
個,一旦超過 64
個,就會使用多條命令來進行記錄。
AOF 重寫緩沖區(qū)
AOF
重寫的時候一般都會有大量的寫操作,所以為了不阻塞客戶端的命令請求,Redis
會把重寫操作放入到子進程中執(zhí)行,但是放入子進程中執(zhí)行也會帶來一個問題,那就是重寫期間如果同時又執(zhí)行了客戶端發(fā)過來的命令,又該如何保證數(shù)據(jù)的一致性?
為了解決數(shù)據(jù)不一致問題,Redis
中引入了一個 AOF
重寫緩沖區(qū)。當(dāng)開始執(zhí)行 AOF
文件重寫之后又接收到客戶端的請求命令,不但要將命令寫入原本的 AOF
緩沖區(qū)(根據(jù)上面提到的參數(shù)刷盤),還要同時寫 入 AOF
重寫緩沖區(qū):
一旦子進程完成了 AOF
文件的重寫,此時會向父進程發(fā)出信號,父進程收到信號之后會進行阻塞(阻塞期間不執(zhí)行任何命令),并進行以下兩項工作:
- 將
AOF
重寫緩沖區(qū)的文件刷新到新的 AOF
文件內(nèi)。
- 將新
AOF
文件進行改名并原子的替換掉舊的 AOF
文件。
完成了上面的兩項工作之后,整個 AOF
重寫工作完成,父進程開始正常接收命令。
AOF 機制觸發(fā)條件
AOF
機制的觸發(fā)條件同樣也分為自動觸發(fā)和手動觸發(fā)。
自動觸發(fā):自動觸發(fā)可以通過以下參數(shù)進行設(shè)置:
auto-aof-rewrite-percentag //文件大小超過上次AOF重寫之后的文件的百分比。默認(rèn)100,也就是默認(rèn)達到上一次AOF重寫文件的2倍之后會再次觸發(fā)AOF重寫
auto-aof-rewrite-min-size //設(shè)置允許重寫的最小AOF文件大小,默認(rèn)是64M。主要是避免滿足了上面的百分比,但是文件還是很小的情況。
手動觸發(fā):執(zhí)行 bgrewriteaof
命令。
注意:bgrewriteaof
命令也不能和上面 RDB
持久化命令 bgsave
同時執(zhí)行,這么做是為了避免同時創(chuàng)建兩個子進程來同時執(zhí)行大量寫磁盤操作,影響到 Redis
的性能。
AOF 機制機制優(yōu)點
- 使用
AOF
機制,可以自由選擇不同 fsync
(刷盤)策略,而且在默認(rèn)策略下最多也僅僅是損失 1s
的數(shù)據(jù)。
AOF
日志是一個僅追加的日志,因此如果出現(xiàn)斷電,也不存在查找或損壞問題。即使由于某些原因(磁盤已滿或其他原因),日志已經(jīng)寫了一半的命令結(jié)束,redis-check-aof工具也能夠輕松地修復(fù)它。
- 當(dāng)
AOF
文件變得太大時,Redis
能夠在后臺自動重寫。
- 不同于
RDB
的文件格式,AOF
是一種易于理解和解析的格式,依次包含所有操作的日志。
AOF 機制機制缺點
- 對于相同的數(shù)據(jù)集,
AOF
文件通常比等效的 RDB
文件大。
- 根據(jù)
fsync
的具體策略,AOF
機制可能比 RDB
機制慢。但是一般情況下,fsync
設(shè)置為每秒的性能仍然很高,禁用 fsync
后,即使在高負(fù)載下,它的速度也能和 RDB
一樣快。
- 因為
AOF
文件是追加形式,可能會遇到 BRPOP
、LPUSH
等阻塞命令的錯誤,從而導(dǎo)致生成的 AOF
在重新加載時不能復(fù)制完全相同的數(shù)據(jù)集,而 RDB
文件每次都是重新從頭創(chuàng)建快照,這在一定程度上來說 RDB
文件更加健壯。
總結(jié)
本文主要介紹了 Redis
的兩種持久化機制:RDB
和 AOF
,并分別介紹了兩種持久化機制的原理,通過對兩種持久化機制的對比分析了兩種持久化機制各自的優(yōu)點和缺點。
到此這篇關(guān)于為什么斷電后Redis數(shù)據(jù)不會丟失的文章就介紹到這了,更多相關(guān)Redis數(shù)據(jù)丟失內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- Redis主從集群切換數(shù)據(jù)丟失的解決方案
- 解決docker重啟redis,mysql數(shù)據(jù)丟失的問題