引言
(本文改編自生活真實(shí)案例,如有類同,絕不是巧合!)
端午節(jié),煙哥正在一邊愉快的學(xué)習(xí)....
突然,微信一陣抖動(dòng)。原來(lái)是老劉呼喚煙哥!善良的煙哥本以為人家是要約我出去玩!然而,打開(kāi)微信一看,出現(xiàn)下圖聊天記錄
于是本文的主題就這么展開(kāi)了。由于我需要迅速讓老劉明白,這種問(wèn)題的回答套路,所以我回答的時(shí)候,教她的是一種通用做法。
ps :附《那些年用過(guò)的redis集群架構(gòu)(含面試解析)》的連接地址。
當(dāng)然,必須的,我一定要先問(wèn)一下老劉答了哪種redis集群架構(gòu)!老劉的回答是用了redis cluster集群架構(gòu)。
于是,我一聽(tīng)心里就有底,開(kāi)始balabala....
正文
持久化套路
OK,一般我們?cè)谏a(chǎn)上采用的持久化策略為
- (1)master關(guān)閉持久化
- (2)slave開(kāi)RDB即可,必要的時(shí)候AOF和RDB都開(kāi)啟
該策略能夠適應(yīng)絕大部分場(chǎng)景,絕大部分集群架構(gòu)。
為什么是絕大部分場(chǎng)景?
因?yàn)檫@套策略存在部分的數(shù)據(jù)丟失可能性。redis的主從復(fù)制是異步的,master執(zhí)行完客戶端請(qǐng)求的命令后會(huì)立即返回結(jié)果給客戶端,然后異步的方式把命令同步給slave。因此master可能還未來(lái)得及將命令傳輸給slave,就宕機(jī)了,此時(shí)slave變?yōu)閙aster,數(shù)據(jù)就丟了。
幸運(yùn)的是,絕大部分業(yè)務(wù)場(chǎng)景,都能容忍數(shù)據(jù)的部分丟失。假設(shè),真的遇到緩存雪崩的情況,代碼中也有熔斷器來(lái)進(jìn)行資源保護(hù),不至于所有的請(qǐng)求都轉(zhuǎn)發(fā)到數(shù)據(jù)庫(kù)上,導(dǎo)致我們的服務(wù)崩潰!
ps :這里的緩存雪崩是指同一時(shí)間來(lái)了一堆請(qǐng)求,請(qǐng)求的key在redis中不存在,導(dǎo)致請(qǐng)求全部轉(zhuǎn)發(fā)到數(shù)據(jù)庫(kù)上。
為什么是絕大部分集群架構(gòu)?
因?yàn)樵诩褐写嬖趓edis讀寫分離的情況,就不適合這套方案了。
幸運(yùn)的是,由于采用redis讀寫分離架構(gòu),就必須要考慮主從同步的延遲性問(wèn)題,徒增系統(tǒng)復(fù)雜度。目前業(yè)內(nèi)采用redis讀寫分離架構(gòu)的項(xiàng)目,真的太少了。
為什么這么做
(1)master關(guān)閉持久化
原因很簡(jiǎn)單,因?yàn)闊o(wú)論哪種持久化方式都會(huì)影響redis的性能,哪一種持久化都會(huì)造成CPU卡頓,影響對(duì)客戶端請(qǐng)求的處理。為了保證讀寫最佳性能,將master的持久化關(guān)閉!
RDB持久化
RDB持久化是將當(dāng)前進(jìn)程中的數(shù)據(jù)生成快照保存到硬盤(因此也稱作快照持久化),保存的文件后綴是rdb;當(dāng)Redis重新啟動(dòng)時(shí),可以讀取快照文件恢復(fù)數(shù)據(jù)。
那么RDB持久化的過(guò)程,相當(dāng)于在執(zhí)行bgsave命令。該命令執(zhí)行過(guò)程如下圖所示
如圖所示,主線程需要調(diào)用系統(tǒng)函數(shù)fork(),構(gòu)建出一個(gè)子進(jìn)程進(jìn)行持久化!很不幸的是,在構(gòu)建子進(jìn)程的過(guò)程中,父進(jìn)程就會(huì)阻塞,無(wú)法響應(yīng)客戶端的請(qǐng)求!
而且,在測(cè)試中發(fā)現(xiàn),fork函數(shù)在虛擬機(jī)上較慢,真機(jī)上較快。考慮到現(xiàn)在都是部署在docker容器中,很少部署在真機(jī)上,為了性能,master不建議打開(kāi)RDB持久化!
AOF持久化
RDB持久化是將進(jìn)程數(shù)據(jù)寫入文件,而AOF持久化(即Append Only File持久化),則是將Redis執(zhí)行的每次寫命令記錄到單獨(dú)的日志文件中。
隨著時(shí)間的流逝,你會(huì)發(fā)現(xiàn)這個(gè)AOF文件越來(lái)越大,于是redis有一套rewrite機(jī)制,來(lái)縮小AOF文件的體積。然而,在rewrite的過(guò)程中也是需要父進(jìn)程來(lái)fork出一個(gè)子進(jìn)程進(jìn)行rewrite操作。至于fork函數(shù)的影響,上面提到過(guò)了。
還有一個(gè)就是刷盤策略fsync,這個(gè)值推薦是配everysec,也就是Redis會(huì)默認(rèn)每隔一秒進(jìn)行一次fsync調(diào)用,將緩沖區(qū)中的數(shù)據(jù)寫到磁盤。
然而,如果磁盤性能不穩(wěn)定,fsync的調(diào)用時(shí)間超過(guò)1秒鐘。此時(shí)主線程進(jìn)行AOF的時(shí)候會(huì)對(duì)比上次fsync成功的時(shí)間;如果距上次不到2s,主線程直接返回;如果超過(guò)2s,則主線程阻塞直到fsync同步完成。
因此AOF也是會(huì)影響redis的性能的。
ps :linux函數(shù)中,wrtie函數(shù)將數(shù)據(jù)寫入文件的時(shí)候,是將數(shù)據(jù)寫入操作系統(tǒng)的緩沖區(qū),還并未刷入磁盤。而fsync函數(shù),可以強(qiáng)制讓操作系統(tǒng)將緩沖區(qū)數(shù)據(jù)刷入磁盤。
綜上所述,我們?yōu)榱吮WC讀寫性能最大化,將master的持久化關(guān)閉。
(2)slave開(kāi)RDB即可,必要的時(shí)候AOF和RDB都開(kāi)啟
首先,我先說(shuō)明一下,我不推薦單開(kāi)AOF的原因是,基于AOF的數(shù)據(jù)恢復(fù)太慢。
你要想,我們已經(jīng)做了主從復(fù)制,數(shù)據(jù)已經(jīng)實(shí)現(xiàn)備份,為什么slave還需要開(kāi)持久化?
因?yàn)槟骋惶炜赡芤驗(yàn)槟衬彻こ蹋褭C(jī)房的電線挖斷了,就會(huì)導(dǎo)致master和slave機(jī)器同時(shí)關(guān)機(jī)。
那么這個(gè)時(shí)候,我們需要迅速恢復(fù)集群,而RDB文件文件小、恢復(fù)快,因此災(zāi)難恢復(fù)常用RDB文件。
其次,官網(wǎng)也不推薦單開(kāi)AOF,地址如下:
https:///topics/persistence
截圖如下
所以,如果實(shí)在對(duì)數(shù)據(jù)安全有一定要求,將AOF和RDB持久化都開(kāi)啟。
另外,做好災(zāi)難備份。利用linux的scp命令,定期將rdb文件拷貝到云服務(wù)器上。
ps :scp是secure copy的簡(jiǎn)寫,用于在Linux下進(jìn)行遠(yuǎn)程拷貝文件的命令,和它類似的命令有cp,不過(guò)cp只是在本機(jī)進(jìn)行拷貝不能跨服務(wù)器,而且scp傳輸是加密的。
總結(jié)
本文提出的是一種通用的持久化策略,主要目的是在面試的時(shí)候被問(wèn)到,給出一個(gè)合理的回答,而不至于一臉懵逼。
|