Redis持久化基石RDB與AOF
Redis持久化
為什么需要持久化
其實在我們工作中也有多持久化場景,比如word。它的持久化形式是以~$論文.docx的形式來持久化。
那么在Redis中為了防止數(shù)據(jù)意外丟失,確保數(shù)據(jù)安全,也會進(jìn)行持久化。
利用永久性存儲介質(zhì)將數(shù)據(jù)進(jìn)行保存,在特定的時間將保存的數(shù)據(jù)進(jìn)行恢復(fù)的工作機(jī)制稱為持久化。
在Redis中有兩種持久化方式:RDB(Redis DataBase)、AOF(Append Only File)。
RDB(Redis DataBase)將當(dāng)前數(shù)據(jù)狀態(tài)進(jìn)行保存,快照形式,存儲數(shù)據(jù)結(jié)果,存儲格式簡單,關(guān)注點在數(shù)據(jù)。
AOF(Append Only File)將數(shù)據(jù)的操作過程進(jìn)行保存,日志形式,存儲操作過程,存儲格式復(fù)雜,關(guān)注點在命令。
RDB持久化
在Redis中可以使用save命令來執(zhí)行一次RDB持久化操作.
save指令相關(guān)配置:
- dbfilename.dump.rdb
- 說明:設(shè)置本地數(shù)據(jù)庫文件名,默認(rèn)值為dump.rdb
- dir
- 說明:設(shè)置存儲.rdb文件的路徑
- rdbcompression yes
- 說明:設(shè)置存儲至本地數(shù)據(jù)庫時是否壓縮數(shù)據(jù),默認(rèn)為yes,采用LZF壓縮
- rdbchecksum yes
- 說明:設(shè)置是否進(jìn)行RDB文件格式校驗,該校驗在寫文件和讀文件過程均進(jìn)行
我們知道早期Redis版本是單線程的。當(dāng)我們執(zhí)行save命令時會阻塞當(dāng)前Redis服務(wù)器,直到RDB過程完成為止,有可能會造成長時間阻塞,線上環(huán)境不建議使用。
那么問題來了,既然使用save會對線上服務(wù)器造成影響,那么有沒有一種更好的持久化方式呢?答案是有的,那就是bgsave.
通過名稱可以看出這個持久化操作是后臺執(zhí)行的,不會導(dǎo)致Redis發(fā)生阻塞。
下面看一下bgsave的工作原理:
可以看出,當(dāng)執(zhí)行bgsave命令后Redis會fork出一個子進(jìn)程,用于創(chuàng)建RDB文件進(jìn)行持久化,這樣一來就不會阻塞Redis了。但是bgsave不會立即執(zhí)行,且會消耗額外的CPU資源。
bgsave命令是針對save阻塞問題做的優(yōu)化。Redis內(nèi)部所有涉及到RDB操作都采用bgsave的方式,save命令可以放棄使用。
bgsave指令相關(guān)配置:
- dbfilename.dump.rdb
- 說明:設(shè)置本地數(shù)據(jù)庫文件名,默認(rèn)值為dump.rdb
- dir
- 說明:設(shè)置存儲.rdb文件的路徑
- rdbcompression yes
- 說明:設(shè)置存儲至本地數(shù)據(jù)庫時是否壓縮數(shù)據(jù),默認(rèn)為yes,采用LZF壓縮
- rdbchecksum yes
- 說明:設(shè)置是否進(jìn)行RDB文件格式校驗,該校驗在寫文件和讀文件過程均進(jìn)行
- stop-writes-on-bgsave-error yes
- 說明:后臺存儲如果出現(xiàn)錯誤,是否停止保存操作
那么問題又來了,我們不可能一直手動去執(zhí)行或者bgsave指令,這時Redis為我們提供了自動執(zhí)行bgsave的功能。
在Redis的配置文件中有這么一個配置save [secone] [changes]可以幫助我們自動進(jìn)行持久化。
- 配置:
- save second changes
- 作用:
- 滿足限定時間范圍內(nèi)key的變化數(shù)量達(dá)到指定數(shù)量即進(jìn)行持久化
- 參數(shù):
- second:監(jiān)控時間范圍
- changes:監(jiān)控key的變化量
- 位置:
- 在conf文件中進(jìn)行配置
- 范例:
- save 900 1
- save 300 10
- save 60 10000
注意: save配置要根據(jù)實際業(yè)務(wù)情況進(jìn)行設(shè)置,頻度過高或過低都會出現(xiàn)性能問題,結(jié)果可能是災(zāi)難性的 save配置中對于second與changes設(shè)置通常具有互補(bǔ)對應(yīng)關(guān)系,盡量不要設(shè)置成包含性關(guān)系 save配置啟動后執(zhí)行的是bgsave操作
RDB三種持久化方式對比:
RDB的優(yōu)點:
- RDB是一個緊湊的壓縮二進(jìn)制文件,存儲效率高
- RDB是內(nèi)部存儲的在Redis某個時間點的數(shù)據(jù)快照,非常適用于數(shù)據(jù)備份,全量復(fù)制等場景
- RDB恢復(fù)數(shù)據(jù)的速度要比AOF快的多
- 服務(wù)器每X個小時執(zhí)行bgsave備份,并將RDB文件拷貝至遠(yuǎn)程機(jī)器中,用于災(zāi)難恢復(fù)
RDB的缺點:
- RDB無論是執(zhí)行指令還是利用配置,都無法做到實時持久化,具有較大的可能性丟失數(shù)據(jù)
- bgsave每次執(zhí)行都會fork創(chuàng)建子進(jìn)程,要犧牲掉一些性能
- Redis眾多版本中,沒有對RDB文件格式統(tǒng)一,有可能出現(xiàn)各版本數(shù)據(jù)不兼容的情況
AOF持久化
AOF(Append Only File)持久化,以獨立日志的方式記錄每次寫命令,重啟時再重新執(zhí)行AOF文件中的命令達(dá)到恢復(fù)數(shù)據(jù)的目的。與RDB相比可以簡單描述為數(shù)據(jù)產(chǎn)生的過程。
AOF主要作用是解決了持久化的實時性,目前已經(jīng)是Redis持久化的主流方式。
AOF持久化過程
在把AOF命令緩沖區(qū)同步到文件時有三種寫數(shù)據(jù)策略(appendfsync):
- always(每次)
- 每次寫入操作均同步到AOF文件中,數(shù)據(jù)零誤差,但性能較低
- everysec(每秒)
- 每秒將緩沖區(qū)中的指令同步到AOF文件中,數(shù)據(jù)準(zhǔn)確性較高,性能也較高
- 在系統(tǒng)突然宕機(jī)是會丟失1秒內(nèi)的數(shù)據(jù)
- no(系統(tǒng)控制)
- 由操作系統(tǒng)每次同步到AOF文件的周期,整體過程不可控
Redis開啟AOF功能持久化
配置:
- appendonly yes|no
- 作用:是否開啟AOF持久化,默認(rèn)為不開啟狀態(tài)
- appendfsync always|everysec|no
- 作用:AOF同步命令數(shù)據(jù)策略
- appendfilename filename
- AOF持久化文件名,默認(rèn)文件名為appendonly.aof,建議配置成appendonly-端口號.aof
AOF在遇到相同命令是如何處理呢
假如同步策略是 appendfsync everysec每秒同步一次,執(zhí)行如下命令:
- set name zhangsan
- set name lisi
- set name wangwu
最終AOF文件里將只有一條:
- set name wangwu
AOF重寫
隨著AOF文件不斷寫入,AOF文件會越來越大,為了解決這個問題,Redis引入了AOF重寫機(jī)制壓縮文件體積。
AOF文件重寫是將Redis進(jìn)程內(nèi)的數(shù)據(jù)轉(zhuǎn)化為寫命令同步到新AOF文件的過程。簡單說就是將若干條命令執(zhí)行結(jié)果轉(zhuǎn)化成最終結(jié)果數(shù)據(jù)對應(yīng)的指令進(jìn)行記錄。
AOF 重寫的作用
- 降低磁盤占用量,提高磁盤利用率
- 提高持久化效率,降低持久化時間,提高IO性能
- 降低數(shù)據(jù)恢復(fù)的時間,提高數(shù)據(jù)恢復(fù)效率
AOF重寫的規(guī)則
- 進(jìn)程內(nèi)已經(jīng)超時的命令不再寫入文件
- 忽略無效指令,重寫時使用進(jìn)程內(nèi)數(shù)據(jù)直接生成,這樣新的AOF中只保留最終數(shù)據(jù)的寫入命令
- del key1
- hdel key2
- 對同一數(shù)據(jù)寫命令合并為一條命令
- 如下命令:
- lpush list1 a、lpush list1 b、 lpush list1 c
- 可以轉(zhuǎn)化為:
- lpush list1 a b c。
- 為防止數(shù)據(jù)量過大造成客戶端緩沖區(qū)溢出,對list、set、hash、zset等類型,每條指令最多寫入64個元素
AOF重寫規(guī)則
- 手動重寫
- bgrewriteaof
- 自動重寫
- auto-aof-rewrite-min-size size
- auto-aof-rewrite-percentage percentage
AOF重寫流程
AOF持久化+重寫:
- 執(zhí)行set等命令
- 主進(jìn)程先是執(zhí)行這條命令,緊接著fork一個子進(jìn)程,用于往AOF緩存區(qū)和AOF重寫緩存區(qū)寫命令
- 滿足條件后寫入AOF文件
- 當(dāng)bgwriteaof執(zhí)行時,同樣會fork一個子進(jìn)程從AOF重寫緩存區(qū)讀取指令并重啟,同時提示bgwriteaof正在執(zhí)行
- 重寫完成后,替換原來的.aof文件
RDB與AOF的區(qū)別
RDB與AOF如何選擇
對數(shù)據(jù)敏感,建議使用默認(rèn)的AOF持久化方案
- AOF持久化策略使用everysec,每秒鐘fsync一次。該策略可以很好的保持處理性能,當(dāng)出現(xiàn)問題時最多丟失0-1秒鐘的數(shù)據(jù)。
- 注意:由于AOF存儲體積較大,所以恢復(fù)速度較慢
數(shù)據(jù)呈現(xiàn)階段有效性,建議使用RDB持久化方案
- 數(shù)據(jù)可以良好的做到階段內(nèi)無丟失,且恢復(fù)速度較快,階段點數(shù)據(jù)恢復(fù)通常使用RDB方案
- 注意:利用RDB實現(xiàn)緊湊的數(shù)據(jù)持久化會使Redis性能降低
綜合對比
- RDB與AOF的選擇實際上是在做一種權(quán)衡,每種都有利弊
- 如果不能承受數(shù)分鐘以內(nèi)的數(shù)據(jù)丟失,對業(yè)務(wù)非常敏感,選用AOF
- 如果能接受數(shù)分鐘以內(nèi)的數(shù)據(jù)丟失,且追求大數(shù)據(jù)集的回復(fù)速度,選用RDB
- 災(zāi)難恢復(fù)選RDB
- 雙保險策略,同時開啟RDB與AOF,重啟后,Redis優(yōu)先使用AOF來恢復(fù)數(shù)據(jù),降低丟失數(shù)據(jù)的量
持久化應(yīng)用場景
- 應(yīng)用于搶購,限購類、限量發(fā)放優(yōu)惠卷、激活碼等業(yè)務(wù)的數(shù)據(jù)存儲設(shè)計
- 應(yīng)用于具有操作先后順序的數(shù)據(jù)控制
- 應(yīng)用于最新消息展示
- 應(yīng)用于基于黑名單與白名單設(shè)定的服務(wù)控制
- 應(yīng)用于計數(shù)器組合排序功能對應(yīng)的排名