詳解Redis的高可用和高并發(fā)機(jī)制

詳解Redis的高可用和高并發(fā)機(jī)制

一、高并發(fā)機(jī)制

我們知道redis是基于單線程的,在單機(jī)模式下能承載的也就幾萬左右吧,所以怎么提高其在大數(shù)據(jù)下幾十萬的高并發(fā)請求,通過redis的主從架構(gòu)和讀寫分離。

視頻課程推薦→:《千萬級數(shù)據(jù)并發(fā)解決方案(理論+實(shí)戰(zhàn))》

1.主從復(fù)制

redis主從復(fù)制的配置就不強(qiáng)調(diào),主要看主從復(fù)制的原理及過程:在進(jìn)行redis的主從復(fù)制的過程中,需要一臺master主機(jī)作為管理員,去搭建多臺slave從機(jī)。當(dāng)slave從機(jī)試圖啟動時會向master主機(jī)發(fā)送一個命令PSYNC,如果這個時候slave從機(jī)是重新連接的,那么會從master主機(jī)上把slave從機(jī)沒有的數(shù)據(jù)復(fù)制過去,如果是第一次連接那么會觸發(fā)full resynchronization。觸發(fā)以后master主機(jī)會在后臺開啟一個進(jìn)程去生成一個RDB快照文件,同時將這個時間段的寫操作存入緩存,當(dāng)這個RDB文件生成完畢之后會向slave從機(jī)發(fā)送RDB文件,從機(jī)拿到文件之后將其先寫入磁盤然后加載進(jìn)入內(nèi)存最后master主機(jī)會將緩存在內(nèi)存里面的數(shù)據(jù)也同時發(fā)送給從機(jī)。如果在發(fā)生主從的網(wǎng)絡(luò)故障的情況下,有多個slave從機(jī)重新連接那么master只會重啟一份RDB去服務(wù)全部slave?!鞠嚓P(guān)推薦:Redis視頻教程

斷點(diǎn)續(xù)傳:在master和slave里面都有一個replica offset里面還有一個master id ,其中offset就是保持在backlog,當(dāng)主從機(jī)發(fā)生網(wǎng)絡(luò)故障重連時,會去找到對應(yīng)的上次replica offset的地方進(jìn)行復(fù)制,如果沒有找到對應(yīng)的offset那么觸發(fā)full resynchronization。

①復(fù)制的完整流程

(1)slave node啟動,僅僅保存master node的信息,包括master node的host和ip,但是復(fù)制流程沒開始

master host和ip是從哪兒來的,redis.conf里面的slaveof配置的

(2)slave node內(nèi)部有個定時任務(wù),每秒檢查是否有新的master node要連接和復(fù)制,如果發(fā)現(xiàn),就跟master node建立socket網(wǎng)絡(luò)連接
(3)slave node發(fā)送ping命令給master node
(4)口令認(rèn)證,如果master設(shè)置了requirepass,那么salve node必須發(fā)送masterauth的口令過去進(jìn)行認(rèn)證
(5)master node第一次執(zhí)行全量復(fù)制,將所有數(shù)據(jù)發(fā)給slave node
(6)master node后續(xù)持續(xù)將寫命令,異步復(fù)制給slave node

②數(shù)據(jù)同步相關(guān)的核心機(jī)制

指的就是第一次slave連接msater的時候,執(zhí)行的全量復(fù)制,那個過程里面你的一些細(xì)節(jié)的機(jī)制

(1)master和slave都會維護(hù)一個offset

master會在自身不斷累加offset,slave也會在自身不斷累加offset
slave每秒都會上報(bào)自己的offset給master,同時master也會保存每個slave的offset

這個倒不是說特定就用在全量復(fù)制的,主要是master和slave都要知道各自的數(shù)據(jù)的offset,才能知道互相之間的數(shù)據(jù)不一致的情況

(2)backlog

master node有一個backlog,默認(rèn)是1MB大小
master node給slave node復(fù)制數(shù)據(jù)時,也會將數(shù)據(jù)在backlog中同步寫一份
backlog主要是用來做全量復(fù)制中斷候的增量復(fù)制的

(3)master run id

info server,可以看到master run id
如果根據(jù)host+ip定位master node,是不靠譜的,如果master node重啟或者數(shù)據(jù)出現(xiàn)了變化,那么slave node應(yīng)該根據(jù)不同的run id區(qū)分,run id不同就做全量復(fù)制
如果需要不更改run id重啟redis,可以使用redis-cli debug reload命令

(4)psync

從節(jié)點(diǎn)使用psync從master node進(jìn)行復(fù)制,psync runid offset
master node會根據(jù)自身的情況返回響應(yīng)信息,可能是FULLRESYNC runid offset觸發(fā)全量復(fù)制,可能是CONTINUE觸發(fā)增量復(fù)制

③全量復(fù)制

(1)master執(zhí)行bgsave,在本地生成一份rdb快照文件
(2)master node將rdb快照文件發(fā)送給salve node,如果rdb復(fù)制時間超過60秒(repl-timeout),那么slave node就會認(rèn)為復(fù)制失敗,可以適當(dāng)調(diào)節(jié)大這個參數(shù)
(3)對于千兆網(wǎng)卡的機(jī)器,一般每秒傳輸100MB,6G文件,很可能超過60s
(4)master node在生成rdb時,會將所有新的寫命令緩存在內(nèi)存中,在salve node保存了rdb之后,再將新的寫命令復(fù)制給salve node
(5)client-output-buffer-limit slave 256MB 64MB 60,如果在復(fù)制期間,內(nèi)存緩沖區(qū)持續(xù)消耗超過64MB,或者一次性超過256MB,那么停止復(fù)制,復(fù)制失敗
(6)slave node接收到rdb之后,清空自己的舊數(shù)據(jù),然后重新加載rdb到自己的內(nèi)存中,同時基于舊的數(shù)據(jù)版本對外提供服務(wù)
(7)如果slave node開啟了AOF,那么會立即執(zhí)行BGREWRITEAOF,重寫AOF

rdb生成、rdb通過網(wǎng)絡(luò)拷貝、slave舊數(shù)據(jù)的清理、slave aof rewrite,很耗費(fèi)時間

如果復(fù)制的數(shù)據(jù)量在4G~6G之間,那么很可能全量復(fù)制時間消耗到1分半到2分鐘

④增量復(fù)制

(1)如果全量復(fù)制過程中,master-slave網(wǎng)絡(luò)連接斷掉,那么salve重新連接master時,會觸發(fā)增量復(fù)制
(2)master直接從自己的backlog中獲取部分丟失的數(shù)據(jù),發(fā)送給slave node,默認(rèn)backlog就是1MB
(3)msater就是根據(jù)slave發(fā)送的psync中的offset來從backlog中獲取數(shù)據(jù)的

⑤heartbeat

主從節(jié)點(diǎn)互相都會發(fā)送heartbeat信息

master默認(rèn)每隔10秒發(fā)送一次heartbeat,salve node每隔1秒發(fā)送一個heartbeat

⑥異步復(fù)制

master每次接收到寫命令之后,現(xiàn)在內(nèi)部寫入數(shù)據(jù),然后異步發(fā)送給slave node
?

2.讀寫分離:master負(fù)責(zé)寫入操作,slave負(fù)責(zé)幫master減輕訪問查詢量

二、高可用機(jī)制

在高并發(fā)的情況下,配備多集群一主多備,雖然可以解決高并發(fā)問題,但是主機(jī)只有一個,master宕機(jī)那么整個無法進(jìn)行寫操作,從機(jī)無法同步數(shù)據(jù)整個系統(tǒng)會處于癱瘓狀態(tài),整就一個不可用。redis的高可用機(jī)制哨兵機(jī)制,哨兵是redis集群里面的重要的組件,他負(fù)責(zé)集群監(jiān)控,信息通知,故障轉(zhuǎn)移,配置中心。

(1)集群監(jiān)控,負(fù)責(zé)監(jiān)控redis master和slave進(jìn)程是否正常工作
(2)消息通知,如果某個redis實(shí)例有故障,那么哨兵負(fù)責(zé)發(fā)送消息作為報(bào)警通知給管理員
(3)故障轉(zhuǎn)移,如果master node掛掉了,會自動轉(zhuǎn)移到slave node上
(4)配置中心,如果故障轉(zhuǎn)移發(fā)生了,通知client客戶端新的master地址
哨兵本身是分布式的,是作為一個集群去工作的,需要互相協(xié)同工作。

當(dāng)發(fā)現(xiàn)master node 宕機(jī),會需要大部分的哨兵同意才可以,這個涉及到分布式的選舉。

哨兵機(jī)制需要保證最少3個節(jié)點(diǎn)才能保證其健壯性,如果我們在測試時只給出兩個節(jié)點(diǎn),一個master node一個為slave node 那么這兩個節(jié)點(diǎn)里面都有一個哨兵負(fù)責(zé)監(jiān)控,當(dāng)其中的master主機(jī)發(fā)生宕機(jī),那么需要哨兵來進(jìn)行選舉,那么master node里面那個s1的哨兵已經(jīng)沒辦法工作,只能由slave node里面的s2哨兵進(jìn)行選舉,那么進(jìn)行選舉之后要進(jìn)行故障轉(zhuǎn)移需要一個哨兵進(jìn)行工作,其majority參數(shù)規(guī)定了需要哨兵的個數(shù)進(jìn)行故障轉(zhuǎn)移,這時只有一個S2哨兵沒有majority可以進(jìn)行故障轉(zhuǎn)移。所以最少需要3個節(jié)點(diǎn)來保證其健壯。

三、高可用與高并發(fā)出現(xiàn)的數(shù)據(jù)丟失問題

(1)異步復(fù)制導(dǎo)致的數(shù)據(jù)丟失

因?yàn)閙aster -> slave的復(fù)制是異步的,所以可能有部分?jǐn)?shù)據(jù)還沒復(fù)制到slave,master就宕機(jī)了,此時這些部分?jǐn)?shù)據(jù)就丟失了。

(2)腦裂導(dǎo)致的數(shù)據(jù)丟失

腦裂,也就是說,某個master所在機(jī)器突然脫離了正常的網(wǎng)絡(luò),跟其他slave機(jī)器不能連接,但是實(shí)際上master還運(yùn)行著,

此時哨兵可能就會認(rèn)為master宕機(jī)了,然后開啟選舉,將其他slave切換成了master,

這個時候,集群里就會有兩個master,也就是所謂的腦裂,

此時雖然某個slave被切換成了master,但是可能client還沒來得及切換到新的master,還繼續(xù)寫向舊master的數(shù)據(jù)可能也丟失了,

因此舊master再次恢復(fù)的時候,會被作為一個slave掛到新的master上去,自己的數(shù)據(jù)會清空,重新從新的master復(fù)制數(shù)據(jù)。

解決異步復(fù)制和腦裂導(dǎo)致的數(shù)據(jù)丟失

min-slaves-to-write?1 ?min-slaves-max-lag?10

要求至少有1個slave,數(shù)據(jù)復(fù)制和同步的延遲不能超過10秒

如果說一旦所有的slave,數(shù)據(jù)復(fù)制和同步的延遲都超過了10秒鐘,那么這個時候,master就不會再接收任何請求了

上面兩個配置可以減少異步復(fù)制和腦裂導(dǎo)致的數(shù)據(jù)丟失

(1)減少異步復(fù)制的數(shù)據(jù)丟失

有了min-slaves-max-lag這個配置,就可以確保說,一旦slave復(fù)制數(shù)據(jù)和ack延時太長,就認(rèn)為可能master宕機(jī)后損失的數(shù)據(jù)太多了,那么就拒絕寫請求,這樣可以把master宕機(jī)時由于部分?jǐn)?shù)據(jù)未同步到slave導(dǎo)致的數(shù)據(jù)丟失降低的可控范圍內(nèi)

(2)減少腦裂的數(shù)據(jù)丟失

如果一個master出現(xiàn)了腦裂,跟其他slave丟了連接,那么上面兩個配置可以確保說,如果不能繼續(xù)給指定數(shù)量的slave發(fā)送數(shù)據(jù),而且slave超過10秒沒有給自己ack消息,那么就直接拒絕客戶端的寫請求

這樣腦裂后的舊master就不會接受client的新數(shù)據(jù),也就避免了數(shù)據(jù)丟失

上面的配置就確保了,如果跟任何一個slave丟了連接,在10秒后發(fā)現(xiàn)沒有slave給自己ack,那么就拒絕新的寫請求

因此在腦裂場景下,最多就丟失10秒的數(shù)據(jù)

更多編程相關(guān)知識,請?jiān)L問:Redis視頻教程??!

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊13 分享