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

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

我們設(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ī)則滿足的情況下,就會觸發(fā)持久化,例如上述的 60s 操作 redis 3 次就會觸發(fā) 1 次持久化
執(zhí)行 flushall 命令的時(shí)候,也會觸發(fā)持久化,生成 dump.db 文件
退出 redis 的時(shí)候, 也會觸發(fā)持久化,生成 dump.db 文件
備份就會自動生成一個(gè) dump.db 文件
如何恢復(fù)持久化文件
1、只需要將 dump.db 文件放到 redis 的啟動目錄即可,redis 啟動的時(shí)候會將該文件讀入到內(nèi)存中,進(jìn)行數(shù)據(jù)恢復(fù)
2、查看 redis 的啟動目錄可以這樣做
127.0.0.1:6379> config get dir
1) "dir"
2) "/root"
復(fù)制代碼這一塊的配置,我們基本上不需要修改太多,默認(rèn)的配置基本就夠用了
RDB 的優(yōu)勢
適合大規(guī)模的數(shù)據(jù)恢復(fù)
對數(shù)據(jù)的完整性要求不高
RDB 的劣勢
需要在一定的時(shí)間間隔進(jìn)行操作,如果 redis 意外宕機(jī),最后一次寫入的數(shù)據(jù)就會丟失
fork 子進(jìn)程的時(shí)候需要占用一定的空間
AOF 持久化方式
AOF 是什么?
將我們的寫命令全部記錄下來,恢復(fù)的時(shí)候,將文件中的記錄全部執(zhí)行一遍

AOF 是 redis 的另外一種持久化方式,以日志的形式記錄每一個(gè)寫操作,將 redis 執(zhí)行過的寫操作全部記錄下來,只允許追加文件,不允許改寫文件
redis 啟動的時(shí)候就會讀取這個(gè) aof 文件重建數(shù)據(jù)庫,也就是說,redis 重啟的時(shí)候,就會根據(jù)日志文件的內(nèi)容將寫指令按照寫入順序執(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í)候,就會再創(chuàng)建一個(gè)子進(jìn)程來寫一個(gè)新的 aof 文件

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

修改 redis.conf 為 aof 模式后,重啟 redis-server 可以看到 appendonly.aof 文件
redis 客戶端連接 server 進(jìn)行操作 redis ,簡單的設(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 的寫命令的記錄
這個(gè)時(shí)候,我們認(rèn)為的在 appendonly.aof 文件中修改一些值
set
$2
k2
$2
v2
*3
$3
set
$2
k3
$2
ashdkklasdjkkv3 # 修改了這一行
復(fù)制代碼
啟動 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 啟動失敗,是因?yàn)樵蹅兊?appendonly.aof 文件被人為的修改過,此時(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 文件后,咱們再次啟動 redis-server 來回復(fù)磁盤數(shù)據(jù),恢復(fù)成功,nice
aof 的優(yōu)勢和劣勢
優(yōu)勢
每一次操作 reids 都會被記錄,文件的完整性好
每秒同步一次,可能會丟失一秒的數(shù)據(jù)
從不同步,這個(gè)效率是最高的
劣勢
相對于數(shù)據(jù)文件來說,aof 文件會遠(yuǎn)大于 rdb 文件,修復(fù)的速度也比 rdb 文件慢
aof 運(yùn)行的效率比 rdb 慢,所以 redis 默認(rèn)的配置是 rdb 持久化
小結(jié)
兩種持久化方式簡述
RDB 持久化的方式能夠在指定的時(shí)間間隔內(nèi)對數(shù)據(jù)進(jìn)行快照存儲
AOF 持久化的方式記錄每次對服務(wù)器的寫操作,當(dāng)服務(wù)器重啟或者宕機(jī)的時(shí)候,會重新執(zhí)行這些記錄里面的寫操作命令來恢復(fù)數(shù)據(jù),AOF 命令以 redis 協(xié)議追加保存每次寫操作到文件末尾,redis 還能對 aof 文件進(jìn)行后臺重寫,是的 AOF 文件的體積不至于過大
如果需求是只做緩存,只期望服務(wù)器運(yùn)行的時(shí)候數(shù)據(jù)存在,那么不用做持久化
兩種持久化方式的開和不開
可以同時(shí)開啟兩種持久化方式
redis 的作者建議是不要只使用 aof 文件,因?yàn)?rdb 更加適合用于備份數(shù)據(jù)庫,因?yàn)?aof 在不斷的變化,不好備份,快速重啟的時(shí)候,rdb 不會有 aof 可能潛在的 bug,留著 rdb 做一個(gè)兜底的機(jī)制
這種情況下,redis 重啟會先載入 aof 文件來恢復(fù)數(shù)據(jù),因?yàn)橥ǔG闆r下 aof 文件保存的數(shù)據(jù)集比 rdb 的數(shù)據(jù)集要完整
rdb 數(shù)據(jù)集不是實(shí)時(shí)的,同時(shí)使用兩種方式時(shí),服務(wù)器重啟有只會找 aof 文件,那么要不要只使用 aof 文件呢?
性能上的建議
對于 rdb 持久化
由于 rdb 文件只用于備份數(shù)據(jù),建議只在 slave 上面持久化 rdb 文件,15 分鐘持久化一次就夠了,也就是這一條指令
save 900 1如果打開 aof 持久化,好處就是在極端情況下丟失數(shù)據(jù)也不會超過 2s 的數(shù)據(jù),啟動腳本就簡單的加載自己的 aof 文件即可,這樣做也是有代價(jià)的
代價(jià)之一就是 這樣做帶來了持續(xù)的 IO 操作
代價(jià)之二就是 AOF 重寫的最后將重寫過程產(chǎn)生新數(shù)據(jù)寫入到新文件造成的阻塞是不可避免的,只要硬盤許可,應(yīng)該要盡量的減少 aof 重寫的頻率
對于 aof 持久化
aof 重寫的基礎(chǔ)大小值是 64 mb,我們可以設(shè)置成 5g 以上,默認(rèn)超過原大小 100% 大小重寫,這個(gè)參數(shù)可以設(shè)置成一個(gè)合理的參數(shù)
如果不打開 aof 模式,僅僅靠主從復(fù)制實(shí)現(xiàn)高可用也是可以的,能夠省掉一大筆 IO 消耗,也減少了重寫帶來系統(tǒng)的性能波動,這樣做仍然是有代價(jià)的
代價(jià)之一就是 如果主備 redis 同時(shí)掛掉(例如斷電),會丟失十幾分鐘的數(shù)據(jù),啟動腳本也要比較主備的 rdb 文件,載入較新的那個(gè) rdb 文件
參考資料:
redis_doc
歡迎點(diǎn)贊,關(guān)注,收藏
朋友們,你的支持和鼓勵,是我堅(jiān)持分享,提高質(zhì)量的動力
作者:小魔童哪吒
鏈接:https://juejin.cn/post/6999477345362903047
來源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
