Redis面試8連問(wèn),你能頂住幾道?
1、如何保證Redis高可用和高并發(fā)?
Redis主從架構(gòu),一主多從,可以滿(mǎn)足高可用和高并發(fā)。出現(xiàn)實(shí)例宕機(jī)自動(dòng)進(jìn)行主備切換,配置讀寫(xiě)分離緩解Master讀寫(xiě)壓力。
2、Redis高可用方案具體怎么實(shí)施?
使用官方推薦的哨兵(sentinel)機(jī)制就能實(shí)現(xiàn),當(dāng)主節(jié)點(diǎn)出現(xiàn)故障時(shí),由Sentinel自動(dòng)完成故障發(fā)現(xiàn)和轉(zhuǎn)移,并通知應(yīng)用方,實(shí)現(xiàn)高可用性。
它有四個(gè)主要功能:
- 集群監(jiān)控,負(fù)責(zé)監(jiān)控redis master和slave進(jìn)程是否正常工作。
- 消息通知,如果某個(gè)redis實(shí)例有故障,那么哨兵負(fù)責(zé)發(fā)送消息作為報(bào)警通知給管理員。
- 故障轉(zhuǎn)移,如果master node掛掉了,會(huì)自動(dòng)轉(zhuǎn)移到slave node上。
- 配置中心,如果故障轉(zhuǎn)移發(fā)生了,通知client客戶(hù)端新的master地址。
3、你能說(shuō)說(shuō)Redis哨兵機(jī)制的原理嗎?
通過(guò)sentinel模式啟動(dòng)Redis后,自動(dòng)監(jiān)控master/slave的運(yùn)行狀態(tài),基本原理是:心跳機(jī)制+投票裁決。
每個(gè)sentinel會(huì)向其它sentinal、master、slave定時(shí)發(fā)送消息,以確認(rèn)對(duì)方是否活著,如果發(fā)現(xiàn)對(duì)方在指定時(shí)間內(nèi)未回應(yīng),則暫時(shí)認(rèn)為對(duì)方宕機(jī)。
若哨兵群中的多數(shù)sentinel都報(bào)告某一master沒(méi)響應(yīng),系統(tǒng)才認(rèn)為該master真正宕機(jī),通過(guò)Raft投票算法,從剩下的slave節(jié)點(diǎn)中,選一臺(tái)提升為master,然后自動(dòng)修改相關(guān)配置。
4、部署Redis哨兵要注意哪些問(wèn)題?
哨兵至少需要3個(gè)實(shí)例,來(lái)保證自己的健壯性。哨兵的詳細(xì)教程及與Spring Boot如何集成請(qǐng)關(guān)注公眾號(hào)Java技術(shù)棧進(jìn)行閱讀。
5、Redis主從架構(gòu)數(shù)據(jù)會(huì)丟失嗎,為什么?
有兩種數(shù)據(jù)丟失的情況:
1)異步復(fù)制導(dǎo)致的數(shù)據(jù)丟失:因?yàn)閙aster -> slave的復(fù)制是異步的,所以可能有部分?jǐn)?shù)據(jù)還沒(méi)復(fù)制到slave,master就宕機(jī)了,此時(shí)這些部分?jǐn)?shù)據(jù)就丟失了。
2)腦裂導(dǎo)致的數(shù)據(jù)丟失:某個(gè)master所在機(jī)器突然脫離了正常的網(wǎng)絡(luò),跟其他slave機(jī)器不能連接,但是實(shí)際上master還運(yùn)行著,此時(shí)哨兵可能就會(huì)認(rèn)為master宕機(jī)了,然后開(kāi)啟選舉,將其他slave切換成了master。這個(gè)時(shí)候,集群里就會(huì)有兩個(gè)master,也就是所謂的腦裂。此時(shí)雖然某個(gè)slave被切換成了master,但是可能client還沒(méi)來(lái)得及切換到新的master,還繼續(xù)寫(xiě)向舊master的數(shù)據(jù)可能也丟失了。因此舊master再次恢復(fù)的時(shí)候,會(huì)被作為一個(gè)slave掛到新的master上去,自己的數(shù)據(jù)會(huì)清空,重新從新的master復(fù)制數(shù)據(jù)。
6、Redis主從復(fù)制的工作原理?
1)一個(gè)Slave實(shí)例,無(wú)論是第一次連接還是重連到Master,它都會(huì)發(fā)出一個(gè)SYNC命令;
2)當(dāng)Master收到SYNC命令之后,會(huì)做兩件事:(a) Master執(zhí)行BGSAVE,即在后臺(tái)保存數(shù)據(jù)到磁盤(pán)(rdb快照文件);(b) Master同時(shí)將新收到的寫(xiě)入和修改數(shù)據(jù)集的命令存入緩沖區(qū)(非查詢(xún)類(lèi));
3)當(dāng)Master在后臺(tái)把數(shù)據(jù)保存到快照文件完成之后,Master會(huì)把這個(gè)快照文件傳送給Slave,而Slave則把內(nèi)存清空后,加載該文件到內(nèi)存中;
4)而Master也會(huì)把此前收集到緩沖區(qū)中的命令,通過(guò)Reids命令協(xié)議形式轉(zhuǎn)發(fā)給Slave,Slave執(zhí)行這些命令,實(shí)現(xiàn)和Master的同步;
5)Master/Slave此后會(huì)不斷通過(guò)異步方式進(jìn)行命令的同步,達(dá)到最終數(shù)據(jù)的同步一致;
7、由于主從延遲導(dǎo)致讀取到過(guò)期數(shù)據(jù)怎么處理?
1)通過(guò)scan命令掃庫(kù):當(dāng)Redis中的key被scan的時(shí)候,相當(dāng)于訪問(wèn)了該key,同樣也會(huì)做過(guò)期檢測(cè),充分發(fā)揮Redis惰性刪除的策略。這個(gè)方法能大大降低了臟數(shù)據(jù)讀取的概率,但缺點(diǎn)也比較明顯,會(huì)造成一定的數(shù)據(jù)庫(kù)壓力,否則影響線(xiàn)上業(yè)務(wù)的效率。
2)Redis加入了一個(gè)新特性來(lái)解決主從不一致導(dǎo)致讀取到過(guò)期數(shù)據(jù)問(wèn)題,增加了key是否過(guò)期以及對(duì)主從庫(kù)的判斷,如果key已過(guò)期,當(dāng)前訪問(wèn)的master則返回null;當(dāng)前訪問(wèn)的是從庫(kù),且執(zhí)行的是只讀命令也返回null。
8、Redis Key的過(guò)期策略有哪些?
1)惰性刪除:當(dāng)讀/寫(xiě)一個(gè)已經(jīng)過(guò)期的key時(shí),會(huì)觸發(fā)惰性刪除策略,直接刪除掉這個(gè)過(guò)期key,很明顯,這是被動(dòng)的。
2)定期刪除:由于惰性刪除策略無(wú)法保證冷數(shù)據(jù)被及時(shí)刪掉,所以 Redis 會(huì)定期主動(dòng)淘汰一批已過(guò)期的key。
3)主動(dòng)刪除:當(dāng)前已用內(nèi)存超過(guò)maxMemory限定時(shí),觸發(fā)主動(dòng)清理策略。主動(dòng)設(shè)置的前提是設(shè)置了maxMemory的值。