Redis持久化機制

DiligentCoder發表於2023-01-13

全量同步與增量同步的區別

全量同步:就是每天定時(避開高峰期)或者採用一個週期實現將資料複製到一個地方也就是Rdb儲存。
增量同步:比如採用對行為的操作實現對資料的同步,也就是AOF。
全量與增量的比較:增量同步比全量同步更加消耗伺服器的記憶體,但是能夠更加的保證資料的同步。

RDB與AOF實現持久化的區別

Redis提供了兩種持久化的機制,分別為RDB、AOF實現,RDB採用定時(全量)持久化機制,但是伺服器因為某種原因當機後可能資料會丟失,AOF是基於資料操作日誌實現的持久化,所以AOF採用增量同步的方案。
Redis已經幫助我預設開啟了rdb儲存。

Redis的RDB與AOF同步配置

RDB

Redis預設採用rdb方式實現資料的持久化,以快照的形式將資料持久化到磁碟的是一個二進位制的檔案dump.rdb, 在redis.conf檔案中搜尋"dump.rdb"。
Redis會將資料集的快照dump到dump.rdb檔案中。此外,我們也可以透過配置檔案來修改Redis伺服器dump快照的頻率,在開啟6379.conf檔案之後,我們搜尋save,可以看到下面的配置資訊:
Redis持久化機制
save 900 1 #在900秒(15分鐘)之後,如果至少有1個key發生變化,則dump記憶體快照。
save 300 10 #在300秒(5分鐘)之後,如果至少有10個key發生變化,則dump記憶體快照。
save 60 10000 #在60秒(1分鐘)之後,如果至少有10000個key發生變化,則dump記憶體快照。
Set(包含增加和覆蓋)、del
Set name yushengjun
Set name mayikt
Del name
這個操作也被稱之為snapshotting,快照也可以手動呼叫save或者bgsave命令,同步或非同步執行rdb快照生成,
save可以設定多個,就是多個snapshotting檢查點,每到一個檢查點,就會去check一下,是否有指定的key數量發生了變更,如果有,就生成一個新的dump.rdb檔案。

RDB持久化機制的工作流程

(1)redis根據配置自己嘗試去生成rdb快照檔案
(2)fork一個子程式出來
(3)子程式嘗試將資料dump到臨時的rdb快照檔案中
(4)完成rdb快照檔案的生成之後,就替換之前的舊的快照檔案(dump.rdb,每次生成一個新的快照,都會覆蓋之前的老快照)
Redis持久化機制

AOF

Aof是以執行命令的形式實現同步,在Redis的配置檔案中存在三種同步方式,它們分別是:
appendfsync always #每次有資料修改發生時都會寫入AOF檔案,能夠保證資料不丟失,但是效率非常低。
appendfsync everysec #每秒鐘同步一次,可能會丟失1s內的資料,但是效率非常高。
appendfsync no #從不同步。高效但是資料不會被持久化。
直接修改redis.conf中 appendonly yes
建議最好還是使用everysec 既能夠保證資料的同步、效率也還可以。
aof檔名預設為 appendonly.aof,可以透過配置 appendfilename修改

AOF持久化機制的工作流程

Redis持久化機制

AOF重寫/壓縮機制

redis中的資料其實有限的,很多資料可能會自動過期,可能會被使用者刪除,可能會被redis用快取清除的演演算法清理掉
redis中的資料會不斷淘汰掉舊的,就一部分常用的資料會被自動保留在redis記憶體中
所以可能很多之前的已經被清理掉的資料,對應的寫日誌還停留在AOF中,AOF日誌檔案就一個,會不斷的膨脹,到很大很大
所以AOF會自動在後臺每隔一定時間做rewrite操作,比如日誌裡已經存放了針對100w資料的寫日誌了; redis記憶體只剩下10萬; 基於記憶體中當前的10萬資料構建一套最新的日誌,到AOF中; 覆蓋之前的老日誌; 確保AOF日誌檔案不會過大,保持跟redis記憶體資料量一致
從命令角度看,會盡量減少操作命令的資料,比如把原有的多條命令操作轉成一條
redis 2.4之前,還需要手動,開發一些指令碼,crontab,透過BGREWRITEAOF命令去執行AOF rewrite,但是redis 2.4之後,會自動進行rewrite操作
在redis.conf中,可以配置rewrite策略
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
比如說上一次AOF rewrite之後,是128mb
然後就會接著128mb繼續寫AOF的日誌,如果發現增長的比例,超過了之前的100%,256mb,就可能會去觸發一次rewrite
但是此時還要去跟min-size,64mb去比較,256mb > 64mb,才會去觸發rewrite
(1)redis fork一個子程式
(2)子程式基於當前記憶體中的資料,構建日誌,開始往一個新的臨時的AOF檔案中寫入日誌
(3)redis主程式,接收到client新的寫操作之後,在記憶體中寫入日誌,同時新的日誌也繼續寫入舊的AOF檔案
(4)子程式寫完新的日誌檔案之後,redis主程式將記憶體中的新日誌再次追加到新的AOF檔案中
(5)用新的日誌檔案替換掉舊的日誌檔案

AOF和RDB同時工作

(1)如果RDB在執行snapshotting操作,那麼redis不會執行AOF rewrite; 如果redis再執行AOF rewrite,那麼就不會執行RDB snapshotting
(2)如果RDB在執行snapshotting,此時使用者執行BGREWRITEAOF命令,那麼等RDB快照生成之後,才會去執行AOF rewrite
(3)同時有RDB snapshot檔案和AOF日誌檔案,那麼redis重啟的時候,會優先使用AOF進行資料恢復,因為其中的日誌更完整

MySQL與Redis一致性解決同步問題

方式1:直接清除Redis的快取,重新讀取資料庫即可
方式2:使用mq非同步訂閱mysql binlog實現增量同步
方式3:使用alibaba的canal

本文參考來源:
螞蟻課堂
https://blog.csdn.net/fengyuyeguirenenen/article/details/124601825
https://baijiahao.baidu.com/s?id=1703595719672597505&wfr=spider&for=pc

相關文章