9.Redis混合持久化你不會(huì)沒(méi)聽(tīng)說(shuō)過(guò)吧蛆挫?(高頻面試題)

Redis持久化機(jī)制

Redis 的數(shù)據(jù)全部在內(nèi)存里坏逢,如果突然宕機(jī)域帐,數(shù)據(jù)就會(huì)全部丟失,因此必須有一種機(jī)制來(lái)保證 Redis 的數(shù)據(jù)不會(huì)因?yàn)楣收隙鴣G失是整,這種機(jī)制就是 Redis 的持久化機(jī)制肖揣。

什么是持久化?
就是把內(nèi)存里的數(shù)據(jù)保存到硬盤(pán)上浮入。

必須使用數(shù)據(jù)持久化嗎?
Redis的數(shù)據(jù)持久化機(jī)制是可以關(guān)閉的龙优。如果你只把Redis作為緩存服務(wù)使用,Redis中存儲(chǔ)的所有數(shù)據(jù)都不是該數(shù)據(jù)的主體而僅僅是同步過(guò)來(lái)的備份事秀,那么可以關(guān)閉Redis的數(shù)據(jù)持久化機(jī)制彤断。

但通常來(lái)說(shuō),仍然建議至少開(kāi)啟RDB方式的數(shù)據(jù)持久化易迹,因?yàn)椋?br> ①數(shù)據(jù)量不是非常大時(shí)宰衙,RDB方式的持久化幾乎不損耗Redis本身的性能,因?yàn)镽edis父進(jìn)程持久化時(shí)只需要fork一個(gè)子進(jìn)程睹欲,這個(gè)子進(jìn)程可以共享主進(jìn)程的所有內(nèi)存數(shù)據(jù)供炼,子進(jìn)程會(huì)去讀取主進(jìn)程的內(nèi)存數(shù)據(jù)一屋,并把它們寫(xiě)入RDB文件。
②Redis無(wú)論因?yàn)槭裁丛虬l(fā)送故障袋哼,重啟時(shí)能夠自動(dòng)恢復(fù)到上一次RDB快照中記錄的數(shù)據(jù)(自動(dòng)加載RDB文件)冀墨。這省去了手工從其他數(shù)據(jù)源(如數(shù)據(jù)庫(kù))同步數(shù)據(jù)的過(guò)程,而且要比其他任何的數(shù)據(jù)恢復(fù)方式都要快先嬉。
③服務(wù)器的硬盤(pán)都是T級(jí)別的轧苫,幾個(gè)G的數(shù)據(jù)影響忽略不計(jì)楚堤。

Redis 不同于 Memcached 的很重要一點(diǎn)就是疫蔓,Redis 支持持久化,而且支持三種不同的持久化策略身冬。

1.RDB

Redis提供了兩個(gè)命令來(lái)生成 RDB 文件:

  • save:在主進(jìn)程中執(zhí)行衅胀,會(huì)導(dǎo)致寫(xiě)請(qǐng)求阻塞。
  • bgsave:fork一個(gè)子進(jìn)程酥筝,專(zhuān)門(mén)用于寫(xiě)入 RDB 文件滚躯,避免了主進(jìn)程的阻塞。

為了快照而阻塞寫(xiě)請(qǐng)求嘿歌,這是系統(tǒng)無(wú)法接受的掸掏,因此Redis借助操作系統(tǒng)提供的寫(xiě)時(shí)復(fù)制技術(shù)(Copy-On-Write, COW),在執(zhí)行快照的同時(shí)宙帝,正常處理寫(xiě)操作丧凤。

Redis在執(zhí)行持久化時(shí),會(huì)fork出一個(gè)bgsave子進(jìn)程步脓,這個(gè)子進(jìn)程可以共享主進(jìn)程的所有內(nèi)存數(shù)據(jù)愿待,bgsave子進(jìn)程運(yùn)行后,會(huì)去讀取主進(jìn)程的內(nèi)存數(shù)據(jù)靴患,并把它們寫(xiě)入RDB文件仍侥。

有小伙伴問(wèn),為什么要fork一個(gè)子線程鸳君?
redis是單線程程序农渊,若單線程同時(shí)在服務(wù)線上的請(qǐng)求還需要進(jìn)行文件IO操作,這不僅影響性能而且還會(huì)阻塞線上業(yè)務(wù)或颊,因此這里主進(jìn)程fork出一個(gè)進(jìn)程砸紊,fork出的這個(gè)進(jìn)程去完成快照操作。

快照持久化是 Redis 默認(rèn)采用的持久化方式饭宾,我們可以根據(jù)業(yè)務(wù)需求配置下面參數(shù):

save 900 1    #每900秒(15分鐘)至少有1個(gè)key發(fā)生變化批糟,Redis就會(huì)自動(dòng)觸發(fā)BGSAVE命令創(chuàng)建快照。

save 300 10   #每300秒(5分鐘)至少有10個(gè)key發(fā)生變化看铆,Redis就會(huì)自動(dòng)觸發(fā)BGSAVE命令創(chuàng)建快照徽鼎。

save 60 10000 #每60秒(1分鐘)至少有10000個(gè)key發(fā)生變化,Redis就會(huì)自動(dòng)觸發(fā)BGSAVE命令創(chuàng)建快照。

key發(fā)生變化(key數(shù)據(jù)添加否淤、修改悄但、刪除)

觸發(fā)快照的幾種方式:
①服務(wù)器正常關(guān)閉時(shí),會(huì)照一次快照 ./bin/redis-cli shutdown
②key滿(mǎn)足一定條件石抡,會(huì)照一次快照(通過(guò)上述Redis.conf配置)
③通過(guò)BGSAVE命令(在redis中執(zhí)行)手動(dòng)觸發(fā)RDB快照保存

優(yōu)點(diǎn):
①RDB文件緊湊檐嚣,體積小,網(wǎng)絡(luò)傳輸快啰扛,適合全量復(fù)制嚎京。
②與AOF方式相比,通過(guò)RDB文件恢復(fù)數(shù)據(jù)比較快更快隐解。
③RDB最大化了Redis的性能鞍帝,因?yàn)镽edis父進(jìn)程持久化時(shí)只需要fork一個(gè)子進(jìn)程,這個(gè)子進(jìn)程可以共享主進(jìn)程的所有內(nèi)存數(shù)據(jù)煞茫,子進(jìn)程會(huì)去讀取主進(jìn)程的內(nèi)存數(shù)據(jù)帕涌,并把它們寫(xiě)入RDB文件。

缺點(diǎn):
①快照是定期生成的续徽,所有在 Redis 故障時(shí)或多或少會(huì)丟失一部分?jǐn)?shù)據(jù)蚓曼。
②當(dāng)數(shù)據(jù)量比較大時(shí),fork 的過(guò)程是非常耗時(shí)的钦扭,fork 子進(jìn)程時(shí)是會(huì)阻塞的纫版,在這期間 Redis 是不能響應(yīng)客戶(hù)端的請(qǐng)求的。

2.AOF

Redis會(huì)把每一個(gè)寫(xiě)請(qǐng)求都記錄在一個(gè)日志文件里土全,在Redis重啟時(shí)捎琐,會(huì)把AOF文件中記錄的所有寫(xiě)操作順序執(zhí)行一遍,確保數(shù)據(jù)恢復(fù)到最新裹匙。

Redis 會(huì)在收到客戶(hù)端修改指令后瑞凑,先進(jìn)行參數(shù)校驗(yàn),如果沒(méi)問(wèn)題概页,就立即將該指令文本存儲(chǔ)到 AOF 日志中籽御,也就是先存到磁盤(pán),然后再執(zhí)行指令惰匙。這樣即使遇到突發(fā)宕機(jī)技掏,已經(jīng)存儲(chǔ)到 AOF 日志的指令進(jìn)行重放一下就可以恢復(fù)到宕機(jī)前的狀態(tài)。

日志文件太大怎么辦项鬼?
AOF 日志在長(zhǎng)期的運(yùn)行過(guò)程中會(huì)變的很大哑梳,Redis重啟時(shí)需要加載 AOF 日志進(jìn)行指令重放,此時(shí)這個(gè)過(guò)程就會(huì)非常耗時(shí)绘盟。 所以需要定期進(jìn)行AOF 重寫(xiě)鸠真,給 AOF 日志進(jìn)行瘦身悯仙。

AOF如何重寫(xiě)?
Redis 提供了 bgrewriteaof 指令用于對(duì) AOF 日志進(jìn)行瘦身吠卷。每次執(zhí)行重寫(xiě)時(shí)锡垄,主進(jìn)程 fork 出一個(gè)bgrewriteaof 子進(jìn)程,會(huì)把主進(jìn)程的內(nèi)存拷貝一份給 bgrewriteaof 子進(jìn)程祭隔,對(duì)內(nèi)存進(jìn)行遍歷轉(zhuǎn)換成一系列 Redis 的操作指令货岭,序列化到一個(gè)新的 AOF 日志文件中。序列化完畢后再將操作期間發(fā)生的增量 AOF 日志追加到這個(gè)新的 AOF 日志文件中疾渴,追加完畢后就立即替代舊的 AOF 日志文件了千贯,瘦身工作就完成了。

Redis提供了AOF rewrite功能程奠,可以重寫(xiě)AOF文件丈牢,只保留能夠把數(shù)據(jù)恢復(fù)到最新?tīng)顟B(tài)的最小寫(xiě)操作集。

AOF 重寫(xiě)可以通過(guò)bgrewriteaof命令(在redis里執(zhí)行)觸發(fā)瞄沙,也可以配置Redis定期自動(dòng)進(jìn)行:

## Redis在每次AOF rewrite時(shí),會(huì)記錄完成rewrite后的AOF日志大小慌核,當(dāng)AOF日志大小在該基礎(chǔ)上增長(zhǎng)了100%后距境,自動(dòng)進(jìn)行AOF rewrite。同時(shí)如果增長(zhǎng)的大小沒(méi)有達(dá)到64mb垮卓,則不會(huì)進(jìn)行rewrite垫桂。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

AOF默認(rèn)是關(guān)閉的,如果需要開(kāi)啟粟按,需要在redis.conf配置文件中配置:

appendonly  yes

AOF提供三種fsync配置诬滩,always/everysec/no,通過(guò)配置項(xiàng)appendfsync指定灭将,默認(rèn)是everysec疼鸟。

appendfsync always    # 每寫(xiě)入一條日志就進(jìn)行一次fsync操作,數(shù)據(jù)安全性最高庙曙,但速度最慢(每次有數(shù)據(jù)修改發(fā)生時(shí)都會(huì)寫(xiě)入AOF文)
appendfsync everysec  # 折中的做法空镜,交由后臺(tái)線程每秒fsync一次(每秒鐘同步一次,該策略為AOF的缺省策略)
appendfsync no        # 不進(jìn)行fsync捌朴,將flush文件的時(shí)機(jī)交給OS決定吴攒,速度最快(從不同步。高效但是數(shù)據(jù)不會(huì)被持久化)

優(yōu)點(diǎn):
①數(shù)據(jù)安全性高砂蔽,可以根據(jù)業(yè)務(wù)需求配置fsync策略
②AOF文件易讀洼怔,可修改,在進(jìn)行了某些錯(cuò)誤的數(shù)據(jù)清除操作后左驾,只要AOF文件沒(méi)有rewrite镣隶,就可以把AOF文件備份出來(lái)泽台,把錯(cuò)誤命令刪除,然后恢復(fù)數(shù)據(jù)

缺點(diǎn):
①AOF方式生成的日志文件太大矾缓,即使通過(guò)AFO重寫(xiě)怀酷,文件體積仍然很大
②數(shù)據(jù)恢復(fù)速度比RDB慢

3.混合持久化

如果我們采用 RDB 持久化會(huì)丟失一段時(shí)間數(shù)據(jù)。如果我們采用 AOF 持久化嗜闻,AOF日志較大蜕依,重放比較慢。

Redis 4.0 為了解決這個(gè)問(wèn)題琉雳,支持混合持久化样眠。將 RDB 文件的內(nèi)容和增量的 AOF 日志文件存在一起。

混合持久化同樣也是通過(guò) bgrewriteaof 完成的翠肘,不同的是當(dāng)開(kāi)啟混合持久化時(shí)檐束,fork出的子進(jìn)程先將共享的內(nèi)存副本全量的以 RDB 方式寫(xiě)入 AOF 文件,然后在將重寫(xiě)緩沖區(qū)的增量命令以 AOF 方式寫(xiě)入到文件束倍,寫(xiě)入完成后通知主進(jìn)程更新統(tǒng)計(jì)信息被丧,并將新的含有RDB格式和 AOF 格式的 AOF 文件替換舊的的 AOF 文件。簡(jiǎn)單的說(shuō):新的AOF文件前半段是RDB格式的全量數(shù)據(jù)后半段是AOF格式的增量數(shù)據(jù)绪妹。

于是在 Redis 重啟的時(shí)候甥桂,可以先加載 rdb 的內(nèi)容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放邮旷,重啟效率因此大幅得到提升黄选。

4.實(shí)戰(zhàn)經(jīng)驗(yàn)

快照需要fork子進(jìn)程的方式進(jìn)行的,它是一個(gè)比較耗資源的操作婶肩。(當(dāng)數(shù)據(jù)量非常大時(shí)办陷,fork會(huì)很耗時(shí),需要大概幾百毫秒甚至1秒律歼,fork時(shí)父進(jìn)程是阻塞的民镜,不能正常服務(wù)redis讀寫(xiě)請(qǐng)求)

AOF 的 fsync 是一個(gè)耗時(shí)的 IO 操作,它會(huì)降低 Redis 性能苗膝,同時(shí)也會(huì)增加系統(tǒng) IO 負(fù)擔(dān)

所以通常 Redis 的主節(jié)點(diǎn)是不會(huì)進(jìn)行持久化操作殃恒,持久化操作主要在從節(jié)點(diǎn)進(jìn)行。從節(jié)點(diǎn)是備份節(jié)點(diǎn)辱揭,沒(méi)有來(lái)自客戶(hù)端請(qǐng)求的壓力离唐,它的操作系統(tǒng)資源往往比較充沛。

但是如果出現(xiàn)網(wǎng)絡(luò)分區(qū)问窃,從節(jié)點(diǎn)長(zhǎng)期連不上主節(jié)點(diǎn)亥鬓,就會(huì)出現(xiàn)數(shù)據(jù)不一致的問(wèn)題,特別是在網(wǎng)絡(luò)分區(qū)出現(xiàn)的情況下又不小心主節(jié)點(diǎn)宕機(jī)了域庇,那么數(shù)據(jù)就會(huì)丟失嵌戈,所以在生產(chǎn)環(huán)境要做好實(shí)時(shí)監(jiān)控工作覆积,保證網(wǎng)絡(luò)暢通或者能快速修復(fù)。另外還應(yīng)該再增加一個(gè)從節(jié)點(diǎn)以降低網(wǎng)絡(luò)分區(qū)的概率熟呛,只要有一個(gè)從節(jié)點(diǎn)數(shù)據(jù)同步正常宽档,數(shù)據(jù)也就不會(huì)輕易丟失。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末庵朝,一起剝皮案震驚了整個(gè)濱河市吗冤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌九府,老刑警劉巖椎瘟,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異侄旬,居然都是意外死亡肺蔚,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)儡羔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)宣羊,“玉大人,你說(shuō)我怎么就攤上這事笔链《沃唬” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵鉴扫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我澈缺,道長(zhǎng)坪创,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任姐赡,我火速辦了婚禮莱预,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘项滑。我一直安慰自己依沮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布枪狂。 她就那樣靜靜地躺著危喉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪州疾。 梳的紋絲不亂的頭發(fā)上辜限,一...
    開(kāi)封第一講書(shū)人閱讀 51,443評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音严蓖,去河邊找鬼薄嫡。 笑死氧急,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的毫深。 我是一名探鬼主播吩坝,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼哑蔫!你這毒婦竟也來(lái)了钉寝?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鸳址,失蹤者是張志新(化名)和其女友劉穎瘩蚪,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體稿黍,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疹瘦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了巡球。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片言沐。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖酣栈,靈堂內(nèi)的尸體忽然破棺而出险胰,到底是詐尸還是另有隱情,我是刑警寧澤矿筝,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布起便,位于F島的核電站,受9級(jí)特大地震影響窖维,放射性物質(zhì)發(fā)生泄漏榆综。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一铸史、第九天 我趴在偏房一處隱蔽的房頂上張望鼻疮。 院中可真熱鬧,春花似錦琳轿、人聲如沸判沟。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)挪哄。三九已至,卻和暖如春媚送,著一層夾襖步出監(jiān)牢的瞬間中燥,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工塘偎, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疗涉,地道東北人拿霉。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像咱扣,于是被迫代替她去往敵國(guó)和親绽淘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

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