概述
Redis是一個基于記憶體的高性能的鍵值型資料庫,它支持三種不同的持久化策略:RDB(快照)、AOF(追加檔案)、混合,這三種策略各有優缺點,需要根據不同的場景和需求進行選擇和配置,本文將介紹這三種策略
RDB(快照)
概述
RDB持久化策略是指在一定的時間間隔內,將Redis記憶體中的資料以二進制檔案的形式保存到硬碟上,這個二進制檔案就是一個快照,它記錄了某個時刻Redis記憶體中的所有資料,RDB持久化策略可以通過組態檔或者命令來觸發,組態檔中可以設定多個條件,當任意一個條件滿足時,就會執行一次快照操作,如下所示:
save 900 1 # 900秒內執行一次 set 操作 則持久化1次
save 300 10 # 300秒內執行10次 set 操作,則持久化1次
save 60 10000 # 60秒內執行10000次 set 操作,則持久化1次
命令有兩種:
save:不建議使用,會阻塞redis服務的行程,直到成功創建RDB檔案bgsave:父行程創建一個子行程生成RDB檔案,父行程可以正常處理客戶端的指令,不影響主行程的服務
優缺點
RDB持久化策略的優點有:
- RDB檔案是一個緊湊的二進制檔案,占用空間小,傳輸速度快,適合做備份和災難恢復
- RDB檔案恢復資料的速度比AOF快,因為只需要加載一次檔案即可
- RDB持久化對Redis服務器的性能影響較小,因為大部分作業由子行程完成
RDB持久化策略的缺點有:
- RDB檔案不能實時或者近實時地反映Redis記憶體中的資料,因為它是定時觸發的,如果在兩次快照之間發生故障,可能會丟失一部分資料
- RDB檔案在生成程序中可能會占用較多的記憶體和CPU資源,因為需要復制主行程的記憶體并執行壓縮操作
AOF(追加檔案)
概述
AOF持久化策略是指將Redis服務器執行的每一條寫命令都記錄到一個文本檔案中,這個文本檔案就是一個追加檔案(append only file)
AOF有三種持久化策略,也就是刷盤策略,可以根據不同的場景使用不同的刷盤策略,
然而隨著時間的推移,AOF檔案也會越來越大,因為它記錄了所有的寫命令,這樣會導致AOF檔案占用過多的磁盤空間,以及恢復資料的時間過長,為了解決這個問題,Redis提供了AOF重寫機制,來壓縮和優化AOF檔案,
優缺點
AOF持久化策略的優點有:
- AOF檔案可以實時或者近實時地記錄Redis記憶體中的資料,因為它是每次寫命令或者每秒鐘同步一次,如果在同步之間發生故障,可能會丟失一部分資料,但是資料丟失的概率比RDB小,
- AOF檔案是一個文本檔案,可以方便地查看和編輯,AOF檔案中的命令是Redis協議格式的,可以直接用Redis客戶端來執行,
- AOF檔案可以自動進行重寫,以減少冗余命令和檔案體積,重寫程序不影響Redis服務器的正常服務,也不會丟失任何資料,
AOF持久化策略的缺點有:
- AOF檔案通常比RDB檔案大,占用更多的磁盤空間
- AOF檔案恢復資料的速度比RDB慢,因為需要重新執行所有的命令
- AOF檔案在寫入程序中可能會出現資料不一致的情況,例如命令只寫入了一半或者寫入了錯誤的命令,這種情況下需要用redis-check-aof工具來修復AOF檔案
AOF刷盤策略
當Redis重啟時,可以通過重新執行追加檔案中的命令來恢復資料,AOF持久化策略可以通過組態檔來開啟和設定,它決定了寫命令記錄到AOF檔案的頻率,有三個選項:
- no:寫入快取,什么時候刷盤由redis決定
- everysec:每隔一秒刷一次盤
- always:寫入快取時同時寫入磁盤(盡快刷盤,而不是實時刷盤)
以下是三個策略的對比:
| 型別 | 資料安全性 | 性能 |
| no | 低 | 高 |
| everysec | 較高 | 較高 |
| always | 高 | 低 |
AOF重寫
AOF重寫機制的原理是:Redis會創建一個新的AOF檔案,然后根據記憶體中的當前資料狀態,生成相應的寫命令,并寫入到新的AOF檔案中,這樣新的AOF檔案就只包含了最終資料的寫命令,而不包含任何無效或者冗余的命令,例如:
# 原始AOF檔案
set a 1
set b 2
incr a
del b
set c 3
# 重寫后的AOF檔案
set a 2
set c 3
上圖就是重寫前和重寫后的檔案對比,因為AOF是追加的,是順序讀寫(ES也是這樣的),所以重寫后的命令set a 1與incr a變成為set a 2,為了保證在AOF重寫期間的新資料不丟失,Redis中引入了AOF重寫緩沖區,當開始執行AOF檔案重寫之后又接收到客戶端的請求命令,不但要將命令寫入原本的AOF緩沖區(根據上面提到的引數刷盤),還要同時寫入AOF重寫緩沖區:

一旦子行程完成了AOF檔案的重寫,此時會向父行程發出信號,父行程收到信號之后會進行阻塞(阻塞期間不執行任何命令),并進行以下兩項作業:
- 將AOF重寫緩沖區的檔案重繪到新的AOF檔案內
- 將新AOF檔案進行改名并原子操作的替換掉舊的AOF檔案
隨后,在完成了上面的兩項作業之后,整個AOF重寫作業完成,父行程開始正常接收命令,
- 自動觸發:自動觸發可以通過以下引數進行設定,
# 檔案大小超過上次AOF重寫之后的檔案的百分比,默認100
# 也就是默認達到上一次AOF重寫檔案的2倍之后會再次觸發AOF重寫
auto-aof-rewrite-percentage 100
# 設定允許重寫的最小AOF檔案大小,默認是64M
# 主要是避免滿足了上面的百分比,但是檔案還是很小的情況,
auto-aof-rewrite-min-size 64mb
- 手動觸發:執行
bgrewriteaof命令,
選取正確的持久化策略
Redis現有的持久化策略有三種:
- AOF
- RDB
- AOF與RDB混合
他們各有優缺點,需要結合不同的應用場景綜合考慮,首先先講解AOF和RDB的選擇,再講解混合模式
AOF和RDB的選擇
在Redis中,AOF和RDB兩種持久化方式各有優缺點,一般來說,有以下幾個方面需要參考:
- 資料安全性:如果要求資料不丟失,推薦AOF
- AOF可以采取每秒同步一次資料或每次寫操作都同步用來保證資料安全性
- 如果使用每秒同步一次策略,則最多丟失一秒的資料
- 如果使用每次寫操作都同步策略,安全性達到了極致,但這會影響性能
- RDB是一個全量的二進制檔案,恢復時只需要加載到記憶體即可,但是可能會丟失最近幾分鐘的資料(取決于RDB持久化策略)
- AOF可以采取每秒同步一次資料或每次寫操作都同步用來保證資料安全性
- 資料恢復速度:如果要求快速恢復資料,推薦RDB
- AOF需要重新執行所有的寫命令,恢復時間會更長
- RDB是一個全量的二進制檔案,恢復時只需要加載到記憶體即可
- 資料備份和遷移:如果要求方便地進行資料備份和遷移,推薦RDB
- AOF檔案可能會很大,傳輸速度慢
- RDB檔案是一個緊湊的二進制檔案,占用空間小,傳輸速度快
- 資料可讀性:如果要求能夠方便地查看和修改資料,推薦AOF
- AOF是一個可讀的文本檔案,記錄了所有的寫命令,可以用于災難恢復或者資料分析
- RDB是一個二進制檔案,不易查看和修改
| 資料安全性 | 資料恢復速度 | 資料備份和遷移 | 資料可讀性 | |
|---|---|---|---|---|
| AOF | 高 | 低 | 低 | 高 |
| RDB | 低 | 高 | 高 | 低 |
AOF與RDB的混合模式
綜合上一節,我們可以根據不同的場景和需求來選擇合適的持久化方式,但是,在實際應用中,并不一定要二選一,也可以同時使用AOF和RDB兩種持久化方式,這樣可以利用AOF來保證資料不丟失,作為資料恢復的第一選擇;用RDB做不同程度的冷備份,當AOF備份檔案丟失或損壞不可用時,可以使用RDB快照檔案快速地恢復資料
綜上所述,混合模式兼并了RDB重啟后的快速恢復能力和AOF丟失資料風險低的能力,具體操作流程如下:
- 子行程會通過
BGSAVE寫入AOF中 - 觸發
BGREWRITEAOF后,會將AOF寫入到檔案 - 將含有RDB和AOF的資料覆寫舊的AOF檔案(這時AOF檔案一半為RDB,一半為AOF)
混合模式的AOF檔案:
REDIS0008?redis-ver4.0.1?redis-bits繞?ctime聮~`?used-mem?? ?aof-preamble??repl-id(6c3378899b63bc4ebeaafaa09c27902d514eeb1f?repl-offset??? list1?77 / appleorangegrape?e k1v1彝髖S[zb*2
$6
SELECT
$1
0
*3
$4
sadd
$8
gamedisk
$4
nioh
*3
$4
sadd
$8
gamedisk
$4
tomb
如果想要開啟混合模式,在redis.conf中配置:
aof-use-rdb-preamble yes
同時使用AOF和RDB兩種持久化方式也需要注意一些問題:
- AOF重寫和RDB持久化可能會同時發生沖突,導致記憶體、CPU和磁盤的消耗增加,為了解決這個問題,Redis采用了一些策略來協調兩者之間的關系,具體可以參考下面的介紹(AOF重寫和RDB持久化的沖突)
- AOF檔案可能會變得很大,導致磁盤空間不足或者恢復時間過長,為了解決這個問題,Redis提供了AOF重寫機制來壓縮AOF檔案,具體可以參考上一節(AOF重寫)
- AOF檔案可能會被損壞或者丟失,導致資料無法恢復,為了解決這個問題,Redis提供了AOF校驗機制來檢測AOF檔案是否完整,具體可以參考下面的介紹(AOF校驗機制)
AOF重寫和RDB持久化的沖突
在Redis中,AOF重寫和RDB持久化可能會同時發生,這會導致一些沖突和問題,例如:
- AOF重寫和RDB持久化都需要fork子行程,如果兩個子行程同時存在,會增加記憶體的消耗和系統的負載,
- AOF重寫和RDB持久化都需要寫入磁盤,如果兩個檔案同時寫入,會增加磁盤的壓力和IO的開銷,
- AOF重寫和RDB持久化都需要在完成后通知主行程,如果兩個信號同時到達,可能會造成信號丟失或者處理錯誤,
為了解決這些沖突和問題,Redis采用了以下策略:
- 如果AOF重寫和RDB持久化同時被觸發,那么只有一個子行程會被創建,優先執行RDB持久化,然后再執行AOF重寫,這樣可以避免同時存在兩個子行程的情況,
- 如果AOF重寫正在進行,而此時又收到了RDB持久化的請求,那么RDB持久化會被延遲到AOF重寫完成后再執行,這樣可以避免同時寫入兩個檔案的情況,
- 如果AOF重寫和RDB持久化都完成了,那么主行程會先處理RDB持久化的信號,然后再處理AOF重寫的信號,這樣可以避免信號丟失或者處理錯誤的情況,
總之,Redis通過優先級、延遲和順序等方式來協調AOF重寫和RDB持久化的沖突和問題,保證了資料的完整性和一致性,下圖為簡要說明,
| 場景 | 策略 |
|---|---|
| AOF重寫與RDB持久化同時被觸發 | 優先RDB |
| AOF重寫正在進行 | 優先AOF |
| AOF重寫和RDB持久化都完成 | 優先RDB |
AOF校驗機制
AOF校驗機制是指在Redis啟動時,對AOF檔案進行檢查,判斷檔案是否完整,是否有損壞或者丟失的資料,如果發現AOF檔案有問題,Redis會拒絕啟動,并給出相應的錯誤資訊
AOF校驗機制的原理是使用一個64位的校驗和(checksum)來對AOF檔案進行驗證,校驗和是一個數字,它是根據AOF檔案的內容計算出來的,如果AOF檔案的內容發生了任何改變,那么校驗和也會發生變化,因此,通過比較計算出來的校驗和和保存在AOF檔案末尾的校驗和,就可以判斷AOF檔案是否完整,
具體來說,AOF校驗機制的程序如下:
- 當Redis執行AOF重寫時,它會在新的AOF檔案末尾寫入一個特殊的命令:
*1\r\n$6\r\nCHECKSUM\r\n,這個命令表示接下來要寫入一個校驗和 - Redis會使用CRC64演算法,對新的AOF檔案中除了最后一行之外的所有內容進行計算,得到一個64位的數字作為校驗和,并將這個數字以16進制的形式寫入到新的AOF檔案末尾,
- Redis會將新的AOF檔案替換舊的AOF檔案,并將校驗和保存在記憶體中
- 當Redis重啟時,它會讀取AOF檔案,并使用同樣的CRC64演算法,對除了最后一行之外的所有內容進行計算,得到一個64位的數字作為校驗和,并將這個數字與記憶體中保存的校驗和進行比較
- 如果兩個校驗和相同,說明AOF檔案沒有損壞或者丟失資料,Redis會繼續啟動并加載AOF檔案中的資料
- 如果兩個校驗和不同,說明AOF檔案有問題,Redis會拒絕啟動,并給出類似于
Bad file format reading the append only file: checksum mismatch這樣的錯誤資訊
通過這種方式,Redis可以保證在啟動時檢測到AOF檔案是否完整,從而避免加載錯誤或者不完整的資料,當然,這種機制也有一些局限性:
- AOF校驗機制只能在Redis啟動時執行,如果在運行程序中AOF檔案被修改或者損壞,Redis無法及時發現,
- AOF校驗機制只能檢測到AOF檔案是否完整,但不能檢測到AOF檔案是否正確,比如說,如果有人惡意地修改了AOF檔案中的某些命令或者引數,導致資料邏輯上出現錯誤,那么Redis無法識別出這種情況,
- AOF校驗機制會增加Redis啟動時的時間開銷,因為需要對整個AOF檔案進行計算,如果AOF檔案很大,那么這個程序可能會很慢,
總之,AOF校驗機制是一種簡單而有效的方法,可以保證在Redis啟動時檢測到AOF檔案是否完整,但是它也有一些局限性和代價,需要在實際應用中權衡利弊,
三種模式的選擇建議
具體的選擇建議如下:
- 如果對資料完整性要求不高,可以只使用RDB,或者將AOF的同步頻率設定為每秒一次
- 如果想讓資料盡可能不丟失,可以只使用AOF,并將AOF的同步頻率設定為每次寫入操作都同步
- 如果對資料完整性和性能都有要求,可以同時使用AOF和RDB,并將AOF的同步頻率設定為每秒一次,這樣既可以保證資料的安全性,又可以利用RDB進行快速的資料恢復
- 如果既想節省磁盤空間,又想提高資料恢復速度,可以只使用RDB,并適當調整RDB的快照頻率
這三種模式各有優缺點,需要根據具體的場景和需求來進行選擇和配置,在選擇時,需要考慮以下幾個因素:
- 資料完整性:即資料丟失的風險和可接受的范圍
- 資料恢復速度:即從持久化檔案恢復到記憶體中所需的時間
- 磁盤空間占用:即持久化檔案所占用的磁盤空間大小
- 寫入性能:即持久化操作對Redis服務端的寫入性能的影響
注意:
AOF策略設定為 always 或 everysec,并且BGSAVE或BGREWRITEAOF正在對磁盤執行大量 I/O 時,Redis 刷盤可能會阻塞
可以設定no-appendfsync-on-rewrite yes,來緩解這個問題,這樣的話,當另一個子行程正在保存的時候,Redis 的持久性與appendfsync no相同,實際上,最嚴重的情況是丟失30秒的日志
持久化策略常見問題及解決方案
AOF檔案過大
當AOF檔案過大時,會占用磁盤空間,影響寫入性能,甚至導致Redis啟動失敗,可以使用bgrewriteaof命令或者配置auto-aof-rewrite-percentage和auto-aof-rewrite-min-size引數來觸發AOF重寫操作,將AOF檔案壓縮為最小的命令集合
# 檔案大小超過上次AOF重寫之后的檔案的百分比,默認100
# 也就是默認達到上一次AOF重寫檔案的2倍之后會再次觸發AOF重寫
auto-aof-rewrite-percentage 100
# 設定允許重寫的最小AOF檔案大小,默認是64M
# 主要是避免滿足了上面的百分比,但是檔案還是很小的情況,
auto-aof-rewrite-min-size 64mb
AOF檔案損壞
當AOF檔案損壞時,會導致Redis無法正常啟動或者恢復資料,可以使用redis-check-aof工具來修復AOF檔案,或者使用備份的RDB檔案來恢復資料
AOF 檔案可能會被截斷
在 Redis 啟動程序中,當 AOF 資料被加載回記憶體時,可能會發現 AOF 檔案在最后被截斷
aof-load-truncated yes,則加載截斷的 AOF 檔案,并且記錄日志aof-load-truncated no,則服務器會因錯誤拒絕啟動,且需要在啟動服務器之前使用redis-check-aof修復aof檔案
可以在redis.conf中配置:
aof-load-truncated yes
可記錄時間戳幫助恢復資料
如果在AOF記錄時間戳,可能會與現有的AOF決議器不兼容,默認關閉
redis.conf中配置:
aof-timestamp-enabled no
RDB檔案丟失
當RDB檔案丟失時,會導致Redis無法恢復資料,為了解決這個問題,可以使用備份的AOF檔案或者其他節點的RDB檔案來恢復資料,或者增加RDB的快照頻率來減少資料丟失的風險
RDB檔案損壞
當RDB檔案損壞時,會導致Redis無法恢復資料,為了解決這個問題,可以使用redis-check-rdb工具來檢查和修復RDB檔案,或者使用備份的AOF檔案或者其他節點的RDB檔案來恢復資料
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/552572.html
標籤:架構設計
上一篇:Kafka 高可靠高性能原理探究
下一篇:返回列表
