redis 學(xué)習(xí),redis 持久化 RDB 和 AOF
Redis 持久化
redis 是內(nèi)存數(shù)據(jù)庫(kù),如果不將內(nèi)存中數(shù)據(jù)庫(kù)保存到磁盤(pán)上,那么服務(wù)器一旦宕機(jī),或者 redis 進(jìn)程退出,不僅數(shù)據(jù)會(huì)被丟失,服務(wù)器中的數(shù)據(jù)庫(kù)狀態(tài)也會(huì)被丟失
因此 redis 提供了持久化的功能
redis 的持久化分為 RDB 和 AOF
RDB (Redis DatabBase)
在主從復(fù)制中,rdb文件都作為備用的,放在從機(jī)上面

在指定時(shí)間間隔內(nèi)將內(nèi)存中的數(shù)據(jù)集快照寫(xiě)入到磁盤(pán)中,這就是快照 snapshot ,恢復(fù)快照的時(shí)候,是把快照文件讀入到內(nèi)存中。
redis 通過(guò) fork 的方式創(chuàng)建一個(gè)子進(jìn)程來(lái)專門(mén)做持久化的動(dòng)作,
先將數(shù)據(jù)寫(xiě)入到一個(gè)臨時(shí)文件中,待持久化過(guò)程結(jié)束,再用這個(gè)臨時(shí)文件替換上一次的持久化好的文件
整個(gè)過(guò)程中,主進(jìn)程是不進(jìn)行任務(wù) IO 操作的,這就保障了極高的性能
如果需要進(jìn)行大規(guī)模的數(shù)據(jù)恢復(fù),且對(duì)于數(shù)據(jù)的完整性要求不那么敏感和嚴(yán)格,選擇 RDB 的持久化方式比 AOF 的持久化方式更優(yōu),更加高效。
RDB 雖然性能高,但是在 最后一次持久化后的數(shù)據(jù)可能會(huì)被丟失,redis 默認(rèn)就是使用的 RDB 持久化方式,一般情況下也不需要修改
save 60 3
# The filename where to dump the DB
dbfilename dump.rdb
dir ./
復(fù)制代碼

我們?cè)O(shè)置 60s 內(nèi)若 有操作 redis 3 次,那就做一次持久化
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> config get dir
1) "dir"
2) "/root"
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
復(fù)制代碼dump.db 文件是生成在 dir 目錄下的,我們這里的 dir 目錄是 /root
進(jìn)行上述操作之后,我們發(fā)現(xiàn) /root 生成了 dump.rdb 文件 ,咱們將該文件刪除掉,再嘗試一次
root@iZuf66y3tuzn4wp3h02t7pZ:~# rm dump.rdb -rf
root@iZuf66y3tuzn4wp3h02t7pZ:~# redis-cli
127.0.0.1:6379> set p1 1
OK
127.0.0.1:6379> set p2 1
OK
127.0.0.1:6379> set p3 3
OK
root@iZuf66y3tuzn4wp3h02t7pZ:~# ls
dump.rdb
復(fù)制代碼果然也是正常生成的
持久化的觸發(fā)機(jī)制
按照 save 的規(guī)則滿足的情況下,就會(huì)觸發(fā)持久化,例如上述的 60s 操作 redis 3 次就會(huì)觸發(fā) 1 次持久化
執(zhí)行 flushall 命令的時(shí)候,也會(huì)觸發(fā)持久化,生成 dump.db 文件
退出 redis 的時(shí)候, 也會(huì)觸發(fā)持久化,生成 dump.db 文件
備份就會(huì)自動(dòng)生成一個(gè) dump.db 文件
如何恢復(fù)持久化文件
1、只需要將 dump.db 文件放到 redis 的啟動(dòng)目錄即可,redis 啟動(dòng)的時(shí)候會(huì)將該文件讀入到內(nèi)存中,進(jìn)行數(shù)據(jù)恢復(fù)
2、查看 redis 的啟動(dòng)目錄可以這樣做
127.0.0.1:6379> config get dir
1) "dir"
2) "/root"
復(fù)制代碼這一塊的配置,我們基本上不需要修改太多,默認(rèn)的配置基本就夠用了
RDB 的優(yōu)勢(shì)
適合大規(guī)模的數(shù)據(jù)恢復(fù)
對(duì)數(shù)據(jù)的完整性要求不高
RDB 的劣勢(shì)
需要在一定的時(shí)間間隔進(jìn)行操作,如果 redis 意外宕機(jī),最后一次寫(xiě)入的數(shù)據(jù)就會(huì)丟失
fork 子進(jìn)程的時(shí)候需要占用一定的空間
AOF 持久化方式
AOF 是什么?
將我們的寫(xiě)命令全部記錄下來(lái),恢復(fù)的時(shí)候,將文件中的記錄全部執(zhí)行一遍

AOF 是 redis 的另外一種持久化方式,以日志的形式記錄每一個(gè)寫(xiě)操作,將 redis 執(zhí)行過(guò)的寫(xiě)操作全部記錄下來(lái),只允許追加文件,不允許改寫(xiě)文件
redis 啟動(dòng)的時(shí)候就會(huì)讀取這個(gè) aof 文件重建數(shù)據(jù)庫(kù),也就是說(shuō),redis 重啟的時(shí)候,就會(huì)根據(jù)日志文件的內(nèi)容將寫(xiě)指令按照寫(xiě)入順序執(zhí)行,完成數(shù)據(jù)恢復(fù)
aof 保存的是 appendonly.aof 文件
# Please check https://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
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
復(fù)制代碼auto-aof-rewrite-min-size 64mb
當(dāng) aof 文件大于 64 mb 的時(shí)候,就會(huì)再創(chuàng)建一個(gè)子進(jìn)程來(lái)寫(xiě)一個(gè)新的 aof 文件

關(guān)于 aof 的配置基本上其他的都是使用默認(rèn)的配置即可,我們只需要把 aof 模式打開(kāi)即可
appendonly yes
復(fù)制代碼默認(rèn) appendonly 是不開(kāi)啟的,我們修改了配置之后,重啟 redis-server 就會(huì)馬上生效
重寫(xiě)規(guī)則說(shuō)明
aof 默認(rèn)是對(duì)文件無(wú)限追加,文件必然會(huì)越來(lái)越大

修改 redis.conf 為 aof 模式后,重啟 redis-server 可以看到 appendonly.aof 文件
redis 客戶端連接 server 進(jìn)行操作 redis ,簡(jiǎn)單的設(shè)置幾個(gè)值
root@iZuf66y3tuzn4wp3h02t7pZ:/# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set name xiaozhu
OK
127.0.0.1:6379> set age 19
OK
127.0.0.1:6379> set hobby play
OK
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> shutdown
not connected>
復(fù)制代碼查看 appendonly.aof 文件

appendonly.aof 文件里面存放的就是我們操作 redis 的寫(xiě)命令的記錄
這個(gè)時(shí)候,我們認(rèn)為的在 appendonly.aof 文件中修改一些值
set
$2
k2
$2
v2
*3
$3
set
$2
k3
$2
ashdkklasdjkkv3 # 修改了這一行
復(fù)制代碼
啟動(dòng) redis-server ,查看是否可以恢復(fù)數(shù)據(jù)
root@iZuf66y3tuzn4wp3h02t7pZ:/# redis-server /usr/local/redis/redis-6.2.5/redis.conf
root@iZuf66y3tuzn4wp3h02t7pZ:/# redis-cli
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected>
root@iZuf66y3tuzn4wp3h02t7pZ:/# ps axu |grep redis
root 1251 0.0 0.0 14436 1048 pts/0 S+ 14:55 0:00 grep --color=auto redis
root@iZuf66y3tuzn4wp3h02t7pZ:/#
復(fù)制代碼發(fā)現(xiàn) redis-server 啟動(dòng)失敗,是因?yàn)樵蹅兊?appendonly.aof 文件被人為的修改過(guò),此時(shí)咱們需要修復(fù)該文件,redis 有提供工具修改 aof 文件,redis-check-aof
使用指令:
redis-check-aof --fix appendonly.aof
# redis-check-aof --fix appendonly.aof
0x ce: Expected \r\n, got: 6864
AOF analyzed: size=223, ok_up_to=181, ok_up_to_line=47, diff=42
This will shrink the AOF from 223 bytes, with 42 bytes, to 181 bytes
Continue? [y/N]: y
Successfully truncated AOF
root@iZuf66y3tuzn4wp3h02t7pZ:/# redis-server /usr/local/redis/redis-6.2.5/redis.conf
root@iZuf66y3tuzn4wp3h02t7pZ:/# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> get k1
"v1"
復(fù)制代碼修復(fù) aof 文件后,咱們?cè)俅螁?dòng) redis-server 來(lái)回復(fù)磁盤(pán)數(shù)據(jù),恢復(fù)成功,nice
aof 的優(yōu)勢(shì)和劣勢(shì)
優(yōu)勢(shì)
每一次操作 reids 都會(huì)被記錄,文件的完整性好
每秒同步一次,可能會(huì)丟失一秒的數(shù)據(jù)
從不同步,這個(gè)效率是最高的
劣勢(shì)
相對(duì)于數(shù)據(jù)文件來(lái)說(shuō),aof 文件會(huì)遠(yuǎn)大于 rdb 文件,修復(fù)的速度也比 rdb 文件慢
aof 運(yùn)行的效率比 rdb 慢,所以 redis 默認(rèn)的配置是 rdb 持久化
小結(jié)
兩種持久化方式簡(jiǎn)述
RDB 持久化的方式能夠在指定的時(shí)間間隔內(nèi)對(duì)數(shù)據(jù)進(jìn)行快照存儲(chǔ)
AOF 持久化的方式記錄每次對(duì)服務(wù)器的寫(xiě)操作,當(dāng)服務(wù)器重啟或者宕機(jī)的時(shí)候,會(huì)重新執(zhí)行這些記錄里面的寫(xiě)操作命令來(lái)恢復(fù)數(shù)據(jù),AOF 命令以 redis 協(xié)議追加保存每次寫(xiě)操作到文件末尾,redis 還能對(duì) aof 文件進(jìn)行后臺(tái)重寫(xiě),是的 AOF 文件的體積不至于過(guò)大
如果需求是只做緩存,只期望服務(wù)器運(yùn)行的時(shí)候數(shù)據(jù)存在,那么不用做持久化
兩種持久化方式的開(kāi)和不開(kāi)
可以同時(shí)開(kāi)啟兩種持久化方式
redis 的作者建議是不要只使用 aof 文件,因?yàn)?rdb 更加適合用于備份數(shù)據(jù)庫(kù),因?yàn)?aof 在不斷的變化,不好備份,快速重啟的時(shí)候,rdb 不會(huì)有 aof 可能潛在的 bug,留著 rdb 做一個(gè)兜底的機(jī)制
這種情況下,redis 重啟會(huì)先載入 aof 文件來(lái)恢復(fù)數(shù)據(jù),因?yàn)橥ǔG闆r下 aof 文件保存的數(shù)據(jù)集比 rdb 的數(shù)據(jù)集要完整
rdb 數(shù)據(jù)集不是實(shí)時(shí)的,同時(shí)使用兩種方式時(shí),服務(wù)器重啟有只會(huì)找 aof 文件,那么要不要只使用 aof 文件呢?
性能上的建議
對(duì)于 rdb 持久化
由于 rdb 文件只用于備份數(shù)據(jù),建議只在 slave 上面持久化 rdb 文件,15 分鐘持久化一次就夠了,也就是這一條指令
save 900 1如果打開(kāi) aof 持久化,好處就是在極端情況下丟失數(shù)據(jù)也不會(huì)超過(guò) 2s 的數(shù)據(jù),啟動(dòng)腳本就簡(jiǎn)單的加載自己的 aof 文件即可,這樣做也是有代價(jià)的
代價(jià)之一就是 這樣做帶來(lái)了持續(xù)的 IO 操作
代價(jià)之二就是 AOF 重寫(xiě)的最后將重寫(xiě)過(guò)程產(chǎn)生新數(shù)據(jù)寫(xiě)入到新文件造成的阻塞是不可避免的,只要硬盤(pán)許可,應(yīng)該要盡量的減少 aof 重寫(xiě)的頻率
對(duì)于 aof 持久化
aof 重寫(xiě)的基礎(chǔ)大小值是 64 mb,我們可以設(shè)置成 5g 以上,默認(rèn)超過(guò)原大小 100% 大小重寫(xiě),這個(gè)參數(shù)可以設(shè)置成一個(gè)合理的參數(shù)
如果不打開(kāi) aof 模式,僅僅靠主從復(fù)制實(shí)現(xiàn)高可用也是可以的,能夠省掉一大筆 IO 消耗,也減少了重寫(xiě)帶來(lái)系統(tǒng)的性能波動(dòng),這樣做仍然是有代價(jià)的
代價(jià)之一就是 如果主備 redis 同時(shí)掛掉(例如斷電),會(huì)丟失十幾分鐘的數(shù)據(jù),啟動(dòng)腳本也要比較主備的 rdb 文件,載入較新的那個(gè) rdb 文件
參考資料:
redis_doc
歡迎點(diǎn)贊,關(guān)注,收藏
朋友們,你的支持和鼓勵(lì),是我堅(jiān)持分享,提高質(zhì)量的動(dòng)力
作者:小魔童哪吒
鏈接:https://juejin.cn/post/6999477345362903047
來(lái)源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
