Redis備份、容災(zāi)及高可用實(shí)戰(zhàn),一文看齊~
一,Redis簡單介紹
Redis是一個高性能的key-value非關(guān)系型數(shù)據(jù)庫,由于其具有高性能的特性,支持高可用、持久化、多種數(shù)據(jù)結(jié)構(gòu)、集群等,使其脫穎而出,成為常用的非關(guān)系型數(shù)據(jù)庫。
此外,Redis的使用場景也比較多。
1. 會話緩存(Session Cache)
Redis緩存會話有非常好的優(yōu)勢,因?yàn)镽edis提供持久化,在需要長時間保持會話的應(yīng)用場景中,如購物車場景這樣的場景中能提供很好的長會話支持,能給用戶提供很好的購物體驗(yàn)。
2. 全頁緩存
在WordPress中,Pantheon提供了一個不錯的插件wp-redis,這個插件能以最快的速度加載你曾經(jīng)瀏覽過的頁面。
3. 隊(duì)列
Reids提供list和set操作,這使得Redis能作為一個很好的消息隊(duì)列平臺來使用。
我們常通過Reids的隊(duì)列功能做購買限制。比如到節(jié)假日或者推廣期間,進(jìn)行一些活動,對用戶購買行為進(jìn)行限制,限制今天只能購買幾次商品或者一段時間內(nèi)只能購買一次。也比較適合適用。
4. 排名
Redis在內(nèi)存中對數(shù)字進(jìn)行遞增或遞減的操作實(shí)現(xiàn)得非常好。所以我們在很多排名的場景中會應(yīng)用Redis來進(jìn)行,比如小說網(wǎng)站對小說進(jìn)行排名,根據(jù)排名,將排名靠前的小說推薦給用戶。
5. 發(fā)布/訂閱
Redis提供發(fā)布和訂閱功能,發(fā)布和訂閱的場景很多,比如我們可以基于發(fā)布和訂閱的腳本觸發(fā)器,實(shí)現(xiàn)用Redis的發(fā)布和訂閱功能建立起來的聊天系統(tǒng)。
此外還有很多其它場景,Redis都表現(xiàn)的不錯。
二,Redis使用中單點(diǎn)故障問題
正是由于Redis具備多種優(yōu)良特新,且應(yīng)用場景非常豐富,以至于Redis在各個公司都有它存在的身影。那么隨之而來的問題和風(fēng)險也就來了。Redis雖然應(yīng)用場景豐富,但部分公司在實(shí)踐Redis應(yīng)用的時候還是相對保守使用單節(jié)點(diǎn)部署,那為日后的維護(hù)帶來了安全風(fēng)險。
在2015年的時候,曾處理過一個因?yàn)閱吸c(diǎn)故障原因?qū)е碌臉I(yè)務(wù)中斷問題。當(dāng)時的Redis都未采用分布式部署,采用單實(shí)例部署,并未考慮容災(zāi)方面的問題。
當(dāng)時我們通過Redis服務(wù)器做用戶購買優(yōu)惠商品的行為控制,但后來由于未知原因Redis節(jié)點(diǎn)的服務(wù)器宕機(jī)了,導(dǎo)致我們無法對用戶購買行為進(jìn)行控制,造成了用戶能夠在一段時間內(nèi)多次購買優(yōu)惠商品的行為。
這種宕機(jī)事故可以說已經(jīng)對公司造成了不可挽回的損失了,安全風(fēng)險問題非常嚴(yán)重,作為當(dāng)時運(yùn)維這個系統(tǒng)的我來說有必要對這個問題進(jìn)行修復(fù)和在架構(gòu)上的改進(jìn)。于是我開始了解決非分布式應(yīng)用下Redis單點(diǎn)故障方面的研究學(xué)習(xí)。
三,非分布式場景下Redis應(yīng)用的備份與容災(zāi)
Redis主從復(fù)制現(xiàn)在應(yīng)該是很普遍了。常用的主從復(fù)制架構(gòu)有如下兩種架構(gòu)方案。
常用Redis主從復(fù)制
- 方案一
這是最常見的一種架構(gòu),一個Master節(jié)點(diǎn),兩個Slave節(jié)點(diǎn)。客戶端寫數(shù)據(jù)的時候是寫Master節(jié)點(diǎn),讀的時候,是讀取兩個Slave,這樣實(shí)現(xiàn)讀的擴(kuò)展,減輕了Master節(jié)點(diǎn)讀負(fù)載。
- 方案二
這種架構(gòu)同樣是一個Master和兩個Slave。不同的是Master和Slave1使用keepalived進(jìn)行VIP轉(zhuǎn)移。Client連接Master的時候是通過VIP進(jìn)行連接的。避免了方案一IP更改的情況。
Redis主從復(fù)制優(yōu)點(diǎn)與不足
- 優(yōu)點(diǎn)
- 實(shí)現(xiàn)了對master數(shù)據(jù)的備份,一旦master出現(xiàn)故障,slave節(jié)點(diǎn)可以提升為新的master,頂替舊的master繼續(xù)提供服務(wù)
- 實(shí)現(xiàn)讀擴(kuò)展。使用主從復(fù)制架構(gòu), 一般都是為了實(shí)現(xiàn)讀擴(kuò)展。Master主要實(shí)現(xiàn)寫功能, Slave實(shí)現(xiàn)讀的功能
- 不足
架構(gòu)方案一
當(dāng)Master出現(xiàn)故障時,Client就與Master端斷開連接,無法實(shí)現(xiàn)寫功能,同時Slave也無法從Master進(jìn)行復(fù)制。
此時需要經(jīng)過如下操作(假設(shè)提升Slave1為Master):
1)在Slave1上執(zhí)slaveof no one命令提升Slave1為新的Master節(jié)點(diǎn)。
2)在Slave1上配置為可寫,這是因?yàn)榇蠖鄶?shù)情況下,都將slave配置只讀。
3)告訴Client端(也就是連接Redis的程序)新的Master節(jié)點(diǎn)的連接地址。
4)配置Slave2從新的Master進(jìn)行數(shù)據(jù)復(fù)制。
架構(gòu)方案二
當(dāng)master出現(xiàn)故障后,Client可以連接到Slave1上進(jìn)行數(shù)據(jù)操作,但是Slave1就成了一個單點(diǎn),就出現(xiàn)了經(jīng)常要避免的單點(diǎn)故障(single point of failure)。
之后需要經(jīng)過如下操作:
1)在Slave1上執(zhí)行slaveof no one命令提升Slave1為新的Master節(jié)點(diǎn)
2)在Slave1上配置為可寫,這是因?yàn)榇蠖鄶?shù)情況下,都將Slave配置只讀
3)配置Slave2從新的Master進(jìn)行數(shù)據(jù)復(fù)制
可以發(fā)現(xiàn),無論是哪種架構(gòu)方案都需要人工干預(yù)來進(jìn)行故障轉(zhuǎn)移(failover)。需要人工干預(yù)就增加了運(yùn)維工作量,同時也對業(yè)務(wù)造成了巨大影響。這時候可以使用Redis的高可用方案-Sentinel
四,Redis Sentinel介紹
Redis Sentinel為Redis提供了高可用方案。從實(shí)踐方面來說,使用Redis Sentinel可以創(chuàng)建一個無需人為干預(yù)就可以預(yù)防某些故障的Redis環(huán)境。
Redis Sentinel設(shè)計(jì)為分布式的架構(gòu),運(yùn)行多個Sentinel進(jìn)程來共同合作的。運(yùn)行多個Sentinel進(jìn)程合作,當(dāng)多個Sentinel同一給定的master無法再繼續(xù)提供服務(wù),就會執(zhí)行故障檢測,這會降低誤報的可能性。
五,Redis Sentinel功能
Redis Sentinel在Redis高可用方案中主要作用有如下功能:
- 監(jiān)控
Sentinel會不斷的檢查master和slave是否像預(yù)期那樣正常運(yùn)行
- 通知
通過API,Sentinel能夠通知系統(tǒng)管理員、程序監(jiān)控的Redis實(shí)例出現(xiàn)了故障
- 自動故障轉(zhuǎn)移
如果master不像預(yù)想中那樣正常運(yùn)行,Sentinel可以啟動故障轉(zhuǎn)移過程,其中的一個slave會提成為master,其它slave會重新配置來使用新的master,使用Redis服務(wù)的應(yīng)用程序,當(dāng)連接時,也會被通知使用新的地址。
- 配置提供者
Sentinel可以做為客戶端服務(wù)發(fā)現(xiàn)的認(rèn)證源:客戶端連接Sentinel來獲取目前負(fù)責(zé)給定服務(wù)的Redis master地址。如果發(fā)生故障轉(zhuǎn)移,Sentinel會報告新的地址。
六,Redis Sentinel架構(gòu)
七,Redis Sentinel實(shí)現(xiàn)原理
Sentinel集群對自身和Redis主從復(fù)制進(jìn)行監(jiān)控。當(dāng)發(fā)現(xiàn)Master節(jié)點(diǎn)出現(xiàn)故障時,會經(jīng)過如下步驟:
1)Sentinel之間進(jìn)行選舉,選舉出一個leader,由選舉出的leader進(jìn)行failover
2)Sentinel leader選取slave節(jié)點(diǎn)中的一個slave作為新的Master節(jié)點(diǎn)。對slave選舉需要對slave進(jìn)行選舉的方法如下:
a) 與master斷開時間
如果與master斷開的時間超過down-after-milliseconds(sentinel配置) * 10秒加上從sentinel判定master不可用到sentinel開始執(zhí)行故障轉(zhuǎn)移之間的時間,就認(rèn)為該slave不適合提升為master。
b) slave優(yōu)先級
每個slave都有優(yōu)先級,保存在redis.conf配置文件里。如果優(yōu)先級相同,則繼續(xù)進(jìn)行。
c) 復(fù)制偏移位置
復(fù)制偏移紀(jì)錄著從master復(fù)制數(shù)據(jù)復(fù)制到哪里,復(fù)制偏移越大表明從master接受的數(shù)據(jù)越多,如果復(fù)制偏移量也一樣,繼續(xù)進(jìn)行選舉
d) Run ID
選舉具有最小Run ID的Slave作為新的Master
流程圖如下:
3) Sentinel leader會在上一步選舉的新master上執(zhí)行slaveof no one操作,將其提升為master節(jié)點(diǎn)
4)Sentinel leader向其它slave發(fā)送命令,讓剩余的slave成為新的master節(jié)點(diǎn)的slave
5)Sentinel leader會讓原來的master降級為slave,當(dāng)恢復(fù)正常工作,Sentinel leader會發(fā)送命令讓其從新的master進(jìn)行復(fù)制
以上failover操作均有sentinel自己獨(dú)自完成,完全無需人工干預(yù)。
總結(jié)
使用sentinel實(shí)現(xiàn)了Redis的高可用,當(dāng)master出現(xiàn)故障時,完全無需人工干預(yù)即可實(shí)現(xiàn)故障轉(zhuǎn)移。避免了對業(yè)務(wù)的影響,提高了運(yùn)維工作效率。
在部署sentinel的時候,建議使用奇數(shù)個sentinel節(jié)點(diǎn),最少三個sentinel節(jié)點(diǎn)。