探索Redis設(shè)計與實現(xiàn)11:使用快照和AOF將Redis數(shù)據(jù)持久化到硬盤中

本文轉(zhuǎn)自互聯(lián)網(wǎng)

本系列文章將整理到我在GitHub上的《Java面試指南》倉庫寂屏,更多精彩內(nèi)容請到我的倉庫里查看

https://github.com/h2pl/Java-Tutorial

喜歡的話麻煩點下Star哈

文章首發(fā)于我的個人博客:

www.how2playlife.com

本文是微信公眾號【Java技術(shù)江湖】的《探索Redis設(shè)計與實現(xiàn)》其中一篇灼狰,本文部分內(nèi)容來源于網(wǎng)絡(luò),為了把本文主題講得清晰透徹碑宴,也整合了很多我認為不錯的技術(shù)博客內(nèi)容,引用其中了一些比較好的博客文章旭等,如有侵權(quán)琅豆,請聯(lián)系作者。

該系列博文會告訴你如何從入門到進階允乐,Redis基本的使用方法矮嫉,Redis的基本數(shù)據(jù)結(jié)構(gòu),以及一些進階的使用方法牍疏,同時也需要進一步了解Redis的底層數(shù)據(jù)結(jié)構(gòu)蠢笋,再接著,還會帶來Redis主從復(fù)制鳞陨、集群昨寞、分布式鎖等方面的相關(guān)內(nèi)容,以及作為緩存的一些使用方法和注意事項厦滤,以便讓你更完整地了解整個Redis相關(guān)的技術(shù)體系援岩,形成自己的知識框架。

如果對本系列文章有什么建議掏导,或者是有什么疑問的話窄俏,也可以關(guān)注公眾號【Java技術(shù)江湖】聯(lián)系作者,歡迎你參與本系列博文的創(chuàng)作和修訂碘菜。

轉(zhuǎn)自https://blog.csdn.net/xlgen157387/article/details/61925524

前言

我們知道Redis是一款內(nèi)存服務(wù)器,就算我們對自己的服務(wù)器足夠的信任,不會出現(xiàn)任何軟件或者硬件的故障忍啸,但也會有可能出現(xiàn)突然斷電等情況仰坦,造成Redis服務(wù)器中的數(shù)據(jù)失效。因此计雌,我們需要向傳統(tǒng)的關(guān)系型數(shù)據(jù)庫一樣對數(shù)據(jù)進行備份悄晃,將Redis在內(nèi)存中的數(shù)據(jù)持久化到硬盤等非易失性介質(zhì)中,來保證數(shù)據(jù)的可靠性凿滤。

將Redis內(nèi)存服務(wù)器中的數(shù)據(jù)持久化到硬盤等介質(zhì)中的一個好處就是妈橄,使得我們的服務(wù)器在重啟之后還可以重用以前的數(shù)據(jù),或者是為了防止系統(tǒng)出現(xiàn)故障而將數(shù)據(jù)備份到一個遠程的位置翁脆。

還有一些場景眷蚓,例如:

對于一些需要進行大量計算而得到的數(shù)據(jù),放置在Redis服務(wù)器反番,我們就有必要對其進行數(shù)據(jù)的持久化沙热,如果需要對數(shù)據(jù)進行恢復(fù)的時候,我們就不需進行重新的計算罢缸,只需要簡單的將這臺機器上的數(shù)據(jù)復(fù)制到另一臺需要恢復(fù)的Redis服務(wù)器就可以了篙贸。

Redis給我們提供了兩種不同方式的持久化方法:快照(Snapshotting) 和 只追加文件(append-only-file)。

(1)名詞簡介

快照(RDB):就是我們俗稱的備份枫疆,他可以在定期內(nèi)對數(shù)據(jù)進行備份爵川,將Redis服務(wù)器中的數(shù)據(jù)持久化到硬盤中;

只追加文件(AOF):他會在執(zhí)行寫命令的時候息楔,將執(zhí)行的寫命令復(fù)制到硬盤里面寝贡,后期恢復(fù)的時候,只需要重新執(zhí)行一下這個寫命令就可以了钞螟。類似于我們的MySQL數(shù)據(jù)庫在進行主從復(fù)制的時候兔甘,使用的是binlog二進制文件,同樣的是執(zhí)行一遍寫命令鳞滨;

(2)快照持久化通用的配置:

save 60 1000  #60秒時間內(nèi)有1000次寫入操作的時候執(zhí)行快照的創(chuàng)建stop-writes-on-bgsave-error no  #創(chuàng)建快照失敗的時候是否仍然繼續(xù)執(zhí)行寫命令rdbcompression yes  #是否對快照文件進行壓縮dbfilename dump.rdb   #如何命名硬盤上的快照文件dir ./  #快照所保存的位置

(3)AOP持久化配置:

appendonly no  #是否使用AOF持久化appendfsync everysec  #多久執(zhí)行一次將寫入內(nèi)容同步到硬盤上no-appendfsync-on-rewrite no #對AOF進行壓縮的時候能否執(zhí)行同步操作auto-aof-rewrite-percentage 100  #多久執(zhí)行一次AOF壓縮auto-aof-rewrite-min-size 64mb  #多久執(zhí)行一次AOF壓縮dir ./ #AOF所保存的位置

需要注意的是:這兩種持久化的方式既可以單獨的使用洞焙,也可以同時使用,具體選擇哪種方式需要根據(jù)具體的情況進行選擇拯啦。

快照持久化

快照就是我們所說的備份澡匪。用戶可以將Redis內(nèi)存中的數(shù)據(jù)在某一個時間點進行備份,在創(chuàng)建快照之后褒链,用戶可以對快照進行備份唁情。通常情況下,為了防止單臺服務(wù)器出現(xiàn)故障造成所有數(shù)據(jù)的丟失甫匹,我們還可以將快照復(fù)制到其他服務(wù)器甸鸟,創(chuàng)建具有相同數(shù)據(jù)的數(shù)據(jù)副本惦费,這樣的話,數(shù)據(jù)恢復(fù)的時候或者服務(wù)器重啟的時候就可以使用這些快照信息進行數(shù)據(jù)的恢復(fù)抢韭,也可以防止單臺服務(wù)器出現(xiàn)故障的時候造成數(shù)據(jù)的丟失薪贫。

但是,沒我們還需要注意的是刻恭,創(chuàng)建快照的方式瞧省,并不能完全保證我們的數(shù)據(jù)不丟失,這個大家可以很好的理解鳍贾,因為快照的創(chuàng)建時定時的鞍匾,并不是每一次更新操作都會創(chuàng)建一個快照的。系統(tǒng)發(fā)生崩潰的時候骑科,用戶將丟失最近一次生成快照之后更改的所有數(shù)據(jù)橡淑。因此,快照持久化的方式只適合于數(shù)據(jù)不經(jīng)常修改或者丟失部分數(shù)據(jù)影響不大的場景纵散。

一梳码、創(chuàng)建快照的方式:

(1)客戶端通過向Redis發(fā)送BGSAVE 命令來創(chuàng)建快照。

使用BGSAVE的時候伍掀,Redis會調(diào)用fork來創(chuàng)建一個子進程掰茶,然后子進程負責(zé)將快照寫到硬盤中,而父進程則繼續(xù)處理命令請求蜜笤。

使用場景:

如果用戶使用了save設(shè)置濒蒋,例如:save 60 1000 ,那么從Redis最近一次創(chuàng)建快照之后開始計算,當(dāng)“60秒之內(nèi)有1000次寫入操作”這個條件滿足的時候把兔,Redis就會自動觸發(fā)BGSAVE命令沪伙。

如果用戶使用了多個save設(shè)置,那么當(dāng)任意一個save配置滿足條件的時候县好,Redis都會觸發(fā)一次BGSAVE命令围橡。

(2)客戶端通過向Redis發(fā)送SAVE 命令來創(chuàng)建快照。

接收到SAVE命令的Redis服務(wù)器在快照創(chuàng)建完畢之前將不再響應(yīng)任何其他命令的請求缕贡。SAVE命令并不常用翁授,我們通常只在沒有足夠的內(nèi)存去執(zhí)行BGSAVE命令的時候才會使用SAVE命令,或者即使等待持久化操作執(zhí)行完畢也無所謂的情況下晾咪,才會使用這個命令收擦;

使用場景:

當(dāng)Redis通過SHUTDOWN命令接收到關(guān)閉服務(wù)器的請求時,或者接收到標準的TERM信號時谍倦,會執(zhí)行一次SAVE命令塞赂,阻塞所有的客戶端,不再執(zhí)行客戶端發(fā)送的任何命令昼蛀,并且在執(zhí)行完SAVE命令之后關(guān)閉服務(wù)器宴猾。

二圆存、使用快照持久化注意事項:

我們在使用快照的方式來保存數(shù)據(jù)的時候,如果Redis服務(wù)器中的數(shù)據(jù)量比較小的話仇哆,例如只有幾個GB的時候辽剧。Redis會創(chuàng)建子進程并將數(shù)據(jù)保存到硬盤里邊,生成快照所需的時間比讀取數(shù)據(jù)所需要的時間還要短税产。

但是,隨著數(shù)據(jù)的增大偷崩,Redis占用的內(nèi)存越來越大的時候辟拷,BGSAVE在創(chuàng)建子進程的時候消耗的時間也會越來越多,如果Redis服務(wù)器所剩下的內(nèi)存不多的時候阐斜,這行BGSAVE命令會使得系統(tǒng)長時間地停頓衫冻,還有可能導(dǎo)致服務(wù)器無法使用。

各虛擬機類別谒出,創(chuàng)建子線程所耗時間:

這里寫圖片描述

因此隅俘,為了防止Redis因為創(chuàng)建子進程的時候出現(xiàn)停頓,我們可以考慮關(guān)閉自動保存笤喳,轉(zhuǎn)而通過手動的方式發(fā)送BGSAVE或者SAVE來進行持久化为居,

手動的方式發(fā)送BGSAVE也會出現(xiàn)停頓的現(xiàn)象,但是我們可以控制發(fā)送該命令的時間來控制出現(xiàn)停頓的時候不影響具體的業(yè)務(wù)請求杀狡。

另外蒙畴,值得注意的是,在使用SAVE命令的時候呜象,雖然會一直阻塞Redis直到快照生成完畢膳凝,但是其不需要創(chuàng)建子進程,所以不會向BGSAVE一樣恭陡,因為創(chuàng)建子進程而導(dǎo)致Redis停頓蹬音。也正因為如此,SAVE創(chuàng)建快照的速度要比BGSAVE創(chuàng)建快照的速度更快一些休玩。

創(chuàng)建快照的時候著淆,我們可以在業(yè)務(wù)請求,比較少的時候哥捕,比如凌晨三牧抽、四點,通過手寫腳本的方式遥赚,定時執(zhí)行扬舒。

AOF持久化

AOF持久化會將被執(zhí)行的寫命令寫到AOF文件的末尾,以此來記錄數(shù)據(jù)發(fā)生的變化凫佛。這樣讲坎,我們在恢復(fù)數(shù)據(jù)的時候孕惜,只需要從頭到尾的執(zhí)行一下AOF文件即可恢復(fù)數(shù)據(jù)。

一晨炕、打開AOF持久化選項

我們可以通過使用如下命令打開AOF:

appendonly yes

我們衫画,通過如下命令來配置AOF文件的同步頻率:

appendfsync everysec/always/no

二、appendfsync同步頻率的區(qū)別

appendfsync同步頻率的區(qū)別如下圖:

這里寫圖片描述

(1)always的方式固然可以對沒一條數(shù)據(jù)進行很好的保存瓮栗,但是這種同步策略需要對硬盤進行大量的寫操作削罩,所以Redis處理命令的速度會受到硬盤性能的限制。

普通的硬盤每秒鐘只能處理大約200個寫命令费奸,使用固態(tài)硬盤SSD每秒可以處理幾萬個寫命令弥激,但是每次只寫一個命令,這種只能怪不斷地寫入很少量的數(shù)據(jù)的做法有可能引發(fā)嚴重的寫入放大問題愿阐,這種情況下降嚴重影響固態(tài)硬盤的使用壽命微服。

(2)everysec的方式,Redis以每秒一次的頻率大隊AOF文件進行同步缨历。這樣的話既可以兼顧數(shù)據(jù)安全也可以兼顧寫入性能以蕴。

Redis以每秒同步一次AOF文件的性能和不使用任何持久化特性時的性能相差無幾,使用每秒更新一次 的方式辛孵,可以保證丛肮,即使出現(xiàn)故障,丟失的數(shù)據(jù)也在一秒之內(nèi)產(chǎn)生的數(shù)據(jù)觉吭。

(3)no的方式腾供,Redis將不對AOF文件執(zhí)行任何顯示的同步操作,而是由操作系統(tǒng)來決定應(yīng)該何時對AOF文件進行同步鲜滩。

這個命令一般不會對Redis的性能造成多大的影響伴鳖,但是當(dāng)系統(tǒng)出現(xiàn)故障的時候使用這種選項的Redis服務(wù)器丟失不定數(shù)量的數(shù)據(jù)。

另外徙硅,當(dāng)用戶的硬盤處理寫入操作的速度不夠快的話榜聂,那么緩沖區(qū)被等待寫入硬盤的數(shù)據(jù)填滿時,Redis的寫入操作將被阻塞嗓蘑,并導(dǎo)致Redis處理命令請求的速度變慢须肆,因為這個原因,一般不推薦使用這個選項桩皿。

三豌汇、重寫/壓縮AOF文件

隨著數(shù)據(jù)量的增大,AOF的文件可能會很大泄隔,這樣在每次進行數(shù)據(jù)恢復(fù)的時候就會進行很長的時間拒贱,為了解決日益增大的AOF文件,用戶可以向Redis發(fā)送BGREWRITEAOF 命令,這個命令會通過移除AOF文件中的冗余命令來重寫AOF文件逻澳,是AOF文件的體檢變得盡可能的小闸天。

BGREWRITEAOF的工作原理和BGSAVE的原理很像:Redis會創(chuàng)建一個子進程,然后由子進程負責(zé)對AOF文件的重寫操作斜做。

因為AOF文件重寫的時候匯創(chuàng)建子進程苞氮,所以快照持久化因為創(chuàng)建子進程而導(dǎo)致的性能和內(nèi)存占用問題同樣會出現(xiàn)在AOF文件重寫的 時候。

四瓤逼、觸發(fā)重寫/壓縮AOF文件條件設(shè)定

AOF通過設(shè)置auto-aof-rewrite-percentageauto-aof-rewrite-min-size 選項來自動執(zhí)行BGREWRITEAOF笼吟。

其具體含義,通過實例可以看出霸旗,如下配置:

auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb

表示當(dāng)前AOF的文件體積大于64MB赞厕,并且AOF文件的體積比上一次重寫之后的體積變大了至少一倍(100%)的時候,Redis將執(zhí)行重寫B(tài)GREWRITEAOF命令定硝。

如果AOF重寫執(zhí)行的過于頻繁的話,可以將auto-aof-rewrite-percentage 選項的值設(shè)置為100以上毫目,這種最偶發(fā)就可以讓Redis在AOF文件的體積變得更大之后才執(zhí)行重寫操作蔬啡,不過,這也使得在進行數(shù)據(jù)恢復(fù)的時候執(zhí)行的時間變得更加長一些镀虐。

驗證快照文件和AOF文件

無論使用哪種方式進行持久化箱蟆,我們在進行恢復(fù)數(shù)據(jù)的時候,Redis提供了兩個命令行程序:

redis-check-aofredis-check-dump

他們可以再系統(tǒng)發(fā)生故障的時候刮便,檢查快照和AOF文件的狀態(tài)空猜,并對有需要的情況對文件進行修復(fù)。

如果用戶在運行redis-check-aof命令的時候恨旱,指定了--fix 參數(shù)辈毯,那么程序?qū)OF文件進行修復(fù)。

程序修復(fù)AOF文件的方法很簡單:他會掃描給定的AOF文件搜贤,尋找不正確或者不完整的命令谆沃,當(dāng)發(fā)現(xiàn)第一個出現(xiàn)錯誤命令的時候,程序會刪除出錯命令以及出錯命令之后的所有命令仪芒,只保留那些位于出錯命令之前的正確命令唁影。大部分情況,被刪除的都是AOF文件末尾的不完整的寫命令掂名。

總結(jié)

上述据沈,一起學(xué)習(xí)了兩種支持持久化的方式,一方面我們需要通過快照或者AOF的方式對數(shù)據(jù)進行持久化饺蔑,另一方面锌介,我們還需要將持久化所得到的文件進行備份,備份到不同的服務(wù)器上膀钠,這樣才可以盡可能的減少數(shù)據(jù)丟失的損失掏湾。


參考文章:

1裹虫、Redis in Action - [美] Josiah L.Carlsono

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市融击,隨后出現(xiàn)的幾起案子筑公,更是在濱河造成了極大的恐慌,老刑警劉巖尊浪,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件匣屡,死亡現(xiàn)場離奇詭異,居然都是意外死亡拇涤,警方通過查閱死者的電腦和手機捣作,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鹅士,“玉大人券躁,你說我怎么就攤上這事〉糁眩” “怎么了也拜?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長趾痘。 經(jīng)常有香客問我慢哈,道長,這世上最難降的妖魔是什么永票? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任卵贱,我火速辦了婚禮,結(jié)果婚禮上侣集,老公的妹妹穿的比我還像新娘键俱。我一直安慰自己,他們只是感情好世分,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布方妖。 她就那樣靜靜地躺著,像睡著了一般罚攀。 火紅的嫁衣襯著肌膚如雪党觅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天斋泄,我揣著相機與錄音杯瞻,去河邊找鬼。 笑死炫掐,一個胖子當(dāng)著我的面吹牛魁莉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼旗唁,長吁一口氣:“原來是場噩夢啊……” “哼畦浓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起检疫,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤讶请,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后屎媳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夺溢,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年烛谊,在試婚紗的時候發(fā)現(xiàn)自己被綠了风响。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡丹禀,死狀恐怖状勤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情双泪,我是刑警寧澤荧降,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站攒读,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏辛友。R本人自食惡果不足惜薄扁,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望废累。 院中可真熱鬧念赶,春花似錦违崇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至捕发,卻和暖如春庙楚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背哎壳。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工毅待, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人归榕。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓尸红,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子外里,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容