前言
好記性不如爛筆頭墓卦,最近看了些關(guān)于redis持久化的文章掷贾,記一下筆記睛榄。
redis持久化方式
redis持久化有兩種方式,分別為RDB快照和AOF想帅。
快照
就是定時(shí)將內(nèi)存中的數(shù)據(jù)集快照寫(xiě)入磁盤(pán)场靴,實(shí)際操作是fork一個(gè)子進(jìn)程將文件寫(xiě)入到一個(gè)臨時(shí)文件,寫(xiě)入成功后港准,再替換掉原先的文件旨剥,用二進(jìn)制壓縮存儲(chǔ)。
AOF
將redis執(zhí)行過(guò)的所有數(shù)據(jù)操作指令(讀操作不記錄)浅缸,記錄到一個(gè)aof日志文件中轨帜,只可追加不可修改文件,當(dāng)啟動(dòng)redis時(shí)候衩椒,redis會(huì)讀取該aof配置文件蚌父,進(jìn)行數(shù)據(jù)操作。
redis持久化方式對(duì)應(yīng)優(yōu)缺點(diǎn)
快照
優(yōu)點(diǎn)
1毛萌、如果數(shù)據(jù)集較大苟弛,rdb的啟動(dòng)效率會(huì)更高,因?yàn)槲覀兛梢院芸彀褑渭兊囊粋€(gè)數(shù)據(jù)文件壓縮轉(zhuǎn)移到其他存儲(chǔ)介質(zhì)上阁将,而aof只是保存了指令膏秫,要從頭開(kāi)始執(zhí)行一遍,數(shù)據(jù)是不斷變化的做盅,所以aof比rdb恢復(fù)數(shù)據(jù)的速度要慢得多
2荔睹、適合備份數(shù)據(jù)
3狸演、性能最大化,fork出一個(gè)子進(jìn)程僻他,再由子進(jìn)程去進(jìn)行持久化的工作宵距,這樣就可以極大的避免服務(wù)進(jìn)程執(zhí)行IO操作缺點(diǎn)
1、定時(shí)存儲(chǔ)的原理吨拗,在宕機(jī)情況下满哪,會(huì)丟失還沒(méi)有來(lái)得及存儲(chǔ)的數(shù)據(jù),而丟失的多少和備份策略有關(guān)劝篷,例如:5分鐘備份一次哨鸭,但是第8分時(shí)宕機(jī)了,那么就丟失了后面的3分鐘數(shù)據(jù)娇妓。
2像鸡、fork子進(jìn)程的時(shí)候,如果數(shù)據(jù)量過(guò)大哈恰,那么可能會(huì)導(dǎo)致整個(gè)服務(wù)器停止服務(wù)只估。
AOF
優(yōu)點(diǎn):
1、就算宕機(jī)了着绷,啟動(dòng)腳本時(shí)只需要加載對(duì)應(yīng)的AOF文件進(jìn)行數(shù)據(jù)重建
2蛔钙、aof對(duì)于日志文件的寫(xiě)入執(zhí)行的是append操作,所以如果發(fā)生中斷荠医,也不會(huì)修改文件中已經(jīng)存在的記錄,如果是寫(xiě)了一半數(shù)據(jù)中斷了吁脱,也可以在Redis下一次啟動(dòng)之前,通過(guò)redis-check-aof工具來(lái)幫助我們解決數(shù)據(jù)一致性的問(wèn)題彬向。缺點(diǎn)
1兼贡、加載aof文件時(shí),帶來(lái)持續(xù)IO娃胆,redis可能會(huì)開(kāi)很久
2遍希、AOF 在過(guò)去曾經(jīng)發(fā)生過(guò)這樣的 bug : 因?yàn)閭€(gè)別命令的原因,導(dǎo)致 AOF 文件在重新載入時(shí)缕棵,無(wú)法將數(shù)據(jù)集恢復(fù)成保存時(shí)的原樣孵班。
3、相同數(shù)據(jù)集的情況下招驴,aof文件要比rdb大得多篙程,,因?yàn)閞db是直接保存了數(shù)據(jù)别厘,而aof只是保存了指令虱饿,要從頭開(kāi)始執(zhí)行一遍,數(shù)據(jù)是不斷變化的,所以aof比rdb恢復(fù)數(shù)據(jù)的速度要慢得多
選用哪種持久化方式氮发?
如果對(duì)于數(shù)據(jù)一致性有比較高的要求渴肉,則啟用aof,如果可以允許數(shù)據(jù)的少量丟失,并且對(duì)于備份要求比較多爽冕,可以采用rdb仇祭。
rdb可定時(shí)備份數(shù)據(jù),并且 RDB 恢復(fù)數(shù)據(jù)集的速度也要比 AOF 恢復(fù)的速度要快颈畸,還可以避免aof帶來(lái)的潛在bug乌奇。也可同時(shí)使用兩種方法。
優(yōu)化
1眯娱、 因?yàn)閞db文件只是用作后備用途礁苗,所以只建議在slave上持久化rdb文件,而且只要15分鐘備份一次徙缴,只保留save 900 1 規(guī)則
2试伙、如果啟用aof,aof 文件rewrite時(shí),將產(chǎn)生的新數(shù)據(jù)寫(xiě)到新文件造成的阻塞幾乎是不可避免的于样,只要硬盤(pán)許可疏叨,應(yīng)該盡量減少AOF rewrite頻率,可將auto-aof-rewrite-min-size即aof重寫(xiě)的閾值從默認(rèn)的64M改為5G,超過(guò)原大小100%這一比率auto-aof-rewrite-percentage 也可調(diào)整百宇。
3考廉、如果不啟用AOF 秘豹,僅靠Master-Slave Replication 實(shí)現(xiàn)高可用性也可以携御。能省掉一大筆IO也減少了rewrite時(shí)帶來(lái)的系統(tǒng)波動(dòng)。代價(jià)是如果Master/Slave同時(shí)倒掉既绕,會(huì)丟失十幾分鐘的數(shù)據(jù)啄刹,啟動(dòng)腳本也要比較兩個(gè)Master/Slave中的RDB文件,載入較新的那個(gè)凄贩。新浪微博就選用了這種架構(gòu)
持久化相關(guān)配置(Redis默認(rèn)為RDB模式,可以通過(guò)修改配置文件來(lái)打開(kāi) AOF 功能:appendonly yes)
RDB配置(可在配置文件中設(shè)置誓军,也可直接執(zhí)行命令)
1、直接執(zhí)行命令進(jìn)行數(shù)據(jù)回寫(xiě)分同步和異步兩種機(jī)制,分別對(duì)應(yīng)SAVE命令和BGSAVE命令
同步回寫(xiě)即SAVE命令疲扎,主進(jìn)程直接向磁盤(pán)回寫(xiě)數(shù)據(jù)昵时。在數(shù)據(jù)大的情況下會(huì)導(dǎo)致系統(tǒng)假死很長(zhǎng)時(shí)間,所以一般不是推薦的椒丧。
異步回寫(xiě)即BGSAVE命令壹甥,主進(jìn)程fork后,復(fù)制自身并通過(guò)這個(gè)新的進(jìn)程回寫(xiě)磁盤(pán)壶熏,回寫(xiě)結(jié)束后新進(jìn)程自行關(guān)閉句柠。由于這樣做不需要主進(jìn)程阻塞,系統(tǒng)不會(huì)假死,一般默認(rèn)會(huì)采用這個(gè)方法溯职。
注意:在小內(nèi)存的進(jìn)程上做一個(gè)fork,不需要太多資源精盅,但當(dāng)這個(gè)進(jìn)程的內(nèi)存空間以G為單位時(shí),fork就成為一件很恐怖的操作谜酒。假設(shè)在16G內(nèi)存的主機(jī)上fork 14G內(nèi)存的進(jìn)程叹俏,肯定會(huì)報(bào)內(nèi)存無(wú)法分配的。并且越是改動(dòng)頻繁的主機(jī)上fork也越頻繁僻族,所以可以通過(guò)設(shè)置vm.overcommit_memory她肯。
Linux內(nèi)核會(huì)根據(jù)參數(shù)vm.overcommit_memory參數(shù)的設(shè)置決定是否放行。
如果 vm.overcommit_memory = 1鹰贵,直接放行
vm.overcommit_memory = 0:則比較 此次請(qǐng)求分配的虛擬內(nèi)存大小和系統(tǒng)當(dāng)前空閑的物理內(nèi)存加上swap晴氨,決定是否放行。
vm.overcommit_memory = 2:則會(huì)比較 進(jìn)程所有已分配的虛擬內(nèi)存加上此次請(qǐng)求分配的虛擬內(nèi)存和系統(tǒng)當(dāng)前的空閑物理內(nèi)存加上swap碉输,決定是否放行籽前。
2、在Redis的配置文件中設(shè)置了多個(gè)save的選項(xiàng)配置
只要其中任一條滿(mǎn)足敷钾,Redis都會(huì)觸發(fā)一次BGSAVE操作枝哄,比如:900秒之內(nèi)至少一次寫(xiě)操作、300秒之內(nèi)至少發(fā)生10次寫(xiě)操作阻荒、60秒之內(nèi)發(fā)生至少10000次寫(xiě)操作都會(huì)觸發(fā)發(fā)生快照操作
語(yǔ)法:save <seconds> <changes>
解釋?zhuān)寒?dāng)在規(guī)定的時(shí)間內(nèi)挠锥,Redis發(fā)生了寫(xiě)操作的個(gè)數(shù)滿(mǎn)足條件,會(huì)觸發(fā)發(fā)生BGSAVE命令
save 900 1
save 300 10
save 60 10000
AOF配置
在Redis的配置文件中存在三種同步方式侨赡,它們分別是:
appendfsync always #每次有數(shù)據(jù)修改發(fā)生時(shí)都會(huì)寫(xiě)入AOF文件蓖租。
appendfsync everysec #每秒鐘同步一次,該策略為AOF的缺省策略羊壹。
appendfsync no #從不同步蓖宦。高效但是數(shù)據(jù)不會(huì)被持久化。
AOF的Rewrite(重寫(xiě))
定義:AOF采用文件追加的方式持久化數(shù)據(jù)油猫,所以文件會(huì)越來(lái)越大稠茂,為了避免這種情況發(fā)生,增加了重寫(xiě)機(jī)制情妖。
原理: 當(dāng)AOF文件的大小超過(guò)了配置所設(shè)置的闕值時(shí)睬关,Redis就會(huì)啟動(dòng)AOF文件壓縮,只保留可以恢復(fù)數(shù)據(jù)的最小指令集毡证,執(zhí)行 BGREWRITEAOF 命令电爹, Redis 將生成一個(gè)新的 AOF 文件, 這個(gè)文件包含重建當(dāng)前數(shù)據(jù)集所需的最少命令情竹。
具體解釋:當(dāng)AOF增長(zhǎng)過(guò)大時(shí)藐不,會(huì)fork出一條新的進(jìn)程將文件重寫(xiě)(也是先寫(xiě)臨時(shí)文件最后rename)匀哄,遍歷新進(jìn)程的內(nèi)存數(shù)據(jù),每條記錄有一條set語(yǔ)句雏蛮。重寫(xiě)AOF文件并沒(méi)有操作舊的AOF文件涎嚼,而是將整個(gè)內(nèi)存中的數(shù)據(jù)內(nèi)容用命令的方式重寫(xiě)了一個(gè)新的aof文件(有點(diǎn)類(lèi)似快照)
觸發(fā)機(jī)制:Redis會(huì)記錄上次重寫(xiě)時(shí)的AOF文件大小,默認(rèn)配置時(shí)當(dāng)AOF文件大小是上次rewrite后大小的一倍且文件大于64M時(shí)觸發(fā)挑秉。
數(shù)據(jù)恢復(fù)具體操作
1法梯、獲取備份目錄
redis 127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/usr/local/redis/bin"
以上命令 CONFIG GET dir 輸出的 redis 備份目錄為 /usr/local/redis/bin。
2犀概、停止redis服務(wù)
3立哑、拷貝備份文件到 /usr/local/redis/bin目錄下
4、重新啟動(dòng)redis服務(wù)
注意事項(xiàng)
1姻灶、當(dāng)Redis服務(wù)器重啟的時(shí)候铛绰,會(huì)自動(dòng)恢復(fù)數(shù)據(jù),RDB與AOF同時(shí)開(kāi)啟時(shí)产喉,優(yōu)先從AOF中恢復(fù)捂掰,其次才從RDB中恢復(fù),因?yàn)?AOF 文件所保存的數(shù)據(jù)通常是最完整的曾沈。
2这嚣、AOF運(yùn)行效率慢于RDB,但是同步策略效率(每秒同步一次)好,不同步效率和RDB相同
3塞俱、配置文件中姐帚,對(duì)于rdb持久化的策略,遵循從下往上匹配條件
4障涯、開(kāi)啟rdb情況下罐旗, 當(dāng)Redis通過(guò)shutdown命令關(guān)閉服務(wù)器請(qǐng)求時(shí),會(huì)執(zhí)行SAVE命令創(chuàng)建一個(gè)快照像樊,如果使用kill -9 PID將不會(huì)創(chuàng)建快照尤莺。
5旅敷、開(kāi)啟rdb情況下生棍,由于redis使用fork來(lái)復(fù)制一份當(dāng)前進(jìn)程,那么子進(jìn)程就會(huì)占有和主進(jìn)程一樣的內(nèi)存資源媳谁,比如說(shuō)主進(jìn)程8G內(nèi)存涂滴,那么在備份的時(shí)候必須保證有16G內(nèi)存,要不然會(huì)啟用虛擬內(nèi)存晴音,性能非常差柔纵。
參考文章
從Redis的數(shù)據(jù)丟失說(shuō)起
redis的持久化方式RDB和AOF的區(qū)別
Redis教程(十):持久化詳解
redis的 rdb 和 aof 持久化的區(qū)別
Redis實(shí)戰(zhàn)總結(jié)-配置、持久化锤躁、復(fù)制
持久化-RDB