二 Redis的兩種持久化方式---RDB和AOF

Redis是內(nèi)存數(shù)據(jù)庫,但是為了防止數(shù)據(jù)丟失,提供了持久化到硬盤的機制。有RDB和AOF兩種持久化方式。

RDB (Redis DataBase)

RDB方式會在指定的時間間隔內(nèi),將內(nèi)存中的數(shù)據(jù)快照寫入磁盤,它恢復(fù)時是將數(shù)據(jù)快照讀到內(nèi)存。

1. Redis RDB配置

################################ SNAPSHOTTING  ################################
#
# Save the DB on disk:
#
#   save <seconds> <changes>
#
#   Will save the DB if both the given number of seconds and the given
#   number of write operations against the DB occurred.
#
#   In the example below the behaviour will be to save:
#   after 900 sec (15 min) if at least 1 key changed
#   after 300 sec (5 min) if at least 10 keys changed
#   after 60 sec if at least 10000 keys changed
#
#   Note: you can disable saving completely by commenting out all "save" lines.
#
#   It is also possible to remove all the previously configured save
#   points by adding a save directive with a single empty string argument
#   like in the following example:
#
#   save ""

save 900 1
save 300 10
save 60 10000

# By default Redis will stop accepting writes if RDB snapshots are enabled
# (at least one save point) and the latest background save failed.
# This will make the user aware (in a hard way) that data is not persisting
# on disk properly, otherwise chances are that no one will notice and some
# disaster will happen.
#
# If the background saving process will start working again Redis will
# automatically allow writes again.
#
# However if you have setup your proper monitoring of the Redis server
# and persistence, you may want to disable this feature so that Redis will
# continue to work as usual even if there are problems with disk,
# permissions, and so forth.
stop-writes-on-bgsave-error yes

# Compress string objects using LZF when dump .rdb databases?
# For default that's set to 'yes' as it's almost always a win.
# If you want to save some CPU in the saving child set it to 'no' but
# the dataset will likely be bigger if you have compressible values or keys.
rdbcompression yes

# Since version 5 of RDB a CRC64 checksum is placed at the end of the file.
# This makes the format more resistant to corruption but there is a performance
# hit to pay (around 10%) when saving and loading RDB files, so you can disable it
# for maximum performances.
#
# RDB files created with checksum disabled have a checksum of zero that will
# tell the loading code to skip the check.
rdbchecksum yes

# The filename where to dump the DB
dbfilename dump.rdb

# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir /usr/local/var/db/redis/

2. 哪些情況會觸發(fā)Redis RDB持久化

將配置改成save 60 5,重啟redis服務(wù)器.

2.1 自動觸發(fā)---配置文件中的save

也就是說60秒內(nèi),如果有5次或以上的寫操作,就會觸發(fā)Redis持久化。 配置文件中的save,執(zhí)行的是bgsave操作,后面會講到。

#1. 查看rdb快照文件目錄,一開始為空,沒有dump數(shù)據(jù)。
$ ls /usr/local/var/db/redis

#2. 在60s內(nèi)進行5次寫操作
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set key1 value1
OK
127.0.0.1:6379> set key1 value2
OK
127.0.0.1:6379> set key1 value3
OK
127.0.0.1:6379> set key1 value4
OK
127.0.0.1:6379> set key1 value5
OK
127.0.0.1:6379> get key1
"value5"

#3. 查看rdb快照目錄,生成了dump.rdb文件
$ ls /usr/local/var/db/redis
dump.rdb

#4. 看看dump.rdb文件的內(nèi)容
$ less /usr/local/var/db/redis/dump.rdb
REDIS0009<FA>   redis-ver^E5.0.3<FA>
redis-bits<C0>@<FA>^Ectime<C2>O<C6>r`<FA>^Hused-mem<C2>`W^O^@<FA>^Laof-preamble<C0>^@<FE>^@<FB>^A^@^@^Dkey1^Fvalue5<FF><A1>
<98>hK<BE>P^A
/usr/local/var/db/redis/dump.rdb (END)

2.2 shutdown命令

正常關(guān)閉redis server,也會觸發(fā)rdb持久化。

#1. 寫入一個key
127.0.0.1:6379> set key2 value2
OK

#2. 馬上觀察dump.rdb,沒有更新

#3. shutdown redis server
127.0.0.1:6379> shutdown
not connected>

#4. 再去觀察dump.rdb,發(fā)現(xiàn)觸發(fā)了持久化,新寫的key被存到了磁盤。
REDIS0009<FA>   redis-ver^E5.0.3<FA>
redis-bits<C0>@<FA>^Ectime<C2>^@<C9>r`<FA>^Hused-mem°^G^P^@<FA>^Laof-preamble<C0>^@<FE>^@<FB>^B^@^@^Dkey2^Fvalue2^@^Dkey1^Fvalue5<FF><98><FE>L1<F7>Sz 
/usr/local/var/db/redis/dump.rdb (END)

注意?。?!
意外關(guān)閉,例如kill -9,不會觸發(fā)持久化。

2.3 flushall也會觸發(fā)持久化,硬盤中的dump.rdb會被清理。

#1. 執(zhí)行flushall之前,dump文件有119B
redis $ ls -ltrh
total 8
-rw-r--r--  1 a123  admin   119B  4 11 18:14 dump.rdb

#2. 執(zhí)行flushall操作
127.0.0.1:6379> flushall
OK

#3. 查看dump.rdb,變小成92B,其中數(shù)據(jù)都被清理掉了。
redis $ ls -ltrh
total 8
-rw-r--r--  1 a123  admin    92B  4 11 18:17 dump.rdb

redis $ less dump.rdb
"dump.rdb" may be a binary file.  See it anyway? 
REDIS0009<FA>   redis-ver^E5.0.3<FA>
redis-bits<C0>@<FA>^Ectime<C2><C3><CC>r`<FA>^Hused-mem<C2>^P^K^P^@<FA>^Laof-preamble<C0>^@<FF>.e1o<E8>  #<ED>
dump.rdb (END)

注意?。?!
flushdb不會觸發(fā)持久化,只是清空內(nèi)存中的數(shù)據(jù),也就是說當前dump.rdb中還是有持久化數(shù)據(jù)的。不過當后續(xù)又觸發(fā)了rdb持久化時,新的數(shù)據(jù)快照會被持久化到硬盤,那么flushdb之前的數(shù)據(jù)就會在硬盤中被清除了。

2.4 執(zhí)行命令save或者bgsave,也會觸發(fā)持久化。不過兩者略有區(qū)別。

save是只管保存,其他不管,全部阻塞(持久化是用的主進程,不會fork子進程). 所以在線上,最好不要使用save命令,太危險。

#1. save命令,觸發(fā)持久化。
127.0.0.1:6379> save
OK

#2. 觀察redis server log
16167:M 11 Apr 2021 18:32:40.092 * DB saved on disk

bgsave redis會在后臺異步進行快照操作(fork子進程),同時可以響應(yīng)客戶端的請求.

#1. bgsave命令
127.0.0.1:6379> bgsave
Background saving started

#2. 查看redis server log,會發(fā)現(xiàn)新開啟了一個進程來處理持久化操作
16167:M 11 Apr 2021 18:32:54.925 * Background saving started by pid 16264
16264:C 11 Apr 2021 18:32:54.927 * DB saved on disk
16167:M 11 Apr 2021 18:32:54.953 * Background saving terminated with success

3. RDB 自動觸發(fā),save m n的實現(xiàn)原理

(下圖引用自互聯(lián)網(wǎng))

  • redis將save配置保存到saveparam參數(shù):


    save配置保存到saveparam
  • 另外,服務(wù)器還保存了dirty計數(shù)器和lastsave屬性


    dirty,lastsave
  • 最后,通過servercron函數(shù)默認每隔100毫秒執(zhí)行一次,檢查保存條件是否滿足。若滿足,則執(zhí)行持久化,并更新lastsave的時間。

4. RDB的優(yōu)點與缺點

4.1 優(yōu)點

  • rdb備份文件緊湊,全量備份。文件相對不會特別大,恢復(fù)起數(shù)據(jù)來相對較快。
  • rdb備份時,是fork子進程進行備份操作,不影響父進程,這樣redis性能相對較高。

4.2 缺點

  • 如果在下一次持久化之前出現(xiàn)故障,沒來得及寫入磁盤的數(shù)據(jù)就會丟失。

AOF (Append Only File)

將我們的所有寫命令都記錄下來,恢復(fù)的時候就把這個文件全部再執(zhí)行一遍。

1. Redis AOF配置

############################## APPEND ONLY MODE ###############################

# By default Redis asynchronously dumps the dataset on disk. This mode is
# good enough in many applications, but an issue with the Redis process or
# a power outage may result into a few minutes of writes lost (depending on
# the configured save points).
#
# The Append Only File is an alternative persistence mode that provides
# much better durability. For instance using the default data fsync policy
# (see later in the config file) Redis can lose just one second of writes in a
# dramatic event like a server power outage, or a single write if something
# wrong with the Redis process itself happens, but the operating system is
# still running correctly.
#
# AOF and RDB persistence can be enabled at the same time without problems.
# If the AOF is enabled on startup Redis will load the AOF, that is the file
# with the better durability guarantees.
#
# Please check http://redis.io/topics/persistence for more information.

appendonly no

# The name of the append only file (default: "appendonly.aof")

appendfilename "appendonly.aof"

# appendfsync always
appendfsync everysec
# appendfsync no

2. 開啟AOF,命令被記錄到appendonly.aof,同時rdb 持久化也依然生效。

開啟AOF的話,默認是appendfsync everysec,也就是每秒都會append到aof文件。
有另一個選項appendfsync always,對于每一次寫都會append到aof文件。這種方式會影響redis的性能。

#1. 開啟AOF之后,重啟redis server,存幾個值
redis $ redis-cli -p 6379 -h 127.0.0.1
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK
127.0.0.1:6379> set k4 v4
OK
127.0.0.1:6379> set k5 v5
#2. 生成了aof和rdb持久化文件
$ ls
appendonly.aof  dump.rdb

$ vim appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
set
$2
k1
$2
v1
*3
$3
set
$2
k2
$2
v2
*3
$3
set
$2
k3
$2
v3
*3
$3
set
$2
k4
$2
v4
*3
$3
set
$2
k5
$2
v5

3. redis-check-aof

如果aof文件有錯誤,redis就無法啟動。這時可以用redis自帶工具 redis-check-aof --fix來修復(fù)文件。修復(fù)之后就能成功啟動redis了。

#1. 在appendonly.aof文件末尾加上一些字符串,來破壞aof文件,內(nèi)容如下
set
$2
k5
$2
v5
testredischeckaof
#2. 重啟redis server,報錯
15637:M 15 Apr 2021 22:29:32.481 # Server initialized
15637:M 15 Apr 2021 22:29:32.481 # Bad file format reading the append only file: make a backup of your AOF file, then use ./redis-check-aof --fix <filename>
#3. 修復(fù)aof文件
$ redis-check-aof --fix appendonly.aof
0x              a8: Expected prefix '*', got: 't'
AOF analyzed: size=187, ok_up_to=168, diff=19
This will shrink the AOF from 187 bytes, with 19 bytes, to 168 bytes
Continue? [y/N]: y
Successfully truncated AOF

4. AOF 優(yōu)缺點

4.1 優(yōu)點

  • 相對rdb,aof數(shù)據(jù)安全性更高。aof如果設(shè)置為appendfsync everysec,只是有可能會丟一秒的數(shù)據(jù)。

4.2 缺點

  • 相較于rdb,aof同步文件可能會比較大,因為它記錄的是每一個寫操作?;謴?fù)起來,aof相對也會慢一些。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容