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相對也會慢一些。

