redis提供了兩種持久化的方式缸榛,分別是RDB(Redis DataBase)和AOF(Append Only File)吝羞。
RDB,簡(jiǎn)而言之仔掸,就是在不同的時(shí)間點(diǎn)脆贵,將redis存儲(chǔ)的數(shù)據(jù)生成快照并存儲(chǔ)到磁盤等介質(zhì)上;
AOF起暮,則是換了一個(gè)角度來(lái)實(shí)現(xiàn)持久化卖氨,那就是將redis執(zhí)行過(guò)的所有寫指令記錄下來(lái),在下次redis重新啟動(dòng)時(shí)负懦,只要把這些寫指令從前到后再重復(fù)執(zhí)行一遍筒捺,就可以實(shí)現(xiàn)數(shù)據(jù)恢復(fù)了。
其實(shí)RDB和AOF兩種方式也可以同時(shí)使用纸厉,在這種情況下系吭,如果redis重啟的話,則會(huì)優(yōu)先采用AOF方式來(lái)進(jìn)行數(shù)據(jù)恢復(fù)颗品,這是因?yàn)锳OF方式的數(shù)據(jù)恢復(fù)完整度更高肯尺。
如果你沒(méi)有數(shù)據(jù)持久化的需求,也完全可以關(guān)閉RDB和AOF方式躯枢,這樣的話则吟,redis將變成一個(gè)純內(nèi)存數(shù)據(jù)庫(kù),就像memcache一樣锄蹂。
【聊聊redis持久化 – RDB】
RDB方式氓仲,是將redis某一時(shí)刻的數(shù)據(jù)持久化到磁盤中,是一種快照式的持久化方法得糜。
redis在進(jìn)行數(shù)據(jù)持久化的過(guò)程中敬扛,會(huì)先將數(shù)據(jù)寫入到一個(gè)臨時(shí)文件中,待持久化過(guò)程都結(jié)束了朝抖,才會(huì)用這個(gè)臨時(shí)文件替換上次持久化好的文件啥箭。正是這種特性,讓我們可以隨時(shí)來(lái)進(jìn)行備份治宣,因?yàn)榭煺瘴募偸峭暾捎玫摹?/p>
對(duì)于RDB方式捉蚤,redis會(huì)單獨(dú)創(chuàng)建(fork)一個(gè)子進(jìn)程來(lái)進(jìn)行持久化抬驴,而主進(jìn)程是不會(huì)進(jìn)行任何IO操作的炼七,這樣就確保了redis極高的性能缆巧。
如果需要進(jìn)行大規(guī)模數(shù)據(jù)的恢復(fù),且對(duì)于數(shù)據(jù)恢復(fù)的完整性不是非常敏感豌拙,那RDB方式要比AOF方式更加的高效陕悬。
雖然RDB有不少優(yōu)點(diǎn),但它的缺點(diǎn)也是不容忽視的按傅。如果你對(duì)數(shù)據(jù)的完整性非常敏感捉超,那么RDB方式就不太適合你,因?yàn)榧词鼓忝?分鐘都持久化一次唯绍,當(dāng)redis故障時(shí)拼岳,仍然會(huì)有近5分鐘的數(shù)據(jù)丟失。所以况芒,redis還提供了另一種持久化方式惜纸,那就是AOF。
【聊聊redis持久化 – AOF】
AOF绝骚,英文是Append Only File耐版,即只允許追加不允許改寫的文件。
如前面介紹的压汪,AOF方式是將執(zhí)行過(guò)的寫指令記錄下來(lái)粪牲,在數(shù)據(jù)恢復(fù)時(shí)按照從前到后的順序再將指令都執(zhí)行一遍,就這么簡(jiǎn)單止剖。
我們通過(guò)配置redis.conf中的appendonly yes就可以打開AOF功能腺阳。如果有寫操作(如SET等),redis就會(huì)被追加到AOF文件的末尾穿香。
默認(rèn)的AOF持久化策略是每秒鐘fsync一次(fsync是指把緩存中的寫指令記錄到磁盤中)亭引,因?yàn)樵谶@種情況下,redis仍然可以保持很好的處理性能扔水,即使redis故障痛侍,也只會(huì)丟失最近1秒鐘的數(shù)據(jù)。
如果在追加日志時(shí)魔市,恰好遇到磁盤空間滿主届、inode滿或斷電等情況導(dǎo)致日志寫入不完整,也沒(méi)有關(guān)系待德,redis提供了redis-check-aof工具君丁,可以用來(lái)進(jìn)行日志修復(fù)。
因?yàn)椴捎昧俗芳臃绞浇埽绻蛔鋈魏翁幚淼脑捇婷疲珹OF文件會(huì)變得越來(lái)越大橡庞,為此,redis提供了AOF文件重寫(rewrite)機(jī)制印蔗,即當(dāng)AOF文件的大小超過(guò)所設(shè)定的閾值時(shí)扒最,redis就會(huì)啟動(dòng)AOF文件的內(nèi)容壓縮,只保留可以恢復(fù)數(shù)據(jù)的最小指令集华嘹。舉個(gè)例子或許更形象吧趣,假如我們調(diào)用了100次INCR指令,在AOF文件中就要存儲(chǔ)100條指令耙厚,但這明顯是很低效的强挫,完全可以把這100條指令合并成一條SET指令,這就是重寫機(jī)制的原理薛躬。
在進(jìn)行AOF重寫時(shí)俯渤,仍然是采用先寫臨時(shí)文件,全部完成后再替換的流程型宝,所以斷電八匠、磁盤滿等問(wèn)題都不會(huì)影響AOF文件的可用性,這點(diǎn)大家可以放心诡曙。
AOF方式的另一個(gè)好處臀叙,我們通過(guò)一個(gè)“場(chǎng)景再現(xiàn)”來(lái)說(shuō)明。某同學(xué)在操作redis時(shí)价卤,不小心執(zhí)行了FLUSHALL劝萤,導(dǎo)致redis內(nèi)存中的數(shù)據(jù)全部被清空了,這是很悲劇的事情慎璧。不過(guò)這也不是世界末日床嫌,只要redis配置了AOF持久化方式,且AOF文件還沒(méi)有被重寫(rewrite)胸私,我們就可以用最快的速度暫停redis并編輯AOF文件厌处,將最后一行的FLUSHALL命令刪除,然后重啟redis岁疼,就可以恢復(fù)redis的所有數(shù)據(jù)到FLUSHALL之前的狀態(tài)了阔涉。是不是很神奇,這就是AOF持久化方式的好處之一捷绒。但是如果AOF文件已經(jīng)被重寫了瑰排,那就無(wú)法通過(guò)這種方法來(lái)恢復(fù)數(shù)據(jù)了。
雖然優(yōu)點(diǎn)多多暖侨,但AOF方式也同樣存在缺陷椭住,比如在同樣數(shù)據(jù)規(guī)模的情況下,AOF文件要比RDB文件的體積大字逗。而且京郑,AOF方式的恢復(fù)速度也要慢于RDB方式宅广。
如果你直接執(zhí)行BGREWRITEAOF命令,那么redis會(huì)生成一個(gè)全新的AOF文件些举,其中便包括了可以恢復(fù)現(xiàn)有數(shù)據(jù)的最少的命令集跟狱。
如果運(yùn)氣比較差,AOF文件出現(xiàn)了被寫壞的情況金拒,也不必過(guò)分擔(dān)憂兽肤,redis并不會(huì)貿(mào)然加載這個(gè)有問(wèn)題的AOF文件,而是報(bào)錯(cuò)退出绪抛。這時(shí)可以通過(guò)以下步驟來(lái)修復(fù)出錯(cuò)的文件:
1.備份被寫壞的AOF文件
2.運(yùn)行redis-check-aof –fix進(jìn)行修復(fù)
3.用diff -u來(lái)看下兩個(gè)文件的差異,確認(rèn)問(wèn)題點(diǎn)
4.重啟redis电禀,加載修復(fù)后的AOF文件
【聊聊redis持久化 – AOF重寫】
AOF重寫的內(nèi)部運(yùn)行原理幢码,我們有必要了解一下。
在重寫即將開始之際尖飞,redis會(huì)創(chuàng)建(fork)一個(gè)“重寫子進(jìn)程”症副,這個(gè)子進(jìn)程會(huì)首先讀取現(xiàn)有的AOF文件,并將其包含的指令進(jìn)行分析壓縮并寫入到一個(gè)臨時(shí)文件中政基。
與此同時(shí)贞铣,主工作進(jìn)程會(huì)將新接收到的寫指令一邊累積到內(nèi)存緩沖區(qū)中,一邊繼續(xù)寫入到原有的AOF文件中沮明,這樣做是保證原有的AOF文件的可用性辕坝,避免在重寫過(guò)程中出現(xiàn)意外。
當(dāng)“重寫子進(jìn)程”完成重寫工作后荐健,它會(huì)給父進(jìn)程發(fā)一個(gè)信號(hào)酱畅,父進(jìn)程收到信號(hào)后就會(huì)將內(nèi)存中緩存的寫指令追加到新AOF文件中。
當(dāng)追加結(jié)束后江场,redis就會(huì)用新AOF文件來(lái)代替舊AOF文件纺酸,之后再有新的寫指令,就都會(huì)追加到新的AOF文件中了址否。
【聊聊redis持久化 – 如何選擇RDB和AOF】
對(duì)于我們應(yīng)該選擇RDB還是AOF餐蔬,官方的建議是兩個(gè)同時(shí)使用。這樣可以提供更可靠的持久化方案佑附。