一文帶你了解Redis的三種集群模式
Redis 的三種集群模式
Redis 的常用的集群方式主要有以下三種,分別是主從復(fù)制模式、哨兵模式、Redis-Cluster集群模式,那么下面我們就分別了解一下這三種集群模式的優(yōu)點(diǎn)與缺點(diǎn)。
主從復(fù)制模式
主從復(fù)制,是指將一臺 Redis 服務(wù)器的數(shù)據(jù),復(fù)制到其他的 Redis 服務(wù)器。前者稱為主節(jié)點(diǎn)(Master),后者稱為從節(jié)點(diǎn)(Slave),數(shù)據(jù)的復(fù)制是單向的,只能由主節(jié)點(diǎn)到從節(jié)點(diǎn)。Redis 的主從復(fù)制模式一般是由一主一從(一個(gè)主節(jié)點(diǎn)+一個(gè)從節(jié)點(diǎn))或一主多從(一個(gè)主節(jié)點(diǎn)+多個(gè)從節(jié)點(diǎn))的形式來構(gòu)成。主節(jié)點(diǎn)負(fù)責(zé)寫操作,從節(jié)點(diǎn)負(fù)責(zé)讀操作,從節(jié)點(diǎn)從主節(jié)點(diǎn)復(fù)制數(shù)據(jù),通過這種方式也可以實(shí)現(xiàn)讀寫分離。
下面我們一起看看主從復(fù)制的原理 ??
- 從服務(wù)器連接主服務(wù)器,發(fā)送 SYNC 命令(即 sync command 命令),請求同步鏈接
- 主服務(wù)器接收到 SYNC 命名后,開始執(zhí)行 BGSAVE 命令生成 RDB 文件并使用緩沖區(qū)記錄此后執(zhí)行的所有寫命令
- 主服務(wù)器BGSAVE執(zhí)行完后,向所有從服務(wù)器發(fā)送快照文件,并在發(fā)送期間繼續(xù)記錄被執(zhí)行的寫命令
- 從服務(wù)器收到快照文件后丟棄所有舊數(shù)據(jù),載入收到的快照
- 主服務(wù)器快照發(fā)送完畢后開始向從服務(wù)器發(fā)送緩沖區(qū)中的寫命令;
- 從服務(wù)器完成對快照的載入,開始接收命令請求,并執(zhí)行來自主服務(wù)器緩沖區(qū)的寫命令;(從服務(wù)器初始化完成)
- 主服務(wù)器每執(zhí)行一個(gè)寫命令就會向從服務(wù)器發(fā)送相同的寫命令,從服務(wù)器接收并執(zhí)行收到的寫命令(從服務(wù)器初始化完成后的操作)
了解了主從復(fù)制模式的概念和原理后,我們一起總結(jié)一下主從復(fù)制模式的優(yōu)缺點(diǎn):
??優(yōu)點(diǎn)??
1、支持主從復(fù)制,主機(jī)會自動(dòng)將數(shù)據(jù)同步到從機(jī),可以進(jìn)行讀寫分離,同時(shí)緩解了主庫的壓力。
2、Master Server 是以非阻塞的方式為 Slaves 提供服務(wù)。所以在 Master-Slave 同步期間,客戶端仍然可以提交查詢或修改請求;Slave Server 同樣是以非阻塞的方式完成數(shù)據(jù)同步。在同步期間,如果有客戶端提交查詢請求,Redis則返回同步之前的數(shù)據(jù)。
??缺點(diǎn)??
1、由于 Redis 不具備自動(dòng)容錯(cuò)和恢復(fù)功能,主機(jī)從機(jī)的宕機(jī)都會導(dǎo)致部分讀寫請求失敗,需要等待機(jī)器重啟或者手動(dòng)將某臺從節(jié)點(diǎn)升級為主節(jié)點(diǎn)才能解決。而且在主機(jī)宕機(jī)時(shí),宕機(jī)前部分?jǐn)?shù)據(jù)未能及時(shí)同步到從機(jī),切換IP后還會引入數(shù)據(jù)不一致的問題,降低了系統(tǒng)的可用性。
我們看完主從復(fù)制模式后,可能有些小伙伴就發(fā)現(xiàn)了一些問題:主從復(fù)制模式下,當(dāng)主節(jié)點(diǎn)宕機(jī)后,需要手動(dòng)將某臺從節(jié)點(diǎn)切換為主節(jié)點(diǎn),這需要人工干預(yù),不僅費(fèi)時(shí)費(fèi)力,而且還會造成一段時(shí)間內(nèi)服務(wù)不可用,這個(gè)問題該如何解決呢?? 接下來就需要請哨兵模式登場了....
哨兵模式
為了解決我們剛剛談到的問題,Redis 2.8 中提供了哨兵工具來實(shí)現(xiàn)自動(dòng)化的系統(tǒng)監(jiān)控和故障恢復(fù)功能。其實(shí)哨兵模式也是一種主從復(fù)制模式,只不過增加了哨兵的功能,哨兵的功能主要有兩點(diǎn):第一是監(jiān)控主服務(wù)器和從服務(wù)器是否正常運(yùn)行;第二是當(dāng)主節(jié)點(diǎn)出現(xiàn)故障時(shí)自動(dòng)將從節(jié)點(diǎn)轉(zhuǎn)換為主節(jié)點(diǎn)。
哨兵的啟動(dòng)依賴于主從模式,所以須把主從模式安裝好的情況下再去做哨兵模式,所有節(jié)點(diǎn)上都需要部署哨兵模式,哨兵模式會監(jiān)控所有的 Redis 工作節(jié)點(diǎn)是否正常,當(dāng) Master (主節(jié)點(diǎn))出現(xiàn)問題的時(shí)候,因?yàn)槠渌?jié)點(diǎn)與主節(jié)點(diǎn)失去聯(lián)系,因此會進(jìn)行投票,投票過半就認(rèn)為這個(gè) Master (主節(jié)點(diǎn))的確出現(xiàn)問題,然后會通知其他哨兵,并從 Slaves (從節(jié)點(diǎn))中選取一個(gè)作為新的 Master(主節(jié)點(diǎn))。既然涉及到了投票過半的要求,那么參與投票的哨兵就必須為單數(shù),即整個(gè)運(yùn)行哨兵的集群的數(shù)量?不得少于3個(gè)節(jié)點(diǎn)?。在選取新的主節(jié)點(diǎn)的過程中,我們又可以將整個(gè)過程細(xì)分為兩步,分別為“選哨兵領(lǐng)導(dǎo)”和“由哨兵領(lǐng)導(dǎo)推舉主節(jié)點(diǎn)”。
?? 第一步:選哨兵領(lǐng)導(dǎo) ??
哨兵A: 哎哎哎?。?!兄弟們,我發(fā)現(xiàn)主節(jié)點(diǎn)掉了?。。?!你們趕緊選我當(dāng)頭,我去選一個(gè)新的子節(jié)點(diǎn)來做主節(jié)點(diǎn)?。?!
哨兵B: 額...行吧,我選你當(dāng)頭,雖然我很想當(dāng)領(lǐng)導(dǎo),但是也沒啥經(jīng)驗(yàn)?zāi)?,還是你來吧。
哨兵C: 不行??!我不支持你,我才是當(dāng)領(lǐng)導(dǎo)的材料!!
哨兵A: 哨兵C你去一邊子的,咱們就三個(gè)兄弟,我和哨兵B都支持,那我就是領(lǐng)導(dǎo)了??
P.S. 如果此時(shí)有多個(gè)哨兵同時(shí)參選,則在等待任意時(shí)間后重新發(fā)起投票,直到選出了領(lǐng)頭的
?? 第二步:哨兵領(lǐng)導(dǎo)選擇主節(jié)點(diǎn) ??
哨兵A: 我來看看以前的領(lǐng)導(dǎo)留下來的《如何選擇主節(jié)點(diǎn)》里是怎么寫的...翻書ing... 根據(jù)書里的記載,我需要按照健康性(哨兵發(fā)送ping命令后的響應(yīng)時(shí)間長短,時(shí)間越短則越健康)、完整性(選擇復(fù)制偏移量最大,也就是復(fù)制最完整的從節(jié)點(diǎn))、優(yōu)先級高低(選擇配置文件中從節(jié)點(diǎn)優(yōu)先級配置最高的,即replica-priority,其默認(rèn)值為100)來進(jìn)行主節(jié)點(diǎn)的挑選工作,如果有兩個(gè)從節(jié)點(diǎn)都具備這三個(gè)條件的話,那就根據(jù)節(jié)點(diǎn)啟動(dòng)時(shí)分配的 run id 來決定誰做主節(jié)點(diǎn)(runid越小越有可能被選擇為主節(jié)點(diǎn))...
哨兵A: 還是查書有用啊,要不我還真不知道怎么干,我去選主節(jié)點(diǎn)啦~~
P.S. 選擇主節(jié)點(diǎn)的過程又稱為故障轉(zhuǎn)移的過程
這里有一點(diǎn)是需要注意的,哨兵的下線分為兩種,分別是主觀下線(我認(rèn)為你掉線了)和客觀下線(我們認(rèn)為你掉線了)。每個(gè)哨兵節(jié)點(diǎn)每隔1秒會向主節(jié)點(diǎn)、從節(jié)點(diǎn)及其它哨兵節(jié)點(diǎn)發(fā)送一次 ping 命令做一次心跳檢測。如果主節(jié)點(diǎn)在一定時(shí)間范圍內(nèi)不回復(fù)或者是回復(fù)一個(gè)錯(cuò)誤消息,那么這個(gè)哨兵就會認(rèn)為這個(gè)主節(jié)點(diǎn)主觀下線了(單方面的)。當(dāng)超過半數(shù)哨兵節(jié)點(diǎn)認(rèn)為該主節(jié)點(diǎn)主觀下線了,這樣就客觀下線了。客觀下線是針對于主節(jié)點(diǎn)來說的概念,也就是說只有發(fā)生了客觀下線,才會執(zhí)行我們上面所說的兩個(gè)步驟;如果從節(jié)點(diǎn)和哨兵節(jié)點(diǎn)發(fā)生故障,被哨兵主觀下線后,則不會再有后續(xù)的客觀下線和故障轉(zhuǎn)移操作。
通過上面的講解,我們也就可以總結(jié)出哨兵模式的優(yōu)點(diǎn)了:哨兵模式是基于主從模式的,所有主從的優(yōu)點(diǎn),哨兵模式都具有,同時(shí)使用哨兵模式后主從節(jié)點(diǎn)可以自動(dòng)切換,可以讓系統(tǒng)更健壯,可用性更高。
Redis-Cluster集群模式
Redis 的哨兵模式基本已經(jīng)可以實(shí)現(xiàn)高可用,讀寫分離 ,但是在這種模式下每臺 Redis 服務(wù)器都存儲相同的數(shù)據(jù),很浪費(fèi)內(nèi)存,所以在 Redis3.0 上加入了 Cluster 模式,實(shí)現(xiàn)的 Redis 的分布式存儲,即每臺 Redis 節(jié)點(diǎn)(Node)上存儲不同的內(nèi)容,很大程度上節(jié)約了內(nèi)容。需要注意的是,集群中的節(jié)點(diǎn)也是分為主節(jié)點(diǎn)和從節(jié)點(diǎn)的,只有主節(jié)點(diǎn)負(fù)責(zé)讀寫請求和集群信息的維護(hù),而從節(jié)點(diǎn)只進(jìn)行主節(jié)點(diǎn)數(shù)據(jù)和狀態(tài)信息的復(fù)制。Redis-Cluster采用無中心結(jié)構(gòu),它有以下三個(gè)特點(diǎn) ??
① 所有的redis節(jié)點(diǎn)彼此互聯(lián)(PING-PONG機(jī)制),內(nèi)部使用二進(jìn)制協(xié)議優(yōu)化傳輸速度和帶寬。
②節(jié)點(diǎn)的失效(下線)是通過集群中超過半數(shù)的節(jié)點(diǎn)檢測失效時(shí)才生效。
③ 客戶端與 Redis 節(jié)點(diǎn)直連,不需要中間代理層,客戶端不需要連接集群所有節(jié)點(diǎn),連接集群中任何一個(gè)可用節(jié)點(diǎn)即可。
接下來我們一起看看 Redis-Cluster 集群模式的工作流程:
在 Redis 的每一個(gè)節(jié)點(diǎn)上,都有這么兩個(gè)小東西,一個(gè)是插槽(slot),它的的取值范圍是:0-16383,另一個(gè)就是cluster,可以理解為是一個(gè)集群管理的插件。當(dāng) Redis 拿到了需要存取的 key 時(shí),Redis 會根據(jù) CRC16 算法得出一個(gè)結(jié)果,然后把結(jié)果對 16384 求余數(shù),這樣每個(gè) key 都會對應(yīng)一個(gè)編號在 0-16383 之間的哈希槽,通過這個(gè)值,去找到對應(yīng)的插槽所對應(yīng)的節(jié)點(diǎn),然后直接自動(dòng)跳轉(zhuǎn)到這個(gè)對應(yīng)的節(jié)點(diǎn)上進(jìn)行存取操作。為了保證高可用,Redis-Cluster 集群引入了主從模式,一個(gè)主節(jié)點(diǎn)對應(yīng)一個(gè)或者多個(gè)從節(jié)點(diǎn),當(dāng)主節(jié)點(diǎn)宕機(jī)的時(shí)候,就會啟用從節(jié)點(diǎn)。
雖說 Redis-Cluster 集群引入了主從模式,但是也帶來了一個(gè)問題:如果集群中具有A、B、C三個(gè)節(jié)點(diǎn),如果節(jié)點(diǎn)B失敗了,整個(gè)集群就會因缺少5461-10922這個(gè)范圍的插槽而不可使用;如果為每個(gè)節(jié)點(diǎn)添加一個(gè)從節(jié)點(diǎn)A1、B1、C1整個(gè)集群便有三個(gè)Master節(jié)點(diǎn)和三個(gè)slave節(jié)點(diǎn)組成,當(dāng)在節(jié)點(diǎn)B失敗后,那么集群選舉B1位為主節(jié)點(diǎn)繼續(xù)服務(wù)。但是當(dāng)B和B1都失敗后,集群將不可用。
有些小伙伴看到這里可能會產(chǎn)生一個(gè)疑問:為什么插槽數(shù)是16384個(gè)呢?為什么不能是65535或者是其他數(shù)值呢?其實(shí)關(guān)于這個(gè)問題,作者已經(jīng)給了我們一個(gè)回復(fù)??
The reason is:
- Normal heartbeat packets carry the full configuration of a node, that can be replaced in an idempotent way with the old in order to update an old config. This means they contain the slots configuration for a node, in raw form, that uses 2k of space with16k slots, but would use a prohibitive 8k of space using 65k slots.
- At the same time it is unlikely that Redis Cluster would scale to more than 1000 mater nodes because of other design tradeoffs.
So 16k was in the right range to ensure enough slots per master with a max of 1000 maters, but a small enough number to propagate the slot configuration as a raw bitmap easily. Note that in small clusters the bitmap would be hard to compress because when N is small the bitmap would have slots/N bits set that is a large percentage of bits set.
用一句話總結(jié)出來就是:由于 Redis 節(jié)點(diǎn)之間通訊會相互交換槽信息,那如果槽過多(意味著網(wǎng)絡(luò)包會變大),網(wǎng)絡(luò)包變大,就意味著會過度占用網(wǎng)絡(luò)的帶寬,同時(shí)作者認(rèn)為 Redis 集群中節(jié)點(diǎn)數(shù)不會超過1000個(gè),所以作者就取了16384這個(gè)數(shù),即可以將數(shù)據(jù)合理打散至 Redis 集群中的不同實(shí)例,又不會在交換數(shù)據(jù)時(shí)導(dǎo)致帶寬占用過多。
小結(jié)
本人經(jīng)驗(yàn)有限,有些地方可能講的沒有特別到位,如果您在閱讀的時(shí)候想到了什么問題,歡迎在評論區(qū)留言,我們后續(xù)再一一探討??
以上就是一文帶你了解Redis的三種集群模式的詳細(xì)內(nèi)容,更多關(guān)于Redis集群模式的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
redis和rabbitmq實(shí)現(xiàn)延時(shí)隊(duì)列的示例代碼
在高并發(fā)場景下,延遲隊(duì)列顯得尤為重要,本文主要介紹了兩種方式,redis和rabbitmq實(shí)現(xiàn)延時(shí)隊(duì)列,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
Redis底層數(shù)據(jù)結(jié)構(gòu)SkipList的實(shí)現(xiàn)
本文主要介紹了Redis底層數(shù)據(jù)結(jié)構(gòu)SkipList的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05

