Redis持久化

Redis持久化有兩種方式:RDB和AOF

一般是兩種方式搭配使用,同時開啟,這時候Redis重新啟動會使用AOF文件來恢復內存中的數據,然后如果我們需要備份Redis數據的話則將dump.rdb文件備份即可。

RDB快照方式持久化

dump.rdb是二進制的壓縮文件,里邊是全量快照數據,用來做備份恢復比較方便。Redis進行RDB持久化的時候會先生成臨時文件,生成完成之后一次性替換dump.rdb文件,所以dump.rdb文件都是完整的。

RDB快照生成時機:

(1)、SAVE和BGSAVE 一般是用后者異步的做快照,不阻塞其他命令,使用LASTSAVE可以看最近一次成功執(zhí)行快照的時間。(返回的是一個UNIX時間戳 ,1641258757 -> 2022-01-04 09:12:37)

127.0.0.1:7001> lastsave
(integer) 1638239440
127.0.0.1:7001> bgsave
Background saving started
127.0.0.1:7001> lastsave
(integer) 1641258757

(2)、根據配置定時進行快照,redis.conf文件里有默認配置

#900秒內如果有1個key發(fā)生了修改,則執(zhí)行一次快照
save 900 1
#300秒內如果有10個key發(fā)生了修改,則執(zhí)行一次快照
save 300 10
#60秒內如果有10000個key發(fā)生了修改,則執(zhí)行一次快照
save 60 10000

(3)、FLUSHALL時,執(zhí)行這個命令會清除內存數據庫中的所有數據,需要注意。

(4)、主從復制時 ,以RDB快照的方式將數據同步到從庫。

rdbcompression參數可以用來控制是否壓縮二進制dump.rdb文件,壓縮的話文件小,傳輸和寫盤快,不壓縮則節(jié)省CPU資源,可以根據需求自己取舍。在redis.conf文件里配置,默認是壓縮的:

rdbcompression yes

RDB快照的時候,Redis會從主進程fork出來子進程來負責快照持久化,fork是內核操作、使用了所謂CopyOnWrite技術:

1、 fork開始時,內存就是readonly的了,子進程復制讀的是fork時刻的快照數據。

2、 主進程如果有寫入會復制一份該修改到的內存頁、新內存頁是可讀寫的、原內存頁仍然readonly給子進程用、然后將指針指向新的這個內存頁。這樣主進程只修改的這一部分后面讀寫會到新內存頁、其他還是會到原內存頁的,而子進程持久化一直是用的原內存頁,兩者同時進行互相不阻塞。且內存使用上也不會是把主進程的內存復制了一模一樣大小的兩份,寫操作少的話,復制的內存頁只占很少一部分。

但如果RDB快照期間寫操作比較多、剩余可用內存又比較少,可能會出現Redis數據庫內存 + 寫復制使用的內存大于系統(tǒng)內存的情況,需要修改Linux系統(tǒng)參數使應用程序可以申請超過可用內存大小的空間:

修改/etc/sysctl.conf:

vm.overcommit_memory = 1

然后執(zhí)行sysctl vm.overcommit_memory = 1確保馬上生效。

overcommit_memory這個參數是應用程序可以向系統(tǒng)申請超過實際可用大小的內存空間,注意只是申請或系統(tǒng)承諾,但并不是馬上就真的分配了這么多內存頁。一般來說保守的策略是不開啟這個參數的。

AOF命令追加方式持久化

RDB方式會丟失最后一次快照之后的數據,如果用Redis做臨時熱點數據的緩存,那問題不大,如果是不能容忍丟失的交易數據,那要配合AOF方式使用。

開啟AOF方式:

appendonly yes

1、AOF——增量命令appendonly和命令重寫

AOF方式會每秒將使得Redis數據修改的命令(更準確說是發(fā)送給Redis Server的通信協(xié)議內容)寫入到appendonly.aof文件里,Redis會定期對寫入命令進行重寫,重寫后的aof文件邏輯上來說跟之前一樣但命令更少,比如執(zhí)行了3個SET key value,那其實只保留最后一個就可以了。

#aof文件超過上一次重寫時的百分之多少則進行重寫
auto-aof-rewrite-percentage 100
#最小要達到多少大小才重寫
auto-aof-rewrite-min-size 64mb

也可以手工觸發(fā)aof重寫,BGREWRITEAOF命令。

2、aof刷盤時機

Redis寫aof文件的時候實際上也是先寫系統(tǒng)磁盤緩沖的,可以根據情況來指定刷盤的時機。

#appendfsync always
appendfsync everysec
#appendfsync no

always是每次寫都同步刷盤,everysec是異步寫磁盤緩沖、1秒刷盤一次,no的話就是Redis自己不主動刷盤、把刷盤控制權交給操作系統(tǒng),Linux默認是30秒一次。所以綜合性能和數據安全性,用everysec就可以了。

參考:

《Redis入門指南(第2版)》

Redis-關于RDB的幾點頓悟-COW(Copy On Write)_Muscleape的博客-CSDN博客_redis的cow

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容