網(wǎng)站在建設時不容忽略的一些細節(jié)最權(quán)威的排行榜網(wǎng)站
文章目錄
- Redis的三種持久化策略及選取建議
- 前言
- RDB(快照)
- 概述
- 優(yōu)缺點
- AOF(追加文件)
- 概述
- 優(yōu)缺點
- AOF刷盤策略
- AOF重寫
- 選取正確的持久化策略
- AOF和RDB的選擇
- AOF與RDB的混合模式
- AOF重寫和RDB持久化的沖突
- AOF校驗機制
- 三種模式的選擇建議
- 持久化策略常見問題及解決方案
- AOF文件過大
- AOF文件損壞
- AOF 文件可能會被截斷
- RDB文件丟失
- RDB文件損壞
- 總結(jié)
- 系列文章目錄
Redis的三種持久化策略及選取建議
前言
Redis是一個基于內(nèi)存的高性能的鍵值型數(shù)據(jù)庫,它支持三種不同的持久化策略:RDB(快照)、AOF(追加文件)、混合。這三種策略各有優(yōu)缺點,需要根據(jù)不同的場景和需求進行選擇和配置。本文將介紹這三種策略
RDB(快照)
概述
RDB持久化策略是指在一定的時間間隔內(nèi),將Redis內(nèi)存中的數(shù)據(jù)以二進制文件的形式保存到硬盤上。這個二進制文件就是一個快照,它記錄了某個時刻Redis內(nèi)存中的所有數(shù)據(jù)。RDB持久化策略可以通過配置文件或者命令來觸發(fā),配置文件中可以設置多個條件,當任意一個條件滿足時,就會執(zhí)行一次快照操作。如下所示:
save 900 1 # 900秒內(nèi)執(zhí)行一次 set 操作 則持久化1次
save 300 10 # 300秒內(nèi)執(zhí)行10次 set 操作,則持久化1次
save 60 10000 # 60秒內(nèi)執(zhí)行10000次 set 操作,則持久化1次
命令有兩種:
save
:不建議使用,會阻塞redis服務的進程,直到成功創(chuàng)建RDB文件bgsave
:父進程創(chuàng)建一個子進程生成RDB文件,父進程可以正常處理客戶端的指令,不影響主進程的服務
優(yōu)缺點
RDB持久化策略的優(yōu)點有:
- RDB文件是一個緊湊的二進制文件,占用空間小,傳輸速度快,適合做備份和災難恢復
- RDB文件恢復數(shù)據(jù)的速度比AOF快,因為只需要加載一次文件即可
- RDB持久化對Redis服務器的性能影響較小,因為大部分工作由子進程完成
RDB持久化策略的缺點有:
- RDB文件不能實時或者近實時地反映Redis內(nèi)存中的數(shù)據(jù),因為它是定時觸發(fā)的。如果在兩次快照之間發(fā)生故障,可能會丟失一部分數(shù)據(jù)
- RDB文件在生成過程中可能會占用較多的內(nèi)存和CPU資源,因為需要復制主進程的內(nèi)存并執(zhí)行壓縮操作
AOF(追加文件)
概述
AOF持久化策略是指將Redis服務器執(zhí)行的每一條寫命令都記錄到一個文本文件中,這個文本文件就是一個追加文件(append only file)
AOF有三種持久化策略,也就是刷盤策略。可以根據(jù)不同的場景使用不同的刷盤策略。
然而隨著時間的推移,AOF文件也會越來越大,因為它記錄了所有的寫命令。這樣會導致AOF文件占用過多的磁盤空間,以及恢復數(shù)據(jù)的時間過長。為了解決這個問題,Redis提供了AOF重寫機制,來壓縮和優(yōu)化AOF文件。
優(yōu)缺點
AOF持久化策略的優(yōu)點有:
- AOF文件可以實時或者近實時地記錄Redis內(nèi)存中的數(shù)據(jù),因為它是每次寫命令或者每秒鐘同步一次。如果在同步之間發(fā)生故障,可能會丟失一部分數(shù)據(jù),但是數(shù)據(jù)丟失的概率比RDB小。
- AOF文件是一個文本文件,可以方便地查看和編輯。AOF文件中的命令是Redis協(xié)議格式的,可以直接用Redis客戶端來執(zhí)行。
- AOF文件可以自動進行重寫,以減少冗余命令和文件體積。重寫過程不影響Redis服務器的正常服務,也不會丟失任何數(shù)據(jù)。
AOF持久化策略的缺點有:
- AOF文件通常比RDB文件大,占用更多的磁盤空間
- AOF文件恢復數(shù)據(jù)的速度比RDB慢,因為需要重新執(zhí)行所有的命令
- AOF文件在寫入過程中可能會出現(xiàn)數(shù)據(jù)不一致的情況,例如命令只寫入了一半或者寫入了錯誤的命令。這種情況下需要用redis-check-aof工具來修復AOF文件
AOF刷盤策略
當Redis重啟時,可以通過重新執(zhí)行追加文件中的命令來恢復數(shù)據(jù)。AOF持久化策略可以通過配置文件來開啟和設置,它決定了寫命令記錄到AOF文件的頻率。有三個選項:
- no:寫入緩存,什么時候刷盤由redis決定
- everysec:每隔一秒刷一次盤
- always:寫入緩存時同時寫入磁盤(盡快刷盤,而不是實時刷盤)
以下是三個策略的對比:
類型 | 數(shù)據(jù)安全性 | 性能 |
no | 低 | 高 |
everysec | 較高 | 較高 |
always | 高 | 低 |
AOF重寫
AOF重寫機制的原理是:Redis會創(chuàng)建一個新的AOF文件,然后根據(jù)內(nèi)存中的當前數(shù)據(jù)狀態(tài),生成相應的寫命令,并寫入到新的AOF文件中。這樣新的AOF文件就只包含了最終數(shù)據(jù)的寫命令,而不包含任何無效或者冗余的命令。例如:
# 原始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重寫期間的新數(shù)據(jù)不丟失,Redis中引入了AOF重寫緩沖區(qū)。當開始執(zhí)行AOF文件重寫之后又接收到客戶端的請求命令,不但要將命令寫入原本的AOF緩沖區(qū)(根據(jù)上面提到的參數(shù)刷盤),還要同時寫入AOF重寫緩沖區(qū):
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-u9lEQqp9-1684733193342)(https://secure2.wostatic.cn/static/sH2Ncnf2Vc3WRoQQWrk8Q/redis_aof_rewrite.png?auth_key=1684286048-feAWJs15rwF6vcevzJg77u-0-b5ee64f632fc1b396eb189fd041deb46)]
一旦子進程完成了AOF文件的重寫,此時會向父進程發(fā)出信號,父進程收到信號之后會進行阻塞(阻塞期間不執(zhí)行任何命令),并進行以下兩項工作:
- 將AOF重寫緩沖區(qū)的文件刷新到新的AOF文件內(nèi)
- 將新AOF文件進行改名并原子操作的替換掉舊的AOF文件
隨后,在完成了上面的兩項工作之后,整個AOF重寫工作完成,父進程開始正常接收命令。
- 自動觸發(fā):自動觸發(fā)可以通過以下參數(shù)進行設置。
# 文件大小超過上次AOF重寫之后的文件的百分比。默認100
# 也就是默認達到上一次AOF重寫文件的2倍之后會再次觸發(fā)AOF重寫
auto-aof-rewrite-percentage 100
# 設置允許重寫的最小AOF文件大小,默認是64M
# 主要是避免滿足了上面的百分比,但是文件還是很小的情況。
auto-aof-rewrite-min-size 64mb
- 手動觸發(fā):執(zhí)行
bgrewriteaof
命令。
選取正確的持久化策略
Redis現(xiàn)有的持久化策略有三種:
- AOF
- RDB
- AOF與RDB混合
他們各有優(yōu)缺點,需要結(jié)合不同的應用場景綜合考慮,首先先講解AOF和RDB的選擇,再講解混合模式
AOF和RDB的選擇
在Redis中,AOF和RDB兩種持久化方式各有優(yōu)缺點,一般來說,有以下幾個方面需要參考:
- 數(shù)據(jù)安全性:如果要求數(shù)據(jù)不丟失,推薦AOF
- AOF可以采取每秒同步一次數(shù)據(jù)或每次寫操作都同步用來保證數(shù)據(jù)安全性
- 如果使用每秒同步一次策略,則最多丟失一秒的數(shù)據(jù)
- 如果使用每次寫操作都同步策略,安全性達到了極致,但這會影響性能
- RDB是一個全量的二進制文件,恢復時只需要加載到內(nèi)存即可,但是可能會丟失最近幾分鐘的數(shù)據(jù)(取決于RDB持久化策略)
- AOF可以采取每秒同步一次數(shù)據(jù)或每次寫操作都同步用來保證數(shù)據(jù)安全性
- 數(shù)據(jù)恢復速度:如果要求快速恢復數(shù)據(jù),推薦RDB
- AOF需要重新執(zhí)行所有的寫命令,恢復時間會更長
- RDB是一個全量的二進制文件,恢復時只需要加載到內(nèi)存即可
- 數(shù)據(jù)備份和遷移:如果要求方便地進行數(shù)據(jù)備份和遷移,推薦RDB
- AOF文件可能會很大,傳輸速度慢
- RDB文件是一個緊湊的二進制文件,占用空間小,傳輸速度快
- 數(shù)據(jù)可讀性:如果要求能夠方便地查看和修改數(shù)據(jù),推薦AOF
- AOF是一個可讀的文本文件,記錄了所有的寫命令,可以用于災難恢復或者數(shù)據(jù)分析
- RDB是一個二進制文件,不易查看和修改
數(shù)據(jù)安全性 | 數(shù)據(jù)恢復速度 | 數(shù)據(jù)備份和遷移 | 數(shù)據(jù)可讀性 | |
---|---|---|---|---|
AOF | 高 | 低 | 低 | 高 |
RDB | 低 | 高 | 高 | 低 |
AOF與RDB的混合模式
綜合上一節(jié),我們可以根據(jù)不同的場景和需求來選擇合適的持久化方式。但是,在實際應用中,并不一定要二選一,也可以同時使用AOF和RDB兩種持久化方式。這樣可以利用AOF來保證數(shù)據(jù)不丟失,作為數(shù)據(jù)恢復的第一選擇;用RDB做不同程度的冷備份,當AOF備份文件丟失或損壞不可用時,可以使用RDB快照文件快速地恢復數(shù)據(jù)
綜上所述,混合模式兼并了RDB重啟后的快速恢復能力和AOF丟失數(shù)據(jù)風險低的能力,具體操作流程如下:
- 子進程會通過
BGSAVE
寫入AOF中 - 觸發(fā)
BGREWRITEAOF
后,會將AOF寫入到文件 - 將含有RDB和AOF的數(shù)據(jù)覆蓋舊的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持久化可能會同時發(fā)生沖突,導致內(nèi)存、CPU和磁盤的消耗增加。為了解決這個問題,Redis采用了一些策略來協(xié)調(diào)兩者之間的關系。具體可以參考下面的介紹(AOF重寫和RDB持久化的沖突)
- AOF文件可能會變得很大,導致磁盤空間不足或者恢復時間過長。為了解決這個問題,Redis提供了AOF重寫機制來壓縮AOF文件。具體可以參考上一節(jié)(AOF重寫)
- AOF文件可能會被損壞或者丟失,導致數(shù)據(jù)無法恢復。為了解決這個問題,Redis提供了AOF校驗機制來檢測AOF文件是否完整。具體可以參考下面的介紹(AOF校驗機制)
AOF重寫和RDB持久化的沖突
在Redis中,AOF重寫和RDB持久化可能會同時發(fā)生,這會導致一些沖突和問題。例如:
- AOF重寫和RDB持久化都需要fork子進程,如果兩個子進程同時存在,會增加內(nèi)存的消耗和系統(tǒng)的負載。
- AOF重寫和RDB持久化都需要寫入磁盤,如果兩個文件同時寫入,會增加磁盤的壓力和IO的開銷。
- AOF重寫和RDB持久化都需要在完成后通知主進程,如果兩個信號同時到達,可能會造成信號丟失或者處理錯誤。
為了解決這些沖突和問題,Redis采用了以下策略:
- 如果AOF重寫和RDB持久化同時被觸發(fā),那么只有一個子進程會被創(chuàng)建,優(yōu)先執(zhí)行RDB持久化,然后再執(zhí)行AOF重寫。這樣可以避免同時存在兩個子進程的情況。
- 如果AOF重寫正在進行,而此時又收到了RDB持久化的請求,那么RDB持久化會被延遲到AOF重寫完成后再執(zhí)行。這樣可以避免同時寫入兩個文件的情況。
- 如果AOF重寫和RDB持久化都完成了,那么主進程會先處理RDB持久化的信號,然后再處理AOF重寫的信號。這樣可以避免信號丟失或者處理錯誤的情況。
總之,Redis通過優(yōu)先級、延遲和順序等方式來協(xié)調(diào)AOF重寫和RDB持久化的沖突和問題,保證了數(shù)據(jù)的完整性和一致性,下圖為簡要說明。
場景 | 策略 |
---|---|
AOF重寫與RDB持久化同時被觸發(fā) | 優(yōu)先RDB |
AOF重寫正在進行 | 優(yōu)先AOF |
AOF重寫和RDB持久化都完成 | 優(yōu)先RDB |
AOF校驗機制
AOF校驗機制是指在Redis啟動時,對AOF文件進行檢查,判斷文件是否完整,是否有損壞或者丟失的數(shù)據(jù)。如果發(fā)現(xiàn)AOF文件有問題,Redis會拒絕啟動,并給出相應的錯誤信息
AOF校驗機制的原理是使用一個64位的校驗和(checksum)來對AOF文件進行驗證。校驗和是一個數(shù)字,它是根據(jù)AOF文件的內(nèi)容計算出來的,如果AOF文件的內(nèi)容發(fā)生了任何改變,那么校驗和也會發(fā)生變化。因此,通過比較計算出來的校驗和和保存在AOF文件末尾的校驗和,就可以判斷AOF文件是否完整。
具體來說,AOF校驗機制的過程如下:
- 當Redis執(zhí)行AOF重寫時,它會在新的AOF文件末尾寫入一個特殊的命令:
*1\r\n$6\r\nCHECKSUM\r\n
,這個命令表示接下來要寫入一個校驗和 - Redis會使用CRC64算法,對新的AOF文件中除了最后一行之外的所有內(nèi)容進行計算,得到一個64位的數(shù)字作為校驗和,并將這個數(shù)字以16進制的形式寫入到新的AOF文件末尾。
- Redis會將新的AOF文件替換舊的AOF文件,并將校驗和保存在內(nèi)存中
- 當Redis重啟時,它會讀取AOF文件,并使用同樣的CRC64算法,對除了最后一行之外的所有內(nèi)容進行計算,得到一個64位的數(shù)字作為校驗和,并將這個數(shù)字與內(nèi)存中保存的校驗和進行比較
- 如果兩個校驗和相同,說明AOF文件沒有損壞或者丟失數(shù)據(jù),Redis會繼續(xù)啟動并加載AOF文件中的數(shù)據(jù)
- 如果兩個校驗和不同,說明AOF文件有問題,Redis會拒絕啟動,并給出類似于
Bad file format reading the append only file: checksum mismatch
這樣的錯誤信息
通過這種方式,Redis可以保證在啟動時檢測到AOF文件是否完整,從而避免加載錯誤或者不完整的數(shù)據(jù)。當然,這種機制也有一些局限性:
- AOF校驗機制只能在Redis啟動時執(zhí)行,如果在運行過程中AOF文件被修改或者損壞,Redis無法及時發(fā)現(xiàn)。
- AOF校驗機制只能檢測到AOF文件是否完整,但不能檢測到AOF文件是否正確。比如說,如果有人惡意地修改了AOF文件中的某些命令或者參數(shù),導致數(shù)據(jù)邏輯上出現(xiàn)錯誤,那么Redis無法識別出這種情況。
- AOF校驗機制會增加Redis啟動時的時間開銷,因為需要對整個AOF文件進行計算。如果AOF文件很大,那么這個過程可能會很慢。
總之,AOF校驗機制是一種簡單而有效的方法,可以保證在Redis啟動時檢測到AOF文件是否完整。但是它也有一些局限性和代價,需要在實際應用中權(quán)衡利弊。
三種模式的選擇建議
具體的選擇建議如下:
- 如果對數(shù)據(jù)完整性要求不高,可以只使用RDB,或者將AOF的同步頻率設置為每秒一次
- 如果想讓數(shù)據(jù)盡可能不丟失,可以只使用AOF,并將AOF的同步頻率設置為每次寫入操作都同步
- 如果對數(shù)據(jù)完整性和性能都有要求,可以同時使用AOF和RDB,并將AOF的同步頻率設置為每秒一次。這樣既可以保證數(shù)據(jù)的安全性,又可以利用RDB進行快速的數(shù)據(jù)恢復
- 如果既想節(jié)省磁盤空間,又想提高數(shù)據(jù)恢復速度,可以只使用RDB,并適當調(diào)整RDB的快照頻率
AOF和RDB兩種持久化方式各有優(yōu)缺點,需要根據(jù)具體的場景和需求來進行選擇和配置。在選擇時,需要考慮以下幾個因素:
- 數(shù)據(jù)完整性:即數(shù)據(jù)丟失的風險和可接受的范圍
- 數(shù)據(jù)恢復速度:即從持久化文件恢復到內(nèi)存中所需的時間
- 磁盤空間占用:即持久化文件所占用的磁盤空間大小
- 寫入性能:即持久化操作對Redis服務端的寫入性能的影響
注意:
AOF策略設置為 always 或 everysec,并且BGSAVE
或BGREWRITEAOF
正在對磁盤執(zhí)行大量 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
參數(shù)來觸發(fā)AOF重寫操作,將AOF文件壓縮為最小的命令集合
# 文件大小超過上次AOF重寫之后的文件的百分比。默認100
# 也就是默認達到上一次AOF重寫文件的2倍之后會再次觸發(fā)AOF重寫
auto-aof-rewrite-percentage 100
# 設置允許重寫的最小AOF文件大小,默認是64M
# 主要是避免滿足了上面的百分比,但是文件還是很小的情況。
auto-aof-rewrite-min-size 64mb
AOF文件損壞
當AOF文件損壞時,會導致Redis無法正常啟動或者恢復數(shù)據(jù)??梢允褂?code>redis-check-aof工具來修復AOF文件,或者使用備份的RDB文件來恢復數(shù)據(jù)
AOF 文件可能會被截斷
在 Redis 啟動過程中,當 AOF 數(shù)據(jù)被加載回內(nèi)存時,可能會發(fā)現(xiàn) AOF 文件在最后被截斷
aof-load-truncated yes
,則加載截斷的 AOF 文件,并且記錄日志aof-load-truncated no
,則服務器會因錯誤拒絕啟動,且需要在啟動服務器之前使用redis-check-aof
修復aof文件
可以在redis.conf
中配置:
aof-load-truncated yes
可記錄時間戳幫助恢復數(shù)據(jù)
如果在AOF記錄時間戳,可能會與現(xiàn)有的AOF解析器不兼容,默認關閉
redis.conf
中配置:
aof-timestamp-enabled no
RDB文件丟失
當RDB文件丟失時,會導致Redis無法恢復數(shù)據(jù)。為了解決這個問題,可以使用備份的AOF文件或者其他節(jié)點的RDB文件來恢復數(shù)據(jù),或者增加RDB的快照頻率來減少數(shù)據(jù)丟失的風險
RDB文件損壞
當RDB文件損壞時,會導致Redis無法恢復數(shù)據(jù)。為了解決這個問題,可以使用redis-check-rdb
工具來檢查和修復RDB文件,或者使用備份的AOF文件或者其他節(jié)點的RDB文件來恢復數(shù)據(jù)
總結(jié)
本文介紹了Redis中的四種特殊數(shù)據(jù)類型:Hyperloglog、GEO、Bitmap、Bitfield
- Hyperloglog是一種用來估計基數(shù)的算法,它可以用少量的內(nèi)存來統(tǒng)計大量不重復元素的個數(shù),適用于諸如UV統(tǒng)計、在線用戶數(shù)等場景
- GEO是一種用來存儲地理坐標和計算距離的數(shù)據(jù)類型,它可以用來實現(xiàn)附近的人、地點等功能
- Bitmap是一種用一個bit位來表示某個元素對應的值或狀態(tài)的數(shù)據(jù)類型,它可以用來實現(xiàn)用戶在線狀態(tài)、簽到功能等
- Bitfield是一種用來對字符串中的位進行操作的命令,它可以用來實現(xiàn)計數(shù)器、布隆過濾器等功能
這些特殊數(shù)據(jù)類型都展示了Redis的強大和靈活性,為開發(fā)者提供了更多的可能性
系列文章目錄
Redis內(nèi)存優(yōu)化——String類型介紹及底層原理詳解
Redis內(nèi)存優(yōu)化——Hash類型介紹及底層原理詳解
Redis內(nèi)存優(yōu)化——List類型介紹及底層原理詳解
Redis內(nèi)存優(yōu)化——Set類型介紹及底層原理詳解
Redis內(nèi)存優(yōu)化——ZSet類型介紹及底層原理詳解
Redis內(nèi)存優(yōu)化——Stream類型介紹及底層原理詳解
Redis內(nèi)存優(yōu)化——Hyperloglog、GEO、Bitmap、Bitfield類型詳解
Redis的三種持久化策略及選取建議