1. redis集群方案有哪些
在Redis中提供的集群方案總共有三種(一般一個(gè)redis節(jié)點(diǎn)不超過(guò)10G內(nèi)存)
主從復(fù)制 / 主從模式 解決高并發(fā)問(wèn)題
哨兵模式 解決高可用問(wèn)題
分片集群
2. 主從復(fù)制(主從數(shù)據(jù)同步)
2.1 主從復(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)
Redis主從復(fù)制服務(wù)器架構(gòu)圖如下:
2.2 如何搭建主從架構(gòu)
主從模式是其中最簡(jiǎn)單的模式,這種模式中,Redis被分為主節(jié)點(diǎn)(master)和從節(jié)點(diǎn)(slave/replica) 。主節(jié)點(diǎn)可以進(jìn)行讀、寫(xiě)操作,而從節(jié)點(diǎn)一般只能進(jìn)行讀操作,如果在從節(jié)點(diǎn)上進(jìn)行寫(xiě)操作,Redis會(huì)報(bào)錯(cuò)。主節(jié)點(diǎn)和從節(jié)點(diǎn)會(huì)進(jìn)行數(shù)據(jù)同步,使節(jié)點(diǎn)上的數(shù)據(jù)保持一致。
假設(shè)我們現(xiàn)在有3臺(tái)計(jì)算機(jī)A、B、C作為Redis節(jié)點(diǎn),我們要用它們來(lái)搭建主從架構(gòu),把A作為master(主節(jié)點(diǎn))。
① 基本配置:首先,我們要在這3個(gè)節(jié)點(diǎn)上都安裝。為保證這3個(gè)節(jié)點(diǎn)的Redis狀態(tài)是一樣的,因此把A的Redis配置文件復(fù)制并覆蓋另外兩個(gè)節(jié)點(diǎn)的Redis配置文件。然后啟動(dòng)3個(gè)節(jié)點(diǎn)上的Redis。
② 開(kāi)啟主從關(guān)系:要配置主從可以使用replicaof或者slaveof命令,這兩條命令是一樣的,只是Redis在5.0版本之后把從節(jié)點(diǎn)的名字從slave改成了replica。
有兩種方式可以進(jìn)行配置:臨時(shí)和永久。
永久配置:在從節(jié)點(diǎn)的Redis配置文件(通常是redis.conf)中添加一行配置:slaveof
臨時(shí)配置:使用redis-cli客戶端連接到redis服務(wù),執(zhí)行slaveof命令(重啟后失效):slaveof
2.3主從復(fù)制同步原理
2.3.1 全量同步
在6步驟中,master節(jié)點(diǎn)會(huì)進(jìn)行一次bgsave操作生成RDB文件,再把這個(gè)RDB文件發(fā)給slave節(jié)點(diǎn)。我們知道,在bgsave期間,Redis仍然能進(jìn)行服務(wù),如果在這段時(shí)間內(nèi),master執(zhí)行了寫(xiě)操作,那么主從節(jié)點(diǎn)之間的數(shù)據(jù)就會(huì)產(chǎn)生差異。因此,master節(jié)點(diǎn)會(huì)把bgsave執(zhí)行期間的所有命令都記錄到repl_backlog(上圖把名字寫(xiě)錯(cuò)了)文件中,然后在發(fā)送RDB文件之后,把repl_backlog中的命令發(fā)送給從節(jié)點(diǎn)(圖中的10操作)。從節(jié)點(diǎn)會(huì)執(zhí)行這些命令,從而保證主從間的數(shù)據(jù)是一致的。
Q:一個(gè)問(wèn)題,master是如何得知slave節(jié)點(diǎn)是第一次與它建立連接的呢?
A:關(guān)于這個(gè)問(wèn)題,首先我們要了解兩個(gè)概念Replication Id和offset:
replid和offset
**Replication Id:**簡(jiǎn)稱replid,是數(shù)據(jù)集的標(biāo)記,id一致則說(shuō)明是同一數(shù)據(jù)集。每一個(gè)master都有唯一的replid,slave則會(huì)繼承master節(jié)點(diǎn)的replid
**offset:**偏移量,隨著記錄在repl_baklog中的數(shù)據(jù)增多而逐漸增大。slave完成同步時(shí)也會(huì)記錄當(dāng)前同步的offset。如果slave的offset小于master的offset,說(shuō)明slave數(shù)據(jù)落后于master,需要更新。
slave要進(jìn)行數(shù)據(jù)同步時(shí),需要告訴master自己的Replication Id和offset。
由于slave原本也是一個(gè)master,因此它也有自己的Replication Id和offset,并且和master的不一樣。
master判斷發(fā)現(xiàn)slave發(fā)送來(lái)的Replication Id與自己的不一致,說(shuō)明這是一個(gè)全新的slave,就知道要做全量同步了。此外,master會(huì)將自己的Replication Id和offset都發(fā)送給這個(gè)slave,因此從,經(jīng)過(guò)第一次全量同步之后,slave的Replication Id就和master的一樣了。
2.3.2 增量同步
通過(guò)bgsave生成RDB是一個(gè)比較消耗性能的操作。因此除了第一次做全量同步,其它大多數(shù)時(shí)候slave與master都是做增量同步。
增量同步就是只更新slave與master存在差異的部分?jǐn)?shù)據(jù)(與offset有關(guān)了)。
2.4 主從復(fù)制優(yōu)缺點(diǎn)
優(yōu)點(diǎn):解決了系統(tǒng)的高并發(fā)讀的問(wèn)題。
缺點(diǎn):無(wú)法保證系統(tǒng)的高可用,所以哨兵[2]模式出現(xiàn)了。
3. 哨兵模式
3.1 哨兵模式的作用
1、監(jiān)控
2、自動(dòng)故障恢復(fù)
3、通知redis客戶端
Sentinel在本質(zhì)上是一個(gè)獨(dú)立的進(jìn)程。Sentinel的作用如下:
監(jiān)控:Sentinel 會(huì)不斷檢查您的master和slave是否按預(yù)期工作。
自動(dòng)故障恢復(fù):如果master故障,Sentinel會(huì)將一個(gè)slave提升為master。當(dāng)故障實(shí)例恢復(fù)后也以新的master為主。
通知:Sentinel充當(dāng)Redis客戶端的服務(wù)發(fā)現(xiàn)來(lái)源,當(dāng)集群發(fā)生故障轉(zhuǎn)移時(shí),會(huì)將最新信息推送給 Redis的客戶端。
3.2 哨兵的監(jiān)控(心跳機(jī)制、選主規(guī)則)
3.2.1**Sentinel是如何進(jìn)行監(jiān)控的(**心跳機(jī)制)
Sentinel基于心跳機(jī)制監(jiān)測(cè)服務(wù)狀態(tài),每隔1秒向集群的每個(gè)實(shí)例發(fā)送ping命令:
主觀下線:如果某sentinel節(jié)點(diǎn)發(fā)現(xiàn)某實(shí)例未在規(guī)定時(shí)間響應(yīng),則認(rèn)為該實(shí)例主觀下線。
客觀下線:若超過(guò)指定數(shù)量(quorum)的sentinel都認(rèn)為該實(shí)例主觀下線,則該實(shí)例客觀下線。quorum值最好超過(guò)Sentinel實(shí)例數(shù)量的一半。
3.2.2選主規(guī)則
一旦發(fā)現(xiàn)主節(jié)點(diǎn)客觀下線了。哨兵會(huì)推舉新的主節(jié)點(diǎn),選主規(guī)則如下:
判斷主與從節(jié)點(diǎn)斷開(kāi)時(shí)間長(zhǎng)短,如超過(guò)指定值就排除該從節(jié)點(diǎn)
然后判斷從節(jié)點(diǎn)的slave-priority值,越小優(yōu)先級(jí)越高
如果slave-prority一樣,則判斷slave節(jié)點(diǎn)的offset值,越大(說(shuō)明從節(jié)點(diǎn)數(shù)據(jù)與主節(jié)點(diǎn)越相近) 優(yōu)先級(jí)越高
最后是判斷slave節(jié)點(diǎn)的運(yùn)行id大小,越小優(yōu)先級(jí)越高。
3.3 集群(哨兵模式)腦裂
如果此時(shí)原本的主節(jié)點(diǎn)(暫時(shí)稱為A)因?yàn)榫W(wǎng)絡(luò)問(wèn)題,使得主從節(jié)點(diǎn)處在不同的網(wǎng)絡(luò)分區(qū),哨兵監(jiān)測(cè)不到主節(jié)點(diǎn)(沒(méi)有回應(yīng)心跳),那么哨兵便會(huì)進(jìn)行選舉出一個(gè)新的主節(jié)點(diǎn)(暫時(shí)稱為B),這樣就存在了兩個(gè)主節(jié)點(diǎn),像是大腦分兩列了一樣。等A節(jié)點(diǎn)網(wǎng)絡(luò)恢復(fù)之后才會(huì)由主節(jié)點(diǎn)降為從節(jié)點(diǎn)。這個(gè)過(guò)程稱為腦裂。
當(dāng)然如果是哨兵監(jiān)測(cè)不到從節(jié)點(diǎn),則會(huì)去除這個(gè)從節(jié)點(diǎn)
3.3.1 腦裂產(chǎn)生的流程
上圖是一個(gè)正常情況下的哨兵模式,但是由于網(wǎng)絡(luò)問(wèn)題,沒(méi)有回應(yīng)心跳,那么哨兵便會(huì)進(jìn)行選舉出一個(gè)新的主節(jié)點(diǎn)(暫時(shí)稱為B),這樣就存在了兩個(gè)主節(jié)點(diǎn),像是大腦分兩列了一樣。如下圖:
就這樣上圖就存在了兩個(gè)主節(jié)點(diǎn),像是大腦分兩列了一樣,且此時(shí)客戶端還是連接的第一個(gè)master主節(jié)點(diǎn),并繼續(xù)寫(xiě)數(shù)據(jù),等到網(wǎng)絡(luò)恢復(fù)后第一個(gè)master會(huì)自動(dòng)把自己變?yōu)閺墓?jié)點(diǎn)(我們暫時(shí)叫從節(jié)點(diǎn)A)如下圖:
從節(jié)點(diǎn)A向主節(jié)點(diǎn)同步數(shù)據(jù)時(shí),由于發(fā)現(xiàn)數(shù)據(jù)不一致,就會(huì)刪除自己原來(lái)的數(shù)據(jù),進(jìn)行同步,造成數(shù)據(jù)丟失的問(wèn)題
3.3.2 集群(哨兵模式)腦裂解決方案
解決方案有兩種,對(duì)應(yīng)著redis的兩個(gè)配置參數(shù):
1. min-replicas-to-write 1 表示最少的slave節(jié)點(diǎn)為1個(gè)
2. min-replicas-max-lag 5 表示數(shù)據(jù)復(fù)制和同步的延遲不能超過(guò)5秒
如果我們選了第一種解決方案,那么當(dāng)哨兵聯(lián)系不上A節(jié)點(diǎn)時(shí),因?yàn)锳節(jié)點(diǎn)沒(méi)有slave了,此時(shí)數(shù)據(jù)過(guò)來(lái),A節(jié)點(diǎn)會(huì)拒絕被寫(xiě)入數(shù)據(jù),那么發(fā)送數(shù)據(jù)的服務(wù)方就會(huì)意識(shí)到數(shù)據(jù)沒(méi)有正常發(fā)送,之后會(huì)采取相應(yīng)的數(shù)據(jù)重傳之類的解決方案。
如果我們選了第二種解決方案,那么就相當(dāng)于限制了一開(kāi)始A節(jié)點(diǎn)的網(wǎng)絡(luò)情況,發(fā)現(xiàn)網(wǎng)絡(luò)情況不好,就拒絕被寫(xiě)入數(shù)據(jù)。
其實(shí)就是分別針對(duì)腦裂時(shí)的2個(gè)特點(diǎn):A節(jié)點(diǎn)(第一個(gè)主節(jié)點(diǎn))網(wǎng)絡(luò)有問(wèn)題,和因?yàn)榫W(wǎng)絡(luò)問(wèn)題導(dǎo)致的和從節(jié)點(diǎn)、哨兵斷開(kāi)聯(lián)系而進(jìn)行的情況判斷,如果發(fā)現(xiàn)符合這兩個(gè)特點(diǎn)之一,那么就拒絕被寫(xiě)入數(shù)據(jù),防止后來(lái)數(shù)據(jù)丟失。
4.分片集群
4.1 分片集群結(jié)構(gòu)
它的結(jié)構(gòu)特點(diǎn)為:
集群中有多個(gè)master,每個(gè)master保存不同數(shù)據(jù),且每個(gè)master都可以有多個(gè)slave節(jié)點(diǎn)。這樣就解決了海量數(shù)據(jù)存儲(chǔ),高并發(fā)讀寫(xiě)的問(wèn)題。相當(dāng)于把主從模式概括進(jìn)來(lái)了。
不再需要哨兵,直接master之間通過(guò)ping監(jiān)測(cè)彼此健康狀態(tài)。只要超過(guò)一定數(shù)量的master節(jié)點(diǎn)認(rèn)為某個(gè)master節(jié)點(diǎn)宕機(jī)了,那么那個(gè)節(jié)點(diǎn)就客觀下線了。相當(dāng)于變形的哨兵模式。
客戶端請(qǐng)求可以訪問(wèn)集群任意節(jié)點(diǎn),經(jīng)過(guò)一定的路由規(guī)則,最終都會(huì)被轉(zhuǎn)發(fā)到正確節(jié)點(diǎn)。
4.2 路由規(guī)則
Redis 分片集群引入了哈希槽的概念,Redis 集群[3]有 16384 個(gè)哈希槽,每個(gè) key通過(guò) CRC16 校驗(yàn)后對(duì) 16384 取模來(lái)決定放置哪個(gè)槽,集群的每個(gè)節(jié)點(diǎn)負(fù)責(zé)一部分 hash 槽。這樣能保證客戶端請(qǐng)求不沖突地正確轉(zhuǎn)發(fā)到redis的某個(gè)master節(jié)點(diǎn)上。
4.3 分片集群優(yōu)缺點(diǎn)
優(yōu)點(diǎn):解決了系統(tǒng)的海量數(shù)據(jù)存儲(chǔ)、高可用、高并發(fā)讀寫(xiě)的問(wèn)題。
缺點(diǎn):集群維護(hù)很麻煩,而且集群之間的通信和心跳檢測(cè)消耗大量的網(wǎng)絡(luò)帶寬,無(wú)法使用lua腳本和事務(wù)。
5. 相關(guān)面試題
5.1 Redis集群有哪些方案?
在Redis中提供的集群方案總共有三種:
主從復(fù)制、
哨兵模式、
Redis分片集群
5.2 介紹一下主從同步
單節(jié)點(diǎn)Redis的并發(fā)能力是有上限的,要進(jìn)一步提高Redis的并發(fā)能力,可以搭建主從集群,實(shí)現(xiàn)讀寫(xiě)分離。一般都是一主多從,主節(jié)點(diǎn)負(fù)責(zé)寫(xiě)數(shù)據(jù),從節(jié)點(diǎn)負(fù)責(zé)讀數(shù)據(jù),主節(jié)點(diǎn)寫(xiě)入數(shù)據(jù)之后,需要把數(shù)據(jù)同步到從節(jié)點(diǎn)中。
5.3 說(shuō)一下主從同步數(shù)據(jù)的流程
主從同步分為了兩個(gè)階段,一個(gè)是全量同步,一個(gè)是增量同步。
全量同步是指從節(jié)點(diǎn)第一次與主節(jié)點(diǎn)建立連接的時(shí)候使用全量同步,流程是這樣的:
**第一:**從節(jié)點(diǎn)請(qǐng)求主節(jié)點(diǎn)同步數(shù)據(jù),其中從節(jié)點(diǎn)會(huì)攜帶自己的replication id和offset偏移量。
**第二:**主節(jié)點(diǎn)判斷是否是第一次請(qǐng)求,主要判斷的依據(jù)就是,主節(jié)點(diǎn)與從節(jié)點(diǎn)是否是同一個(gè)replication id,如果不是,就說(shuō)明是第一次同步,那主節(jié)點(diǎn)就會(huì)把自己的replication id和offset發(fā)送給從節(jié)點(diǎn),讓從節(jié)點(diǎn)與主節(jié)點(diǎn)的信息保持一致。
**第三:**在同時(shí)主節(jié)點(diǎn)會(huì)執(zhí)行bgsave,生成rdb文件后,發(fā)送給從節(jié)點(diǎn)去執(zhí)行,從節(jié)點(diǎn)先把自己的數(shù)據(jù)清空,然后執(zhí)行主節(jié)點(diǎn)發(fā)送過(guò)來(lái)的rdb文件,這樣就保持了一致。
當(dāng)然,如果在rdb生成執(zhí)行期間,依然有請(qǐng)求到了主節(jié)點(diǎn),而主節(jié)點(diǎn)會(huì)以命令的方式記錄到緩沖區(qū),緩沖區(qū)是一個(gè)日志文件(repl_backlog),最后把這個(gè)日志文件發(fā)送給從節(jié)點(diǎn),這樣就能保證主節(jié)點(diǎn)與從節(jié)點(diǎn)完全一致了,后期再同步數(shù)據(jù)的時(shí)候,都是依賴于這個(gè)日志文件,這個(gè)就是全量同步
增量同步指的是,當(dāng)從節(jié)點(diǎn)服務(wù)重啟之后,數(shù)據(jù)就不一致了,所以這個(gè)時(shí)候,從節(jié)點(diǎn)會(huì)請(qǐng)求主節(jié)點(diǎn)同步數(shù)據(jù),主節(jié)點(diǎn)還是判斷不是第一次請(qǐng)求,不是第一次就獲取從節(jié)點(diǎn)的offset值,然后主節(jié)點(diǎn)從命令日志中獲取offset值之后的數(shù)據(jù),發(fā)送給從節(jié)點(diǎn)進(jìn)行數(shù)據(jù)同步。
5.4 怎么保證Redis的高并發(fā)、高可用
答:使用哨兵模式搭建redis集群
詳細(xì)回答:
首先可以搭建主從集群,再加上使用redis中的哨兵模式,哨兵模式可以實(shí)現(xiàn)主從集群的自動(dòng)故障恢復(fù),里面就包含了對(duì)主從服務(wù)的監(jiān)控、自動(dòng)故障恢復(fù)、通知;如果master故障,Sentinel會(huì)將一個(gè)slave提升為master。當(dāng)故障實(shí)例恢復(fù)后也以新的master為主;同時(shí)Sentinel也充當(dāng)Redis客戶端的服務(wù)發(fā)現(xiàn)來(lái)源,當(dāng)集群發(fā)生故障轉(zhuǎn)移時(shí),會(huì)將最新信息推送給Redis的客戶端,所以一般項(xiàng)目都會(huì)采用哨兵的模式來(lái)保證redis的高并發(fā)高可用。
5.5 你使用redis是單點(diǎn)還是集群,哪種集群
答:主從(1主1從)+哨兵就可以了。單節(jié)點(diǎn)不超過(guò)10G內(nèi)存,如果Redis內(nèi)存不足則可以給不同服務(wù)分配獨(dú)立的Redis主從節(jié)點(diǎn)
詳細(xì)回答:
候選人:我當(dāng)時(shí)使用的是主從(1主1從)加哨兵。一般單節(jié)點(diǎn)不超過(guò)10G內(nèi)存,如果Redis內(nèi)存不足則可以給不同服務(wù)分配獨(dú)立的Redis主從節(jié)點(diǎn)。盡量不做分片集群。因?yàn)榧壕S護(hù)起來(lái)比較麻煩,并且集群之間的心跳檢測(cè)和數(shù)據(jù)通信會(huì)消耗大量的網(wǎng)絡(luò)帶寬,也沒(méi)有辦法使用lua腳本和事務(wù)
5.6 redis集群腦裂,該怎么解決呢?
集群腦裂是由于主節(jié)點(diǎn)和從節(jié)點(diǎn)和sentinel處于不同的網(wǎng)絡(luò)分區(qū),使得sentinel沒(méi)有能夠心跳感知到主節(jié)點(diǎn),所以通過(guò)選舉的方式提升了一個(gè)從節(jié)點(diǎn)為主,這樣就存在了兩個(gè)master,就像大腦分裂了一樣,這樣會(huì)導(dǎo)致客戶端還在老的主節(jié)點(diǎn)那里寫(xiě)入數(shù)據(jù),新節(jié)點(diǎn)無(wú)法同步數(shù)據(jù),當(dāng)網(wǎng)絡(luò)恢復(fù)后,Sentinel會(huì)將老的主節(jié)點(diǎn)降為從節(jié)點(diǎn),這時(shí)再?gòu)男耺aster同步數(shù)據(jù),就會(huì)導(dǎo)致數(shù)據(jù)丟失
redis集群腦裂問(wèn)題,在項(xiàng)目中很少見(jiàn),不過(guò)是這樣解決的
**解決:**我們可以修改redis的配置,可以設(shè)置最少的從節(jié)點(diǎn)數(shù)量以及縮短主從數(shù)據(jù)同步的延遲時(shí)間不能超過(guò)5秒,達(dá)不到要求就拒絕請(qǐng)求,就可以避免大量的數(shù)據(jù)丟失
(如果這里看不懂請(qǐng)重新看 3.3.2)
5.7 redis的分片集群有什么作用
分片集群主要解決的是,海量數(shù)據(jù)存儲(chǔ)的問(wèn)題,集群中有多個(gè)master,每個(gè)master保存不同數(shù)據(jù),并且還可以給每個(gè)master設(shè)置多個(gè)slave節(jié)點(diǎn),就可以繼續(xù)增大集群的高并發(fā)能力。同時(shí)每個(gè)master之間通過(guò)ping監(jiān)測(cè)彼此健康狀態(tài),就類似于哨兵模式了。當(dāng)客戶端請(qǐng)求可以訪問(wèn)集群任意節(jié)點(diǎn),最終都會(huì)被轉(zhuǎn)發(fā)到正確節(jié)點(diǎn)
5.8 Redis分片集群中數(shù)據(jù)是怎么存儲(chǔ)和讀取的?
在redis集群中是這樣的
Redis 集群引入了哈希槽的概念,有 16384 個(gè)哈希槽,集群中每個(gè)主節(jié)點(diǎn)綁定了一定范圍的哈希槽范圍, key通過(guò) CRC16 校驗(yàn)后對(duì) 16384 取模來(lái)決定放置哪個(gè)槽,通過(guò)槽找到對(duì)應(yīng)的節(jié)點(diǎn)進(jìn)行存儲(chǔ)。
-
服務(wù)器
+關(guān)注
關(guān)注
13文章
9753瀏覽量
87582 -
內(nèi)存
+關(guān)注
關(guān)注
8文章
3117瀏覽量
75127 -
集群
+關(guān)注
關(guān)注
0文章
102瀏覽量
17410 -
Redis
+關(guān)注
關(guān)注
0文章
385瀏覽量
11382
原文標(biāo)題:redis三種集群方案詳解(主從復(fù)制、哨兵模式、分片集群)
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
啟動(dòng)Redis的三種方法
Redis實(shí)現(xiàn)限流的三種方式分享
redis集群狀態(tài)查看命令
redis集群中的hash一致性算法的理解
redis集群性能測(cè)試工具有哪些
redis查看集群狀態(tài)命令
性能與可靠性并重,F(xiàn)lexus X 實(shí)例助力 Redis 三主三從集群高效運(yùn)行

評(píng)論