文章目錄
- 9.一篇文章看懂Redis持久化機制
- 9.1Redis的兩種持久化機制
- 9.1.1為什么有持久化?
- 9.2RDB機制
- 9.2.1介紹
- 9.2.2觸發機制
- (1)save命令觸發
- (2)bgsave命令觸發
- (3)自動觸發
- 9.2.3執行流程
- 9.2.4優點
- 9.2.5缺點
- 9.3AOF機制
- 9.3.1介紹
- 9.3.2rewrite機制
- 9.3.3觸發機制
- 9.3.4優點
- 9.3.5缺點
- 9.4Redis4.0的混合持久化
- 9.5RDB與AOF對比
9.一篇文章看懂Redis持久化機制
9.1Redis的兩種持久化機制
9.1.1為什么有持久化?
由于Redis的數據都存放在內存中,如果沒有配置持久化,redis重啟后數據就全丟失了,于是需要開啟redis的持久化功能,將數據保存到磁盤上,當redis重啟后,可以從磁盤中恢復數據。
Redis提供兩種持久化方式,RDB(Redis DataBase縮寫快照)和AOF(Append Only File);
第一種是RDB快照,第二種是AOF日志。
-
RDB:
- RDB快照是一次全量備份
- 快照是內存數據的二進制序列化形式,在存儲上非常緊湊
-
AOF:
- AOF是連續的增量備份。
- AOF 日志記錄的是內存數據修改的指令記錄文本。
9.2RDB機制
9.2.1介紹
- RDB快照就是把數據以快照的形式保存在磁盤上,是某個時間點的一次全量數據備份,以二進制序列化形式的文件存儲,并且在存儲上非常緊密。
- RDB持久化是指在指定的時間間隔內將內存中的數據集以快照的方式寫入磁盤,并保存到一個名為dump.rdb的二進制文件中,也是默認的持久化方式,它恢復時是將快照文件從磁盤直接讀到內存里。
9.2.2觸發機制
RDB來說持久化觸發機制有三種:save、bgsave、自動化觸發
(1)save命令觸發
該命令會阻塞當前Redis服務器,執行save命令期間,Redis不能處理其他命令,直到RDB完成為止,如果數據量大的話會造成長時間的阻塞,所以線上環境一般禁止使用。
執行該命令時,Redis會在后臺異步進行快照操作,快照同時還可以響應客戶端請求。具體流程如下:
(2)bgsave命令觸發
執行bgsave命令時,Redis主進程會fork一個子進程來完成RDB的過程,會先將數據寫入到一個臨時二進制文件中,待持久化過程都結束了,再用這個臨時文件替換上次持久化好的文件(可以理解為Copy On Write機制)。Redis主進程阻塞時間只有fork階段的那一下。相對于save,阻塞時間很短。基本上 Redis 內部所有的RDB操作都是采用 bgsave 命令。
ps: fork的作用是復制一個與當前進程一樣的進程。新進程的所有數據(變量、環境變量、程序計數器等)數值都和原進程一致,但是是一個全新的進程,并作為原進程的子進程。
(3)自動觸發
自動觸發是可以在redis.conf配置文件中修改,默認達到 以下三種條件,就會自動觸發持久化,觸發后,底層調用的其實還有bgsave命令:
舉例:1分鐘內改了1萬次,5分鐘內改了10次,或15分鐘內改了1次。
- save 900 1 #在900秒(15分鐘)之后,如果至少有1個key發生變化,則dump內存快照。
- save 300 10 #在300秒(5分鐘)之后,如果至少有10個key發生變化,則dump內存快照。
- save 60 10000 #在60秒(1分鐘)之后,如果至少有10000個key發生變化,則dump內存快照。
如果不需要持久化機制,則可以注釋掉所有的save命令
9.2.3執行流程
- 執行bgsave命令的時候,Redis主進程會檢查是否有子進程在執行RDB/AOF持久化任務,如果有的話,直接返回,主要是為了性能的考慮,防止兩個進程同時對磁盤進行寫入操作
- Redis主進程fork一個子進程來執行執行RDB操作,fork操作會對主進程造成阻塞(影響Redis的讀寫),fork操作完成后會發消息給主進程,從而不再阻塞主進程(阻塞僅指主進程fork子進程的過程,后續子進程執行操作時不會阻塞)
- RDB子進程把Redis主進程的內存數據,寫入到一個臨時的快照文件,持久化完成后,再使用臨時快照文件替換掉原來的RDB文件。(該過程中主進程的讀寫不受影響,但Redis的寫操作不會同步到主進程的主內存中,而是會寫到一個臨時的內存區域作為一個副本)
- 子進程完成RDB持久化后會發消息給主進程,通知RDB持久化完成,并將步驟3中的內存副本中的增量寫數據同步到主內存
9.2.4優點
-
RDB文件緊湊,全量備份,非常 適合用于進行備份和災難恢復。
-
對于大規模數據的恢復,且對于數據恢復的完整性不是非常敏感的場景,RDB的恢復速度要比AOF方式更加的高效。
-
生成RDB文件的時候,redis主進程會fork()一個子進程來處理所有保存工作,主進程不需要進行任何磁盤IO操作。
9.2.5缺點
- fork的時候,內存中的數據被克隆了一份,大致2倍的膨脹性需要考慮。
- 當進行快照持久化時,會開啟一個子進程專門負責快照持久化,子進程會擁有父進程的內存數據,父進程修改內存子進程不會反應出來,所以在快照持久化期間修改的數據不會被保存,可能丟失數據。
- 在一定間隔時間做一次備份,所以如果redis意外down掉的話,就會丟失最后一次快照后的所有修改。
9.3AOF機制
9.3.1介紹
每次都使用RDB機制全量備份的方式是非常耗時間的,因此Redis還提供了另一種持久化機制 AOF(append only file)。AOF日志是持續增量的備份,將Redis執行過的每個 寫操作以日志的形式記錄下來 (讀操作不記錄),只許追加文件但不可以改寫文件(appendonly.aof文件)。
redis啟動的時候會讀取該文件進行數據恢復,根據日志文件的內容將寫指令從前到后執行一次以完成數據的恢復工作。
9.3.2rewrite機制
- 因為AOF采用文件追加方式,文件會越來越大,為避免出現此種情況,需要 定期進行AOF重寫,當AOF文件的大小超過所設定的閾值時,Redis就會對AOF文件的內容壓縮,只保留可以恢復數據的最小指令集。redis提供了bgrewriteaof命令,fork一個新的進程對aof文件進行重寫。
- 重寫原理:AOF文件持續增長而過大時,會fork出一條新進程來重寫aof文件,將內存中的整個數據庫內容用命令的方式重寫了一個新的aof文件(注意:在重寫時并不是讀取舊的aof文件),在執行 BGREWRITEAOF 命令時,Redis 服務器會維護一個 AOF 重寫緩沖區,該緩沖區會在子進程創建新AOF文件期間,記錄服務器執行的所有寫命令。當子進程完成創建新AOF文件的工作之后,服務器會將重寫緩沖區中的所有內容追加到新AOF文件的末尾,使得新舊兩個AOF文件所保存的數據庫狀態一致。最后,服務器用新的AOF文件替換舊的AOF文件,以此來完成AOF文件重寫操作。
- 觸發時機:Redis會記錄上次重寫時的AOF大小,默認配置是當AOF文件大小是上次rewrite后大小的一倍且文件大于64M時觸發。
9.3.3觸發機制
- 每修改同步:appendfsync always 同步持久化,每次發生數據變更會被立即記錄到磁盤,性能較差但數據完整性比較好。
- 每秒同步:appendfsync everysec 異步操作,每秒記錄,如果一秒內宕機,有數據丟失。
- 不同步:appendfsync no 從不同步
9.3.4優點
- 數據安全,AOF持久化可以配置 appendfsync 屬性,有always屬性,每進行一次命令操作就記錄到AOF文件中一次;
- 通過append模式寫文件,即使中途服務器宕機 ,可以通過 redis-check-aof 工具解決數據一致性問題;
- AOF機制的rewrite模式。AOF文件沒被 rewrite 之前(文件過大時會對命令 進行合并重寫),可以刪除其中的某些命令(比如誤操作的 flushall);
9.3.5缺點
- AOF文件比RDB文件大,且恢復速度慢;
- 數據集大的時候,比RDB啟動效率低;
注:如果同時開啟兩種持久化方式,在這種情況下,當redis重啟的時候會優先載入AOF文件來恢復原始的數據,因為在通常情況下AOF文件保存的數據集要比RDB文件保存的數據集要完整。
9.4Redis4.0的混合持久化
- 僅使用 RDB快照方式恢復數據,由于快照時間粒度較大時,會丟失大量數據。
- 僅使用 AOF重放方式 恢復數據,日志性能相對 rdb 來說要慢。在 Redis 實例很大的情況下,啟動需要花費很長的時間。
為了解決這個問題,Redis4.0開始支持RDB和AOF的混合持久化(默認關閉,可以通過配置項 aof-use-rdb-preamble 開啟)。RDB 文件的內容和增量的 AOF 日志文件存在一起,這里的 AOF 日志不再是全量的日志,而是自持久化開始到持久化結束的這段時間發生的增量 AOF 日志,通常這部分 AOF 日志很小
- 大量數據使用粗粒度(時間上)的rdb快照方式,性能高,恢復時間快。
- 增量數據使用細粒度(時間上)的AOF日志方式,盡量保證數據的不丟失。
在Redis重啟時,進行AOF重寫的時候就直接把RDB的內容寫到 AOF 文件開頭。這樣做的好處是可以結合 RDB和 AOF 的優點,快速加載同時避免丟失過多的數據。當然缺點也是有的, AOF 里面的 RDB 部分是壓縮格式不再是AOF 格式,可讀性較差。
另外,可以使用下面這種方式:Master使用AOF,Slave使用RDB快照,master需要首先確保數據完整性,它作為數據備份的第一選擇;slave提供只讀服務或僅作為備機,它的主要目的就是快速響應客戶端read請求或災切換。
9.5RDB與AOF對比
- AOF文件比RDB更新頻率高,優先使用AOF還原數據;
- AOF比RDB更安全也更大;
- RDB性能比AOF好;
- 如果兩個都配了優先加載AOF;