Redis是一個基於記憶體的高效能的鍵值型資料庫,它支援三種不同的持久化策略:RDB(快照)、AOF(追加檔案)、混合。這三種策略各有優缺點,需要根據不同的場景和需求進行選擇和設定。本文將介紹這三種策略
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持久化策略的缺點有:
AOF持久化策略是指將Redis伺服器執行的每一條寫命令都記錄到一個文字檔案中,這個文字檔案就是一個追加檔案(append only file)
AOF有三種持久化策略,也就是刷盤策略。可以根據不同的場景使用不同的刷盤策略。
然而隨著時間的推移,AOF檔案也會越來越大,因為它記錄了所有的寫命令。這樣會導致AOF檔案佔用過多的磁碟空間,以及恢復資料的時間過長。為了解決這個問題,Redis提供了AOF重寫機制,來壓縮和優化AOF檔案。
AOF持久化策略的優點有:
AOF持久化策略的缺點有:
當Redis重啟時,可以通過重新執行追加檔案中的命令來恢復資料。AOF持久化策略可以通過組態檔來開啟和設定,它決定了寫命令記錄到AOF檔案的頻率。有三個選項:
以下是三個策略的對比:
型別 | 資料安全性 | 效能 |
no | 低 | 高 |
everysec | 較高 | 較高 |
always | 高 | 低 |
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重寫之後的檔案的百分比。預設100
# 也就是預設達到上一次AOF重寫檔案的2倍之後會再次觸發AOF重寫
auto-aof-rewrite-percentage 100
# 設定允許重寫的最小AOF檔案大小,預設是64M
# 主要是避免滿足了上面的百分比,但是檔案還是很小的情況。
auto-aof-rewrite-min-size 64mb
bgrewriteaof
命令。Redis現有的持久化策略有三種:
他們各有優缺點,需要結合不同的應用場景綜合考慮,首先先講解AOF和RDB的選擇,再講解混合模式
在Redis中,AOF和RDB兩種持久化方式各有優缺點,一般來說,有以下幾個方面需要參考:
資料安全性 | 資料恢復速度 | 資料備份和遷移 | 資料可讀性 | |
---|---|---|---|---|
AOF | 高 | 低 | 低 | 高 |
RDB | 低 | 高 | 高 | 低 |
綜合上一節,我們可以根據不同的場景和需求來選擇合適的持久化方式。但是,在實際應用中,並不一定要二選一,也可以同時使用AOF和RDB兩種持久化方式。這樣可以利用AOF來保證資料不丟失,作為資料恢復的第一選擇;用RDB做不同程度的冷備份,當AOF備份檔案丟失或損壞不可用時,可以使用RDB快照檔案快速地恢復資料
綜上所述,混合模式兼併了RDB重啟後的快速恢復能力和AOF丟失資料風險低的能力,具體操作流程如下:
BGSAVE
寫入AOF中BGREWRITEAOF
後,會將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兩種持久化方式也需要注意一些問題:
在Redis中,AOF重寫和RDB持久化可能會同時發生,這會導致一些衝突和問題。例如:
為了解決這些衝突和問題,Redis採用了以下策略:
總之,Redis通過優先順序、延遲和順序等方式來協調AOF重寫和RDB持久化的衝突和問題,保證了資料的完整性和一致性,下圖為簡要說明。
場景 | 策略 |
---|---|
AOF重寫與RDB持久化同時被觸發 | 優先RDB |
AOF重寫正在進行 | 優先AOF |
AOF重寫和RDB持久化都完成 | 優先RDB |
AOF校驗機制是指在Redis啟動時,對AOF檔案進行檢查,判斷檔案是否完整,是否有損壞或者丟失的資料。如果發現AOF檔案有問題,Redis會拒絕啟動,並給出相應的錯誤資訊
AOF校驗機制的原理是使用一個64位元的校驗和(checksum)來對AOF檔案進行驗證。校驗和是一個數位,它是根據AOF檔案的內容計算出來的,如果AOF檔案的內容發生了任何改變,那麼校驗和也會發生變化。因此,通過比較計算出來的校驗和和儲存在AOF檔案末尾的校驗和,就可以判斷AOF檔案是否完整。
具體來說,AOF校驗機制的過程如下:
*1\r\n$6\r\nCHECKSUM\r\n
,這個命令表示接下來要寫入一個校驗和Bad file format reading the append only file: checksum mismatch
這樣的錯誤資訊通過這種方式,Redis可以保證在啟動時檢測到AOF檔案是否完整,從而避免載入錯誤或者不完整的資料。當然,這種機制也有一些侷限性:
總之,AOF校驗機制是一種簡單而有效的方法,可以保證在Redis啟動時檢測到AOF檔案是否完整。但是它也有一些侷限性和代價,需要在實際應用中權衡利弊。
具體的選擇建議如下:
這三種模式各有優缺點,需要根據具體的場景和需求來進行選擇和設定。在選擇時,需要考慮以下幾個因素:
注意:
AOF策略設定為 always 或 everysec,並且BGSAVE
或BGREWRITEAOF
正在對磁碟執行大量 I/O 時,Redis 刷盤可能會阻塞
可以設定no-appendfsync-on-rewrite yes
,來緩解這個問題。這樣的話,當另一個子程序正在儲存的時候,Redis 的永續性與appendfsync no
相同。實際上,最嚴重的情況是丟失30秒的紀錄檔
當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檔案損壞時,會導致Redis無法正常啟動或者恢復資料。可以使用redis-check-aof
工具來修復AOF檔案,或者使用備份的RDB檔案來恢復資料
在 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檔案丟失時,會導致Redis無法恢復資料。為了解決這個問題,可以使用備份的AOF檔案或者其他節點的RDB檔案來恢復資料,或者增加RDB的快照頻率來減少資料丟失的風險
當RDB檔案損壞時,會導致Redis無法恢復資料。為了解決這個問題,可以使用redis-check-rdb
工具來檢查和修復RDB檔案,或者使用備份的AOF檔案或者其他節點的RDB檔案來恢復資料