深度講解Redis主從復(fù)制、哨兵、Cluster三種模式
在Redis中,有三種不同的部署模式:主從復(fù)制(Master-Slave Replication)、哨兵(Sentinel)模式和集群(Cluster)模式。每種模式都有其特定的用途和優(yōu)勢(shì),適用于不同的場(chǎng)景。下面我將分別介紹這三種模式,并探討它們的特點(diǎn)和應(yīng)用。
redis集群類型
redis集群模式主要有以下幾種方式:
主從復(fù)制(redis2.8版本之前的模式)
Redis Sentinel 哨兵模式(redis2.8及之后的模式)
Redis Cluster集群模式(客戶端sharding)(redis3.0版本之后)
Jedis sharding集群(客戶端sharding)
利用中間件代理
在這里主要講述主從復(fù)制、哨兵模式、Redis Cluster集群這三種方式。
主從復(fù)制
主從復(fù)制概念
主從復(fù)制,是指將一臺(tái)Redis服務(wù)器的數(shù)據(jù),復(fù)制到其他的Redis服務(wù)器。前者稱為主節(jié)點(diǎn)(master),后者稱為從節(jié)點(diǎn)(slave),數(shù)據(jù)的復(fù)制是單向的,只能由主節(jié)點(diǎn)到從節(jié)點(diǎn)。
默認(rèn)情況下,每臺(tái)Redis服務(wù)器都是主節(jié)點(diǎn);且一個(gè)主節(jié)點(diǎn)可以有多個(gè)從節(jié)點(diǎn)(或沒(méi)有從節(jié)點(diǎn)),但一個(gè)從節(jié)點(diǎn)只能有一個(gè)主節(jié)點(diǎn)。
如果Master和Slave之間的鏈接出現(xiàn)斷連現(xiàn)象,Slave可以自動(dòng)重連Master,但是在連接成功之后,一次完全同步將被自動(dòng)執(zhí)行。
工作原理
從服務(wù)器連接主服務(wù)器,發(fā)送SYNC命令;
主服務(wù)器接收到SYNC命名后,開始執(zhí)行BGSAVE命令生成RDB文件并使用緩沖區(qū)記錄此后執(zhí)行的所有寫命令;
主服務(wù)器BGSAVE執(zhí)行完后,向所有從服務(wù)器發(fā)送快照文件,并在發(fā)送期間繼續(xù)記錄被執(zhí)行的寫命令;
從服務(wù)器收到快照文件后丟棄所有舊數(shù)據(jù),載入收到的快照;
主服務(wù)器快照發(fā)送完畢后開始向從服務(wù)器發(fā)送緩沖區(qū)中的寫命令;
從服務(wù)器完成對(duì)快照的載入,開始接收命令請(qǐng)求,并執(zhí)行來(lái)自主服務(wù)器緩沖區(qū)的寫命令;(從服務(wù)器初始化完成)
主服務(wù)器每執(zhí)行一個(gè)寫命令就會(huì)向從服務(wù)器發(fā)送相同的寫命令,從服務(wù)器接收并執(zhí)行收到的寫命令 (從服務(wù)器初始化完成后的操作)
主從復(fù)制啟用
從節(jié)點(diǎn)開啟主從復(fù)制,有3種方式:
配置文件:在從服務(wù)器的配置文件中加入:slaveof
啟動(dòng)命令: redis-server啟動(dòng)命令后加入 --slaveof
客戶端命令: Redis服務(wù)器啟動(dòng)后,直接通過(guò)客戶端執(zhí)行命令:slaveof
,則該Redis實(shí)例成為從節(jié)點(diǎn)。
通過(guò) info replication 命令可以看到復(fù)制的一些信息
主從復(fù)制優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
支持主從復(fù)制,可以進(jìn)行讀寫分離
為了分載Master的讀操作壓力,Slave服務(wù)器可以為客戶端提供只讀操作的服務(wù),寫服務(wù)仍然必須由Master來(lái)完成
Slave同樣可以接受其它Slaves的連接和同步請(qǐng)求,這樣可以有效的分載Master的同步壓力。
Master Server是以非阻塞的方式為Slaves提供服務(wù)。所以在Master-Slave同步期間,客戶端仍然可以提交查詢或修改請(qǐng)求。
Slave Server同樣是以非阻塞的方式完成數(shù)據(jù)同步。在同步期間,如果有客戶端提交查詢請(qǐng)求,Redis則返回同步之前的數(shù)據(jù)
缺點(diǎn)
Redis不具備自動(dòng)容錯(cuò)和恢復(fù)功能,主機(jī)從機(jī)的宕機(jī)都會(huì)導(dǎo)致前端部分讀寫請(qǐng)求失敗,需要等待機(jī)器重啟或者手動(dòng)切換前端的IP才能恢復(fù)。
主機(jī)宕機(jī),宕機(jī)前有部分?jǐn)?shù)據(jù)未能及時(shí)同步到從機(jī),切換IP后還會(huì)引入數(shù)據(jù)不一致的問(wèn)題,降低了系統(tǒng)的可用性。
Redis較難支持在線擴(kuò)容,在集群容量達(dá)到上限時(shí)在線擴(kuò)容會(huì)變得很復(fù)雜。
哨兵模式
基本概念
當(dāng)主服務(wù)器中斷服務(wù)后,可以將一個(gè)從服務(wù)器升級(jí)為主服務(wù)器,以便繼續(xù)提供服務(wù),但是這個(gè)過(guò)程需要人工手動(dòng)來(lái)操作。為此,Redis 2.8中提供了哨兵工具來(lái)實(shí)現(xiàn)自動(dòng)化的系統(tǒng)監(jiān)控和故障恢復(fù)功能。
它的功能包括以下兩個(gè):
監(jiān)控主服務(wù)器和從服務(wù)器是否正常運(yùn)行。
主服務(wù)器出現(xiàn)故障時(shí)自動(dòng)將從服務(wù)器轉(zhuǎn)換為主服務(wù)器。
哨兵模式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
哨兵模式是基于主從模式的,所有主從模式的優(yōu)點(diǎn),哨兵模式都具有。
主從可以自動(dòng)切換,進(jìn)行故障轉(zhuǎn)移,系統(tǒng)更健壯,可用性更高。
缺點(diǎn)
Redis較難支持在線擴(kuò)容,在集群容量達(dá)到上限時(shí)在線擴(kuò)容會(huì)變得很復(fù)雜。
Redis-Cluster集群
cluster集群概述
在 Redis 3.0 之前,使用 哨兵(sentinel)機(jī)制來(lái)監(jiān)控各個(gè)節(jié)點(diǎn)之間的狀態(tài),基本已經(jīng)可以實(shí)現(xiàn)高可用,讀寫分離。
而Redis Cluster 是 Redis 的分布式解決方案,在 3.0 版本正式推出,有效地解決了 Redis 在 分布式 方面的需求。當(dāng)遇到 單機(jī)內(nèi)存、并發(fā)、流量 等瓶頸時(shí),可以采用 Cluster 架構(gòu)方案達(dá)到 負(fù)載均衡 的目的。
Redis 支持三種集群模式,分別為主從模式、哨兵模式和Cluster模式。
最初,Redis采用主從模式構(gòu)建集群。在這種模式下,如果主節(jié)點(diǎn)(master)出現(xiàn)故障,需要手動(dòng)將從節(jié)點(diǎn)(slave)轉(zhuǎn)換為主節(jié)點(diǎn)。然而,這種模式在故障恢復(fù)方面效率不高。
為了提高系統(tǒng)的可用性,Redis引入了哨兵模式。在哨兵模式中,一個(gè)哨兵集群負(fù)責(zé)監(jiān)控主節(jié)點(diǎn)和從節(jié)點(diǎn)。如果檢測(cè)到主節(jié)點(diǎn)故障,系統(tǒng)可以自動(dòng)將從節(jié)點(diǎn)晉升為新的主節(jié)點(diǎn)。這提高了故障恢復(fù)的自動(dòng)化程度。
盡管如此,哨兵模式仍然面臨內(nèi)存容量和寫入性能的限制,因?yàn)檫@種模式的寫入能力仍然局限于單個(gè)節(jié)點(diǎn)。為了解決這一問(wèn)題,Redis在3.x版本之后推出了Cluster集群模式。Cluster模式通過(guò)數(shù)據(jù)分片和節(jié)點(diǎn)的水平擴(kuò)展,實(shí)現(xiàn)了更高效的內(nèi)存利用和寫入性能。
Redis 主從模式架構(gòu)介紹
概要
在Redis的主從復(fù)制架構(gòu)中,系統(tǒng)通過(guò)定義主庫(kù)(master)和從庫(kù)(slave)的角色,實(shí)現(xiàn)數(shù)據(jù)的高效同步和備份。這一架構(gòu)具體包含以下特點(diǎn):
master的讀寫能力:master是系統(tǒng)中的數(shù)據(jù)中心,它不僅承擔(dān)全部的寫操作,還能處理讀請(qǐng)求。當(dāng)在master上執(zhí)行任何改變數(shù)據(jù)的操作時(shí),這些更改會(huì)自動(dòng)且實(shí)時(shí)地同步到所有slave。
單向數(shù)據(jù)流:數(shù)據(jù)同步流是單向的,意味著數(shù)據(jù)只從master流向slave,確保了數(shù)據(jù)同步的一致性和可靠性。
slave的只讀特性:slave通常被配置為只讀模式,它們接收并存儲(chǔ)從master傳來(lái)的數(shù)據(jù)。這樣設(shè)計(jì)主要是為了分散讀取壓力,從而提高系統(tǒng)的整體讀取性能。
主slave的對(duì)應(yīng)關(guān)系:一個(gè)master可以對(duì)應(yīng)多個(gè)slave,形成一對(duì)多的關(guān)系。這種結(jié)構(gòu)利于數(shù)據(jù)的冗余備份和讀取負(fù)載的分散。相反,一個(gè)slave只能對(duì)應(yīng)一個(gè)master,以保持?jǐn)?shù)據(jù)同步的一致性。
slave的容錯(cuò)性:如果某個(gè)slave出現(xiàn)故障,它對(duì)系統(tǒng)其他部分的影響是最小的。即便在slave宕機(jī)的情況下,其它slave仍能繼續(xù)提供讀服務(wù),master也能保持正常的讀寫操作。當(dāng)故障的slave恢復(fù)后,它會(huì)自動(dòng)從master同步缺失的數(shù)據(jù)。
master故障的影響:master的故障會(huì)導(dǎo)致Redis暫時(shí)無(wú)法處理新的寫請(qǐng)求,但已連接的slave可以繼續(xù)提供讀服務(wù)。一旦master恢復(fù),Redis會(huì)重新提供完整的讀寫服務(wù)。
master故障的應(yīng)對(duì)機(jī)制:在當(dāng)前的master發(fā)生故障時(shí),系統(tǒng)不會(huì)自動(dòng)在slave中選擇一個(gè)新的master。這需要通過(guò)額外的高可用性解決方案來(lái)實(shí)現(xiàn),例如使用Redis Sentinel或Redis Cluster來(lái)管理master的選舉和故障轉(zhuǎn)移。
在Redis主從復(fù)制架構(gòu),Redis能夠有效地提供高可用性、數(shù)據(jù)冗余以及讀寫分離,從而在維持高性能的同時(shí)確保數(shù)據(jù)的安全和一致性。
Redis主從復(fù)制原理
在本文檔中,我們將重點(diǎn)介紹Redis版本2.8及其后續(xù)版本的主從復(fù)制機(jī)制。
無(wú)是哪種場(chǎng)景,Redis 的主從復(fù)制機(jī)制均采用異步復(fù)制,也稱為樂(lè)觀復(fù)制,因此不能完全保證主從數(shù)據(jù)的一致性。
不論在什么場(chǎng)景下,Redis的主從復(fù)制機(jī)制都采用了所謂的“異步復(fù)制”或“樂(lè)觀復(fù)制”。這種復(fù)制方式意味著不能完全保證主庫(kù)和從庫(kù)數(shù)據(jù)的實(shí)時(shí)一致性。
Redis的主從復(fù)制機(jī)制可以根據(jù)不同的運(yùn)行場(chǎng)景和條件采取不同的實(shí)現(xiàn)方式。以下是一些主要場(chǎng)景及其對(duì)應(yīng)的復(fù)制實(shí)現(xiàn)和說(shuō)明:
第一次啟動(dòng):在從庫(kù)第一次連接到主庫(kù)時(shí),將采用psync復(fù)制方式進(jìn)行全量復(fù)制。這意味著從庫(kù)會(huì)從頭開始復(fù)制主庫(kù)中的全部數(shù)據(jù)。
正常運(yùn)行期間:在正常運(yùn)行狀態(tài)下,從庫(kù)通過(guò)讀取主庫(kù)的緩沖區(qū)來(lái)進(jìn)行增量復(fù)制。這個(gè)過(guò)程涉及復(fù)制主庫(kù)上發(fā)生的新的數(shù)據(jù)變更。
從庫(kù)第二次啟動(dòng)(主庫(kù)緩沖區(qū)未溢出):當(dāng)從庫(kù)重新啟動(dòng)且主庫(kù)的緩沖區(qū)未溢出時(shí),將通過(guò)讀取主庫(kù)的緩沖區(qū)進(jìn)行部分復(fù)制。這種方式能夠快速同步中斷期間發(fā)生的數(shù)據(jù)變更,而不會(huì)對(duì)主庫(kù)造成重大影響。
Redis 2.8及以上版本的從庫(kù)第二次啟動(dòng)(針對(duì)主庫(kù)):當(dāng)從庫(kù)第二次啟動(dòng)且系統(tǒng)版本為Redis 2.8或以上時(shí),將采用psync復(fù)制進(jìn)行全量復(fù)制。這種情況通常發(fā)生在主庫(kù)的緩沖區(qū)數(shù)據(jù)無(wú)法滿足從庫(kù)需要同步的數(shù)據(jù)量時(shí)。
通過(guò)上述不同的復(fù)制策略,Redis能夠在保證數(shù)據(jù)備份和減少系統(tǒng)負(fù)載的同時(shí),靈活應(yīng)對(duì)各種運(yùn)行場(chǎng)景。盡管異步復(fù)制機(jī)制可能導(dǎo)致主從數(shù)據(jù)存在短暫的不一致,但這種設(shè)計(jì)在絕大多數(shù)應(yīng)用場(chǎng)景中已被證明是既高效又可靠的。
PS:異步復(fù)制是Redis的復(fù)制方式,而psync是實(shí)現(xiàn)這種復(fù)制方式的具體命令。樂(lè)觀復(fù)制或樂(lè)觀并發(fā)控制則是另一種與Redis的異步復(fù)制機(jī)制不同的數(shù)據(jù)庫(kù)事務(wù)處理概念。不少博客或說(shuō)明介紹異步復(fù)制和樂(lè)觀復(fù)制是同一個(gè)概念。
PSYNC 工作原理
PSYNC 命令是Redis中用于從節(jié)點(diǎn)與主節(jié)點(diǎn)之間數(shù)據(jù)同步的關(guān)鍵命令。它的工作原理包括以下幾個(gè)步驟:
啟動(dòng)或重連判斷:
當(dāng)從節(jié)點(diǎn)(Slave)啟動(dòng)或與主節(jié)點(diǎn)(Master)的連接斷開后重連時(shí),從節(jié)點(diǎn)需要確定是否曾經(jīng)同步過(guò)。
如果從節(jié)點(diǎn)沒(méi)有保存任何主節(jié)點(diǎn)的運(yùn)行ID(runid),它將視為第一次連接到主節(jié)點(diǎn)。
第一次同步處理:
在第一次同步的情況下,從節(jié)點(diǎn)會(huì)發(fā)送 PSYNC -1 命令給主節(jié)點(diǎn),請(qǐng)求進(jìn)行全量數(shù)據(jù)同步。
全量同步是指主節(jié)點(diǎn)將其所有數(shù)據(jù)完整地復(fù)制一份給從節(jié)點(diǎn)。
斷線重連處理:
對(duì)于之前已經(jīng)同步過(guò)的從節(jié)點(diǎn),它會(huì)發(fā)送 PSYNC runid offset 命令,其中runid是主節(jié)點(diǎn)的唯一標(biāo)識(shí)符,offset是從節(jié)點(diǎn)上次同步數(shù)據(jù)的偏移量。
主節(jié)點(diǎn)的響應(yīng):
主節(jié)點(diǎn)接收到PSYNC命令后,會(huì)檢查runid是否匹配,以及offset是否在復(fù)制積壓緩沖區(qū)的范圍內(nèi)。
如果匹配且offset有效,主節(jié)點(diǎn)將回復(fù)CONTINUE,并發(fā)送自從節(jié)點(diǎn)上次斷開連接以來(lái)的所有寫命令。
全量同步觸發(fā)條件:
如果runid不匹配,或offset超出了積壓緩沖區(qū)的范圍,主節(jié)點(diǎn)將通知從節(jié)點(diǎn)執(zhí)行全量同步,回復(fù)FULLRESYNC runid offset。
復(fù)制積壓緩沖區(qū)的作用:
主節(jié)點(diǎn)會(huì)在處理寫命令的同時(shí),將這些命令存入復(fù)制積壓隊(duì)列,同時(shí)記錄隊(duì)列中存放命令的全局offset。
當(dāng)從節(jié)點(diǎn)斷線重連,且條件允許時(shí),它可以通過(guò)offset從積壓隊(duì)列中進(jìn)行增量復(fù)制,而不是全量復(fù)制。
數(shù)據(jù)一致性保障:
PSYNC機(jī)制允許從節(jié)點(diǎn)在網(wǎng)絡(luò)不穩(wěn)定或其他意外斷開連接的情況下,能夠以增量方式重新同步數(shù)據(jù),保持主從節(jié)點(diǎn)數(shù)據(jù)的一致性。
PS:判斷是否進(jìn)行全量同步,需要考慮兩個(gè)關(guān)鍵因素:首先,確認(rèn)這是否是第一次進(jìn)行數(shù)據(jù)同步;其次,檢查緩存區(qū)是否已經(jīng)達(dá)到或超過(guò)其容量上限。只有在是第一次同步,或者緩存區(qū)已溢出的情況下,才會(huì)執(zhí)行全量同步。