Redis 提供了兩種主要的持久化機制,用于將內存中的數據保存到磁盤,以防止服務器重啟或故障導致數據丟失。這兩種機制分別是 RDB(Redis Database)和 AOF(Append Only File)。
1. RDB 持久化
RDB 是 Redis 默認的持久化方式,它通過創建內存中數據的快照來實現持久化。
2.RDB 持久化的觸發方式
1. 自動觸發(配置文件方式)
這是最常用的方式,通過在 Redis 配置文件(redis.conf
)中設置觸發條件,當滿足條件時自動執行 RDB 持久化。
配置格式:
save <seconds> <changes>
表示在?seconds
?秒內發生了至少?changes
?次數據修改時,觸發 RDB 快照。
默認配置:
save 900 1 # 900秒內有至少1個鍵被修改
save 300 10 # 300秒內有至少10個鍵被修改
save 60 10000 # 60秒內有至少10000個鍵被修改
2. 手動觸發
可以通過 Redis 命令手動觸發 RDB 持久化:
SAVE
?命令:
執行該命令時,Redis 主進程會直接進行 RDB 持久化操作,期間會阻塞所有客戶端請求,直到 RDB 完成。127.0.0.1:6379> SAVE OK
適合在低峰期或維護時使用。
BGSAVE
?命令:
執行該命令時,Redis 會 fork 一個子進程來進行 RDB 持久化,主進程繼續處理客戶端請求,不會阻塞服務。127.0.0.1:6379> BGSAVE Background saving started
這是更常用的手動觸發方式。
注意:
執行flushall也會清空rdb文件
1.fork
在 Redis 中,
fork
?是一個非常關鍵的系統調用(由操作系統提供),用于創建一個與當前進程(父進程)幾乎完全相同的新進程(子進程)。當 Redis 執行?
BGSAVE
?命令時,會通過?fork
?操作創建一個子進程,這個子進程會復制父進程的內存數據,然后負責將數據寫入 RDB 文件。
fork
?的特點:
內存共享機制:
- 在 Linux 系統中,
fork
?采用?寫時復制(Copy-On-Write)?技術,初始時子進程并不會真正復制父進程的全部內存數據,而是共享同一塊內存。- 只有當父進程或子進程修改數據時,才會復制被修改的部分數據,這樣可以大大節省內存和提高效率。
對 Redis 的意義:
- 主進程(父進程)可以繼續處理客戶端請求,不會被阻塞。
- 子進程專注于將數據寫入磁盤生成 RDB 文件,完成后會自動退出。
可能的影響:
fork
?操作本身會短暫阻塞主進程(阻塞時間與內存大小相關)。- 如果數據集非常大,
fork
?可能會導致 Redis 出現短暫的響應延遲。簡單來說,
fork
?讓 Redis 能夠在不中斷服務的情況下完成 RDB 持久化,是實現后臺異步操作的核心機制。
2.寫時拷貝
寫時拷貝的核心原理:
當一個進程(父進程)通過?
fork
?創建新進程(子進程)時,不會立即復制父進程的全部內存數據,而是讓父子進程共享同一塊內存空間。只有當其中一方(父進程或子進程)修改數據時,才會復制被修改的那部分內存頁,確保雙方的數據獨立性。
3.rdb文件
redis的工作目錄
后續redis服務器重新啟動,就會嘗試加載這個rdb文件,如果發現格式錯誤,就可能會加載數據失敗,rdb文件雖然咱們不去主動動他,但是也可能會出現一些意外問題,一旦通過一些操作(比如網絡傳輸)引起這個文件被破壞,此時redis服務器就無法啟動
redis官方提供了rdb文件檢查工具
注意:
如果redis異常退出(如服務器崩潰,kill-9),此時redis服務器來不及生成rdb,內存中尚未保存到快照中的數據,就會隨重啟而丟失
當rdb文件錯誤時,啟動redis加上rdb文件來預警
3. 其他觸發場景
服務器關閉時:當執行?
SHUTDOWN
?命令關閉 Redis 服務器時,Redis 會自動執行一次?SAVE
?命令,生成 RDB 文件后再關閉,確保數據不丟失。主從復制時:當從節點連接主節點時,主節點會自動執行一次?
BGSAVE
?生成 RDB 文件,并發送給從節點,用于數據同步。
工作原理:
- Redis 在指定的時間間隔內,將內存中的數據集快照寫入磁盤的二進制文件(默認文件名是?
dump.rdb
) - 當 Redis 重啟時,會讀取這個文件恢復數據
配置方式(在 redis.conf 中):
# 900秒內有至少1個鍵被修改,則觸發快照
save 900 1
# 300秒內有至少10個鍵被修改,則觸發快照
save 300 10
# 60秒內有至少10000個鍵被修改,則觸發快照
save 60 10000
#關閉自動生成快照
save ""
優點:
- 生成的 RDB 文件是緊湊的二進制文件,適合用于備份和災難恢復
- 恢復大數據集時速度比 AOF 快
- 對 Redis 性能影響較小,因為 fork 子進程進行持久化操作
缺點:
- 可能會丟失最后一次快照之后的數據
- 如果數據集很大,fork 過程可能會阻塞 Redis 服務器一段時間
3. AOF 持久化
AOF 持久化記錄服務器執行的所有寫操作命令,并在服務器啟動時,通過重新執行這些命令來恢復數據。
工作原理:
- 每當執行一個改變數據集的命令時,Redis 就會將該命令追加到 AOF 文件的末尾
- 當 Redis 重啟時,會重新執行 AOF 文件中的所有命令以恢復數據
配置方式(在 redis.conf 中):
# 開啟 AOF 持久化
appendonly yes
# AOF 文件名
appendfilename "appendonly.aof"# AOF 同步策略
# appendfsync always # 每次有寫操作就立即同步到磁盤,最慢但最安全
appendfsync everysec # 每秒同步一次,平衡性能和安全性(默認)
# appendfsync no # 由操作系統決定何時同步,最快但最不安全
AOF是否會影響redis性能
AOF緩沖區刷新策略
1. always(每寫命令都同步)
- 策略描述:每當有新的寫命令追加到 AOF 文件時,Redis 就會立即調用系統的?
fsync
?函數,將 AOF 緩沖區中的數據強制寫入磁盤 。- 優點:數據安全性最高,因為一旦寫入成功,數據就已經持久化到磁盤,即使發生系統崩潰、斷電等異常情況,最多只會丟失剛剛執行但還沒來得及寫入 AOF 文件的那一個寫命令的數據。
- 缺點:性能開銷較大,頻繁的磁盤 I/O 操作會降低 Redis 的寫入性能,因為每次寫操作都需要等待磁盤寫入完成。
2. everysec(每秒同步)
- 策略描述:Redis 會每秒調用一次?
fsync
?函數,將 AOF 緩沖區中的數據寫入磁盤。- 優點:兼顧了數據安全性和性能。在大多數情況下,即使發生系統崩潰,最多只會丟失 1 秒內的數據 ,同時又避免了過于頻繁的磁盤 I/O 操作,對 Redis 的性能影響相對較小。
- 缺點:在極端情況下,比如系統崩潰時剛好距離上次?
fsync
?超過 1 秒,可能會丟失這 1 秒內的寫命令數據。3. no(由操作系統決定同步時機)
- 策略描述:Redis 不主動調用?
fsync
?函數,而是將數據寫入 AOF 緩沖區后,由操作系統來決定何時將緩沖區的數據真正寫入磁盤。- 優點:對 Redis 性能影響最小,因為減少了 Redis 對磁盤 I/O 操作的干預,寫操作只是簡單地追加到緩沖區,不需要等待磁盤寫入。
- 缺點:數據安全性最低,因為數據停留在緩沖區的時間不確定,一旦系統崩潰,緩沖區中未寫入磁盤的數據都會丟失,可能會丟失大量數據。
在實際應用中,
everysec
?是最常用的 AOF 刷新策略,它在數據安全性和性能之間找到了一個較好的平衡點。 可以在 Redis 的配置文件(redis.conf
)中通過?appendfsync
?配置項來設置 AOF 刷新策略,例如:plaintext
appendfsync always # 或者 appendfsync everysec # 或者 appendfsync no
也可以在 Redis 運行時,通過?
CONFIG SET appendfsync <策略值>
?命令動態修改 AOF 刷新策略。
AOF重寫機制
AOF(Append Only File)重寫機制是 Redis 中用于優化 AOF 文件大小的一種重要機制。隨著 Redis 不斷執行寫命令并將其追加到 AOF 文件中,AOF 文件會越來越大,不僅占用過多磁盤空間,還會導致 Redis 在重啟時,重放 AOF 文件中的命令耗時過長,影響恢復速度 。AOF 重寫機制主要做了以下幾件事:
1. 原理
AOF 重寫是指 Redis 會讀取當前數據庫中的所有鍵值對,然后根據這些鍵值對重新構建出能夠恢復當前數據庫狀態的最小命令集合,再將這些命令寫入一個新的 AOF 文件,而不是簡單地將原 AOF 文件中的命令進行壓縮。
舉個例子,假設先后執行了三條命令:
SET key1 value1 APPEND key1 value2 APPEND key1 value3
在 AOF 文件中會依次記錄這三條命令。但通過 AOF 重寫,Redis 會直接生成?
SET key1 value1value2value3
?這一條命令,達到同樣的效果,卻極大減少了命令數量。2. 觸發方式
- 手動觸發:可以通過?
BGREWRITEAOF
?命令手動觸發 AOF 重寫。執行該命令后,Redis 會在后臺(fork 一個子進程)進行 AOF 重寫操作,不會阻塞主線程,保證 Redis 的正常服務。- 自動觸發:Redis 會根據配置文件中的相關參數自動觸發 AOF 重寫。主要涉及兩個參數:
auto-aof-rewrite-percentage
:指定 AOF 文件大小相較于上次重寫后增長的百分比。默認值為 100,表示如果 AOF 文件大小比上次重寫后增大了一倍(100%),就可能觸發 AOF 重寫。auto-aof-rewrite-min-size
:指定觸發 AOF 重寫的最小 AOF 文件大小。默認值為 64MB,即只有當 AOF 文件大小大于等于 64MB,且滿足?auto-aof-rewrite-percentage
?設定的增長條件時,才會觸發 AOF 重寫 。3. 執行過程
- fork 子進程:Redis 主進程調用?
fork
?函數創建一個子進程,子進程負責進行 AOF 重寫工作。在這個過程中,主進程和子進程共享內存數據,這樣可以避免復制大量數據帶來的性能開銷。- 子進程重寫:子進程遍歷當前數據庫中的所有鍵值對,根據鍵值對的類型和狀態生成對應的最小命令集合,并寫入到一個臨時的 AOF 重寫文件中。
- 主進程處理新寫命令:在子進程進行 AOF 重寫期間,主進程依然可以正常處理客戶端的請求。對于新收到的寫命令,主進程一方面會將其追加到現有的 AOF 文件中,以保證數據的實時持久化;另一方面會將這些新寫命令記錄到一個內存緩沖區(AOF 重寫緩沖區)中。
- 完成重寫并替換:當子進程完成 AOF 重寫后,會向主進程發送一個信號。主進程收到信號后,會先將 AOF 重寫緩沖區中的所有寫命令追加到新的 AOF 重寫文件中,以保證新 AOF 文件中的數據和當前數據庫狀態一致。然后,主進程會原子性地用新的 AOF 重寫文件替換掉原來的 AOF 文件,完成 AOF 重寫操作。
通過 AOF 重寫機制,Redis 可以在保證數據完整性的前提下,有效控制 AOF 文件的大小,提升數據恢復效率和磁盤空間利用率。
優點:
- 數據安全性更高,可以配置不同的同步策略
- AOF 文件是可讀的文本文件,包含所有操作命令,便于分析和修改
缺點:
- AOF 文件通常比 RDB 文件大
- 恢復數據的速度比 RDB 慢
- 在高負載下可能會影響性能
4. 混合持久化(Redis 4.0+)
Redis 4.0 引入了混合持久化機制,結合了 RDB 和 AOF 的優點:
- 快照以 RDB 格式寫入文件開頭
- 之后的增量數據以 AOF 命令格式存儲
配置方式:
# 開啟混合持久化
aof-use-rdb-preamble yes
5.對于信號的簡單解釋
6. 如何選擇持久化方式
- 如果需要快速恢復且可以接受少量數據丟失,選擇 RDB
- 如果需要更高的數據安全性,選擇 AOF
- 對于關鍵業務,推薦使用混合持久化或同時啟用 RDB 和 AOF
可以通過?CONFIG SET
?命令動態修改持久化配置,也可以使用?SAVE
?或?BGSAVE
?命令手動觸發 RDB 快照,使用?BGREWRITEAOF
?命令重寫 AOF 文件。