1. 單機(jī)故障
如果發(fā)生機(jī)器故障,例如磁盤損壞,主板損壞等,未能在短時(shí)間內(nèi)修復(fù)好,客戶端將無法連接redis。
當(dāng)然如果僅僅是redis節(jié)點(diǎn)掛掉了,可以進(jìn)行問題排查然后重啟,姑且不考慮這段時(shí)間對外服務(wù)的可用性,那還是可以接受的。而發(fā)生機(jī)器故障,基本是無濟(jì)于事。除非把redis遷移到另一臺機(jī)器上,并且還要考慮數(shù)據(jù)同步的問題。
2. 容量瓶頸
假如一臺機(jī)器是16G內(nèi)存,redis使用了12G內(nèi)存,而其他應(yīng)用還需要使用內(nèi)存,假設(shè)我們總共需要60G內(nèi)存要如何去做呢,是否有必要購買64G內(nèi)存的機(jī)器呢?
3. QPS瓶頸
redis官方數(shù)據(jù)顯示可以達(dá)到10w的QPS,如果業(yè)務(wù)需要100w的QPS怎么去做呢?
關(guān)于容量瓶頸和QPS瓶頸是redis分布式需要解決的問題,而機(jī)器故障就是高可用的問題了。
2、單機(jī)故障解決方法在分布式系統(tǒng)中為了解決單點(diǎn)問題,通常會把數(shù)據(jù)復(fù)制多個(gè)副本部署到其他機(jī)器(主從模式),滿足故障恢復(fù)和負(fù)載均衡的需求。
redis也是如此,它為我們提供了復(fù)制功能,實(shí)現(xiàn)了相同數(shù)據(jù)的多個(gè)redis副本(復(fù)制功能是高可用redis的基礎(chǔ),哨兵和集群都是在復(fù)制的基礎(chǔ)上實(shí)現(xiàn)高可用的)。
但是這樣會有如下問題,多個(gè)副本之間的數(shù)據(jù)如何保持一致呢?數(shù)據(jù)讀寫操作可以發(fā)送給所有實(shí)例呢?
實(shí)際上,Redis 提供了主從庫模式,以保證數(shù)據(jù)副本的一致,主從庫之間采用的是讀寫分離的方式。
即:
說明:?
在了解 Redis 的主從復(fù)制之前,讓我們先來理解一下現(xiàn)代分布式系統(tǒng)的理論基石——CAP 原理。
CAP 原理是分布式存儲的理論基石:
分布式系統(tǒng)的節(jié)點(diǎn)往往都是分布在不同的機(jī)器上進(jìn)行網(wǎng)絡(luò)隔離開的,這意味著必然會有網(wǎng)絡(luò)斷開的風(fēng)險(xiǎn),這個(gè)網(wǎng)絡(luò)斷開的場景的專業(yè)詞匯叫做”網(wǎng)絡(luò)分區(qū)“。
在網(wǎng)絡(luò)分區(qū)發(fā)生時(shí),兩個(gè)分布式節(jié)點(diǎn)無法進(jìn)行通信,我們對一個(gè)節(jié)點(diǎn)進(jìn)行的修改操作將無法同步到另外一個(gè)節(jié)點(diǎn),所以數(shù)據(jù)的”一致性“將無法滿足,因?yàn)閮蓚€(gè)分布式節(jié)點(diǎn)的數(shù)據(jù)不再保持一致。除非我們犧牲”可用性“,也就是暫停分布式節(jié)點(diǎn)服務(wù),在網(wǎng)絡(luò)分區(qū)發(fā)生時(shí),不再提供修改數(shù)據(jù)的功能,直到網(wǎng)絡(luò)狀況完全恢復(fù)正常再繼續(xù)對外提供服務(wù)。
一句話概括 CAP 原理就是——網(wǎng)絡(luò)分區(qū)發(fā)生時(shí),一致性和可用性兩難全。
2、Redis主從同步最終一致性Redis 的主從數(shù)據(jù)是 異步 復(fù)制的,所以分布式的 Redis 系統(tǒng)并不滿足一致性要求。當(dāng)客戶端在 Redis 的主節(jié)點(diǎn)修改了數(shù)據(jù)后,立即返回,即使在主從網(wǎng)絡(luò)斷開的情況下,主節(jié)點(diǎn)依舊可以正常對外提供服務(wù),所以 Redis 滿足可用性。
而 Redis 其實(shí)是保證 ”最終一致性“,從節(jié)點(diǎn)會努力追趕主節(jié)點(diǎn),最終從節(jié)點(diǎn)的狀態(tài)會和主節(jié)點(diǎn)的狀態(tài)保持一致。如果網(wǎng)絡(luò)斷開了,主從節(jié)點(diǎn)的數(shù)據(jù)將會出現(xiàn)大量不一致,一旦網(wǎng)絡(luò)恢復(fù),從節(jié)點(diǎn)會采用多種策略努力追趕上落后的數(shù)據(jù),繼續(xù)盡力保持和主節(jié)點(diǎn)一致。
三、主從復(fù)制類型 1、主備與主從1. 主備
請求都只能打到Master主節(jié)點(diǎn)上,備機(jī)只是等主機(jī)掛了后來自動升級為客戶端繼續(xù)提供服務(wù)。也就是說他不會為主節(jié)點(diǎn)分?jǐn)傉埱髩毫Α?/p>
2. 主從
讀請求會均攤到主節(jié)點(diǎn)和從節(jié)點(diǎn)上,而不是等主機(jī)掛了才提供服務(wù)。寫請求在master上進(jìn)行,然后同步到slaver。讀請求會分?jǐn)偅热?0w個(gè)請求,一主雙從的話,可能M上3w個(gè),兩個(gè)S上處理6w個(gè),他會為主節(jié)點(diǎn)分?jǐn)倝毫ΑK钥梢越鉀Q單點(diǎn)故障問題。
2、主從復(fù)制三種類型1.?同步阻塞
這種方式講究強(qiáng)一致性,必須等所有Slave都寫入成功后我才會給客戶端響應(yīng),否則一直阻塞。也是CAP中的C。
原理圖:
2. 異步非阻塞
Redis采取的這種方式。沒有采取下面同步阻塞mq的方式可能也是因?yàn)樾拾桑驗(yàn)镽edis就是要高效。客戶端發(fā)完請求到Redis Master后,立馬給客戶端返回,我不管你Slaver是否同步完成。保留CAP的A,舍棄C。
原理圖:
3. 同步阻塞MQ
大數(shù)據(jù)hive采取的就是這種方式,他會保證最終一致性。相對于第二種方式好處在于能保證數(shù)據(jù)的最終一致性,壞處在于沒第二種方式高效,但第二種存在丟數(shù)據(jù)的風(fēng)險(xiǎn)。
主從復(fù)制其實(shí)就是實(shí)現(xiàn)高可用(雖然是人工操作),避免單點(diǎn)故障問題。掛掉一個(gè)節(jié)點(diǎn),我其他節(jié)點(diǎn)可以接著提供服務(wù),但是明顯缺點(diǎn)發(fā)現(xiàn)是Slave掛掉還好,Master掛掉可就難受了,Slave太多的話那就夠運(yùn)維折騰的了,這時(shí)候就有了哨兵。 同時(shí),Redis雖然讀取寫入的速度都特別快,但是也會產(chǎn)生讀壓力特別大的情況,主從復(fù)制也能夠分擔(dān)讀壓力。
主從復(fù)制原理圖:
其實(shí)就跟MySQL一個(gè)道理,mysql是靠binlog,而Redis靠的是rdb文件和aof文件。
2、主從復(fù)制實(shí)現(xiàn)原理總的來說主從復(fù)制功能的詳細(xì)步驟可以分為7個(gè)步驟:
設(shè)置主節(jié)點(diǎn)的地址和端口-》建立套接字鏈接-》發(fā)送PING命令-》權(quán)限驗(yàn)證-》同步-》命令傳播
接下來分別敘述每個(gè)步驟,整個(gè)流程圖如下:
假設(shè)在本地機(jī)開啟兩個(gè)Redis節(jié)點(diǎn),分別監(jiān)聽:
1. 設(shè)置主服務(wù)器的地址和端口
第一步首先是在從服務(wù)器設(shè)置需要同步的主服務(wù)器信息,包括機(jī)器IP,端口。
主從復(fù)制的開啟,完全是從節(jié)點(diǎn)發(fā)起;不需要我們在主節(jié)點(diǎn)做任何事情。
從節(jié)點(diǎn)開啟主從復(fù)制,有3種方式:
(1)配置文件
在從服務(wù)器的配置文件中加入:
slaveof masterip masterport
(2)啟動命令
redis-server啟動命令后加入:
slaveof masterip masterport
(3)客戶端命令
Redis服務(wù)器啟動后,直接通過客戶端執(zhí)行命令:
slaveof masterip masterport
則該Redis實(shí)例稱為從節(jié)點(diǎn)。
上述3種方法是等效的,下面以客戶端命令的方式為例,看一下當(dāng)執(zhí)行了slaveof后,Redis主節(jié)點(diǎn)和從節(jié)點(diǎn)的變化。從服務(wù)器會將主服務(wù)器的ip地址和端口號保存到服務(wù)器狀態(tài)的屬性里面,可以使用Redis命令 info replication 分別查看從服務(wù)器和主服務(wù)器的主從信息。
2. 建立套接字連接
在slaveof命令執(zhí)行之后,從服務(wù)器會根據(jù)設(shè)置的ip和端口,向主服務(wù)器建立socket連接。
在6380從服務(wù)器里面執(zhí)行完 slave of 127.0.0.1 6379 后意味著,從服務(wù)器向主服務(wù)器發(fā)起 socket 連接。
在執(zhí)行info Replication 命令分別查看從服務(wù)器的主從信息:
而6379服務(wù)器已經(jīng)成為主服務(wù)器角色:?
3. 發(fā)送PING命令
從節(jié)點(diǎn)成為了主節(jié)點(diǎn)的客戶端之后,發(fā)送 ping 命令進(jìn)行首次請求,目的是:檢查socket連接是否可用,以及主節(jié)點(diǎn)當(dāng)前是否能夠處理請求。
從節(jié)點(diǎn)發(fā)送 ping 命令后,可能出現(xiàn)3種情況:
4. 身份驗(yàn)證
如果從節(jié)點(diǎn)中設(shè)置了masterauth選項(xiàng),則從節(jié)點(diǎn)需要向主節(jié)點(diǎn)進(jìn)行身份驗(yàn)證;沒有設(shè)置該選項(xiàng),則不需要驗(yàn)證。從節(jié)點(diǎn)進(jìn)行身份驗(yàn)證是通過向主節(jié)點(diǎn)發(fā)送auth命令進(jìn)行的,auth命令的參數(shù)即為配置文件中的masterauth的值。
如果主節(jié)點(diǎn)設(shè)置密碼的狀態(tài),與從節(jié)點(diǎn)masterauth的狀態(tài)一致(一致是指都存在,且密碼相同,或者都不存在),則身份驗(yàn)證通過,復(fù)制過程繼續(xù);如果不一致,則從節(jié)點(diǎn)斷開socket連接,并重連。
5. 同步
同步就是將從節(jié)點(diǎn)的數(shù)據(jù)庫狀態(tài)更新成主節(jié)點(diǎn)當(dāng)前的數(shù)據(jù)庫狀態(tài)。具體執(zhí)行的方式是:從節(jié)點(diǎn)向主節(jié)點(diǎn)發(fā)送psync命令(Redis2.8以前是sync命令),開始同步。
數(shù)據(jù)同步階段是主從復(fù)制最核心的階段,根據(jù)主從節(jié)點(diǎn)當(dāng)前狀態(tài)的不同,可以分為 全量復(fù)制 和 部分復(fù)制。
6. 命令傳播
經(jīng)過上面同步操作,此時(shí)主從的數(shù)據(jù)庫狀態(tài)其實(shí)已經(jīng)一致了,但這種一致的狀態(tài)并不是一成不變的。
在完成同步之后,也許主服務(wù)器馬上就接受到了新的寫命令,執(zhí)行完該命令后,主從的數(shù)據(jù)庫狀態(tài)又不一致。
數(shù)據(jù)同步階段完成后,主從節(jié)點(diǎn)進(jìn)入命令傳播階段;在這個(gè)階段主節(jié)點(diǎn)將自己執(zhí)行的寫命令發(fā)送給從節(jié)點(diǎn),從節(jié)點(diǎn)接受命令并執(zhí)行,從而保證主從節(jié)點(diǎn)數(shù)據(jù)的一致性。
另外命令傳播我們需要關(guān)注兩個(gè)點(diǎn):延遲與不一致 和 心跳機(jī)制。
需要注意的是,命令傳播是異步的過程,即主節(jié)點(diǎn)發(fā)送寫命令后并不會等待從節(jié)點(diǎn)的回復(fù);因此實(shí)際上主從節(jié)點(diǎn)之間很難保持實(shí)時(shí)的一致性,延遲在所難免。數(shù)據(jù)不一致的程度,與主從節(jié)點(diǎn)之間的網(wǎng)路狀況、主節(jié)點(diǎn)寫命令執(zhí)行頻率、以及主節(jié)點(diǎn)中repl-disable-tcp-nodelay 配置等有關(guān)。
repl-disable-tcp-nodelay 配置如下:
概括來說就是:前者關(guān)注性能,后者關(guān)注一致性。
一般來說,只有當(dāng)應(yīng)用對Redis數(shù)據(jù)不一致的容忍度較高,且主從節(jié)點(diǎn)之間網(wǎng)絡(luò)狀態(tài)不好時(shí),才會設(shè)置為yes;多數(shù)情況使用默認(rèn)值no
命令傳播階段,從服務(wù)器會利用心跳檢測機(jī)制定時(shí)的向主服務(wù)發(fā)送消息。
3、Redis主從復(fù)制結(jié)構(gòu)Redis的主從結(jié)構(gòu)可以采用一主一從、一主多從或者樹狀主從結(jié)構(gòu),Redis主從復(fù)制可以根據(jù)是否是全量分為全量同步和增量同步。
一主一從:
一主多從:
樹狀主從結(jié)構(gòu):
在Redis2.8以前,從接待你向主節(jié)點(diǎn)發(fā)送sync命令請求同步數(shù)據(jù),此時(shí)的同步方式是全量復(fù)制;在Redis2.8及以后,從節(jié)點(diǎn)可以發(fā)送psync命令請求同步數(shù)據(jù),此時(shí)根據(jù)主從節(jié)點(diǎn)當(dāng)前狀態(tài)的不同,同步方式可能是全量復(fù)制或部分復(fù)制。
全量復(fù)制:用于初次復(fù)制或其他無法進(jìn)行部分復(fù)制的情況,將主節(jié)點(diǎn)中的所有數(shù)據(jù)都發(fā)送給從節(jié)點(diǎn),是一個(gè)非常重型的操作。
部分復(fù)制:用于網(wǎng)絡(luò)中斷等情況后的復(fù)制,只將中斷期間主節(jié)點(diǎn)執(zhí)行的寫命令發(fā)送給從節(jié)點(diǎn),與全量復(fù)制相比更加高效,需要注意的是,如果網(wǎng)絡(luò)中斷時(shí)間過長,導(dǎo)致主節(jié)點(diǎn)沒有能夠完整地保存中斷期間執(zhí)行地寫命令,則無法進(jìn)行部分復(fù)制,仍使用全量復(fù)制。
1. 全量同步
Redis全量復(fù)制一般發(fā)生在Slave初始化階段,這時(shí)Slave需要將Master上的所有數(shù)據(jù)都復(fù)制一份。
具體步驟如下:?
完成上面幾個(gè)步驟后就完成了從服務(wù)器數(shù)據(jù)初始化的所有操作,從服務(wù)器此時(shí)可以接收來自用戶的讀請求。
2. 增量同步
由于全量復(fù)制在主節(jié)點(diǎn)數(shù)據(jù)量較大時(shí)效率太低,因此Redis2.8開始提供部分復(fù)制,用于處理網(wǎng)絡(luò)中斷時(shí)的數(shù)據(jù)同步。
部分復(fù)制的實(shí)現(xiàn),依賴于三個(gè)重量的概念:復(fù)制偏移量、復(fù)制積壓緩沖區(qū)、服務(wù)器運(yùn)行id(runid)
1)復(fù)制偏移量
執(zhí)行復(fù)制的雙方,主從節(jié)點(diǎn),分別會維護(hù)一個(gè)復(fù)制偏移量offset:
offset用于判斷主從節(jié)點(diǎn)的數(shù)據(jù)庫狀態(tài)是否一致:如果二者offset相同,則一致;如果offset不同,則不一致,此時(shí)可以根據(jù)兩個(gè)offset找出從節(jié)點(diǎn)缺少的那部分?jǐn)?shù)據(jù)。例如,如果主節(jié)點(diǎn)offset是1000,而從節(jié)點(diǎn)的offset是500,那么部分復(fù)制舊需要將offset為501-1000的數(shù)據(jù)傳遞給從節(jié)點(diǎn)。而offset為501-1000的數(shù)據(jù)存儲的位置,就是下面要介紹的復(fù)制積壓緩沖區(qū)。
2)復(fù)制積壓緩沖區(qū)(replication-backlog-buffer)
主節(jié)點(diǎn)內(nèi)部維護(hù)了一個(gè)固定長度的、先進(jìn)先出(FIFO)隊(duì)列作為復(fù)制積壓緩沖區(qū),默認(rèn)大小為1MB,在主節(jié)點(diǎn)進(jìn)行命令傳播時(shí),不僅會將寫命令同步到從節(jié)點(diǎn),還會將寫命令寫入復(fù)制積壓緩沖區(qū)。
由于復(fù)制積壓緩沖區(qū)定長且是先進(jìn)先出,所以他保存的是主節(jié)點(diǎn)最近執(zhí)行的寫命令;時(shí)間較早的寫命令會被擠出緩沖區(qū)。因此,當(dāng)主從節(jié)點(diǎn)offset的差距過大超過緩沖區(qū)長度時(shí),將無法執(zhí)行部分復(fù)制,只能執(zhí)行全量復(fù)制。
為了提高網(wǎng)絡(luò)中斷時(shí)部分復(fù)制執(zhí)行的概率,可以根據(jù)需要增大復(fù)制積壓緩沖區(qū)的大小(通過配置repl-backlog-size);例如如果網(wǎng)絡(luò)中斷的平均時(shí)間是60s,而主節(jié)點(diǎn)平均每秒產(chǎn)生的寫命令(某些特定協(xié)議格式)所占據(jù)的字節(jié)數(shù)為100KB,則復(fù)制積壓緩沖區(qū)的平均需求為6MB,保險(xiǎn)起見,可以設(shè)置為12MB,來保證絕大多數(shù)斷線情況都可以使用部分復(fù)制。
從節(jié)點(diǎn)將offset發(fā)送給主節(jié)點(diǎn)后,主節(jié)點(diǎn)根據(jù)offset和緩沖區(qū)大小決定能否執(zhí)行部分復(fù)制:
3)服務(wù)器運(yùn)行ID(runid)
每個(gè)Redis節(jié)點(diǎn),都有其運(yùn)行ID,運(yùn)行ID由節(jié)點(diǎn)在啟動時(shí)自動生成,主節(jié)點(diǎn)會將自己的運(yùn)行ID發(fā)送給從節(jié)點(diǎn),從節(jié)點(diǎn)會將主節(jié)點(diǎn)的運(yùn)行ID存起來。從節(jié)點(diǎn)Redis斷開重連的時(shí)候,就是根據(jù)運(yùn)行ID來判斷同步的進(jìn)度:
如果從節(jié)點(diǎn)保存的runid與主節(jié)點(diǎn)現(xiàn)在的runid相同,說明主從節(jié)點(diǎn)之前同步過,主節(jié)點(diǎn)會繼續(xù)嘗試使用部分復(fù)制(到底能不能部分復(fù)制還要看offset和復(fù)制積壓緩沖區(qū)的情況);
如果從節(jié)點(diǎn)保存的runid與主節(jié)點(diǎn)現(xiàn)在的runid不同,說明從節(jié)點(diǎn)在斷線前同步的Redis節(jié)點(diǎn)并不是當(dāng)前的主節(jié)點(diǎn),只能進(jìn)行全量復(fù)制。
4、psync命令的執(zhí)行在了解了復(fù)制偏移量、復(fù)制積壓緩沖區(qū)、節(jié)點(diǎn)運(yùn)行id之后,這里psync命令的參數(shù)和返回值,從而說明psync命令執(zhí)行過程中,主從節(jié)點(diǎn)是如何確定使用全量復(fù)制還是部分復(fù)制的。
psync命令流程圖如下:
psync命令的大體流程如下:
如果從節(jié)點(diǎn)之前沒有復(fù)制過任何主節(jié)點(diǎn),或者之前執(zhí)行過slaveof no one 命令,從節(jié)點(diǎn)就會向主節(jié)點(diǎn)發(fā)送psync 命令,請求主節(jié)點(diǎn)進(jìn)行數(shù)據(jù)的全量同步。
如果前面從節(jié)點(diǎn)已經(jīng)同步過部分?jǐn)?shù)據(jù),此時(shí)從節(jié)點(diǎn)就會發(fā)送psync runid offset 命令給主節(jié)點(diǎn),其中runid是上一次主節(jié)點(diǎn)的運(yùn)行ID,offset是當(dāng)前從節(jié)點(diǎn)的復(fù)制偏移量
主節(jié)點(diǎn)收到psync命令后,會出現(xiàn)以下三種可能:
主節(jié)點(diǎn)返回 fullresync runid offset 回復(fù),表示主節(jié)點(diǎn)要求與從節(jié)點(diǎn)進(jìn)行數(shù)據(jù)的完整全量復(fù)制,其中runid表示主節(jié)點(diǎn)的運(yùn)行ID,offset表示當(dāng)前主節(jié)點(diǎn)的復(fù)制偏移量。
如果主服務(wù)器返回+continue,表示從節(jié)點(diǎn)與從節(jié)點(diǎn)會進(jìn)行部分?jǐn)?shù)據(jù)的同步操作,將從節(jié)點(diǎn)缺失的數(shù)據(jù)復(fù)制過來即可。
如果主服務(wù)器返回-err,表示主服務(wù)器的Redis版本低于2.8,無法是別psync命令,此時(shí)從服務(wù)器會向主服務(wù)器發(fā)送sync,進(jìn)行完整的數(shù)據(jù)全量復(fù)制。
Redis通過psnyc命令進(jìn)行全量復(fù)制的過程如下:
通過全量復(fù)制的過程可以看出,全量復(fù)制是非常重型的操作:
心跳檢測機(jī)制的作用有三個(gè):
檢查主從服務(wù)器的網(wǎng)絡(luò)連接狀態(tài),主節(jié)點(diǎn)信息中可以看到所屬的從節(jié)點(diǎn)的連接信息:
state 表示從節(jié)點(diǎn)狀態(tài)、offset表示復(fù)制偏移量、lag表示延遲值(幾秒之前有過心跳檢測機(jī)制)
輔助實(shí)現(xiàn)min-slaves選項(xiàng),Redis.conf 配置文件中有下方兩個(gè)參數(shù):
# 未達(dá)到下面兩個(gè)條件時(shí),寫操作就不會被執(zhí)行
# 最少包含的從服務(wù)器
# min-slaves-to-write 3
# 延遲值
# min-slaves-max-lag 10
如果將兩個(gè)參數(shù)注釋取消,那么如果從服務(wù)器的數(shù)量少于3個(gè),或者三個(gè)從服務(wù)器的延遲(lag)大于等于10秒時(shí),主服務(wù)器都會拒絕執(zhí)行寫命令。
檢測命令丟失時(shí),在從服務(wù)器的連接信息中可以看到復(fù)制偏移量,如果此時(shí)主服務(wù)器的復(fù)制偏移量與從服務(wù)器的復(fù)制偏移量不一致時(shí),主服務(wù)器會補(bǔ)發(fā)缺失的數(shù)據(jù)。
5、無磁盤復(fù)制通常來講,一個(gè)完全重新同步需要在磁盤上創(chuàng)建一個(gè)RDB文件,然后加載這個(gè)文件以便為從服務(wù)器發(fā)送數(shù)據(jù)。如果使用比較低速的磁盤,這種操作會給主服務(wù)器帶來較大的壓力。Redis從2.8.18版本開始嘗試支持無磁盤的復(fù)制。使用這種設(shè)置時(shí),子進(jìn)程直接將RDB通過網(wǎng)絡(luò)發(fā)送給從服務(wù)器,不使用磁盤作為中間存儲,避免了IO性能差問題。
可以使用repl-diskless-sync 配置參數(shù)來啟動無磁盤復(fù)制。使用repl-diskless-sync-delay參數(shù)來配置傳輸開始的延遲時(shí)間,以便等待更多的從服務(wù)器連接上來。
開啟無磁盤復(fù)制:
repl-diskless-sync yes
6、主從復(fù)制架構(gòu)中出現(xiàn)宕機(jī)情況如果在主從復(fù)制架構(gòu)中出現(xiàn)宕機(jī)的情況,需要分情況看:
1. 從Redis宕機(jī)
這個(gè)相對而言比較簡單,在Redis中從庫重新啟動后會自動加入到主從架構(gòu)中,自動完成同步數(shù)據(jù),這是因?yàn)樵赗edis2.8版本后就新增了增量復(fù)制功能,主從斷線后恢復(fù)是通過增量復(fù)制實(shí)現(xiàn)的。所以這種情況無需擔(dān)心。
2. 主Redis宕機(jī)
這個(gè)情況相對而言就會復(fù)雜一些,需要以下2步才能完成:
第一步,在從數(shù)據(jù)庫中執(zhí)行SLAVEOF NO ONE命令,斷開主從關(guān)系并且提升為主庫繼續(xù)服務(wù);
第二步,將主庫修復(fù)重新啟動后,執(zhí)行SLAVEOF命令,將其設(shè)置為其他庫的從庫,這時(shí)數(shù)據(jù)就能更新回來;
這兩個(gè)步驟要通過手動完成恢復(fù),過程其實(shí)是比較麻煩的并且容易出錯,有沒有好辦法解決呢?有的,Redis提供的哨兵(sentinel)功能就可以實(shí)現(xiàn)主Redis宕機(jī)的自動切換。
7、Redis主從復(fù)制總結(jié)1. Redis主從復(fù)制策略
主從剛剛連接的時(shí)候,進(jìn)行全量同步;全同步結(jié)束后,進(jìn)行增量同步。當(dāng)然,如果有需要,slave 在任何時(shí)候都可以發(fā)起全量同步。redis的策略是,無論如何,首先會嘗試進(jìn)行增量同步,如不成功,要求從機(jī)進(jìn)行全量同步。
2. 主從復(fù)制的特點(diǎn)
主從復(fù)制的特點(diǎn):
主從模式并不完美,它也存在許多不足之處,下面做了簡單地總結(jié):
雖然主從模式存在上述不足,但他仍然是實(shí)現(xiàn)分布式集群的基礎(chǔ)。Sentinel哨兵模式同樣是依賴于主從模式實(shí)現(xiàn)。
五、Redis主從復(fù)制實(shí)戰(zhàn) 1、主從復(fù)制配置文件redis.config配置文件相關(guān)配置:
配置主從:
# 相當(dāng)于我們上面客戶端執(zhí)行的REPLICAOF命令,配置到配置文件每次重啟就不用手動再執(zhí)行命令了。
replicaof# master的密碼
masterauth
主從傳輸數(shù)據(jù)這期間,從節(jié)點(diǎn)是否允許對外提供服務(wù):
# 默認(rèn)是ye,允許
slave-serve-stale-data yes
看下面的log(這是我們建立主從關(guān)系的時(shí)候產(chǎn)生的log)。
意思是說在和Master建立連接,獲取完Master數(shù)據(jù)之間,也就是從庫進(jìn)行flush操作之前,是否允許對外繼續(xù)提供請求(就是Slave完成配置之前的那些flush之前的老數(shù)據(jù)是否還允許被訪問)。
是否開啟Slave從節(jié)點(diǎn)也支持寫命令:
# 默認(rèn)只讀,yes代表只讀
slave-read-only yes
先落磁盤再傳輸還是直接網(wǎng)絡(luò)傳輸:
# 默認(rèn)是先落盤,再進(jìn)行網(wǎng)絡(luò)傳輸
repl-diskless-sync no
因?yàn)槟J(rèn)是Master先生成rdb文件到磁盤,這時(shí)候產(chǎn)生一次磁盤IO,然后將磁盤上rdb文件以網(wǎng)絡(luò)的方式傳遞給Slave,這時(shí)候又產(chǎn)生一次IO,如果rdb幾個(gè)GB的話那還不如直接走網(wǎng)絡(luò)傳輸,就不走磁盤io了。 改為yes的話直接Master通過網(wǎng)絡(luò)的方式發(fā)送rdb給Slave。默認(rèn)是no,從日志也可以看出先落盤了
原理圖:
全量還是增量:
repl-backlog-size 1mb
可以發(fā)現(xiàn)比主從復(fù)制原理圖中多了個(gè)隊(duì)列和偏移量。
這個(gè)隊(duì)列代表repl-backlog-size參數(shù)設(shè)置的值大小,是決定全量復(fù)制還是增量復(fù)制的關(guān)鍵參數(shù)。
RDB每次同步到slave的時(shí)候,slave都會記錄一個(gè)offset偏移量,然后每次同步數(shù)據(jù)的時(shí)候都會看隊(duì)列里的數(shù)據(jù)偏移量是否符合slave上次同步的數(shù)據(jù)大小,若符合則增量,否則全量。
舉例:
如果設(shè)置的1MB,你掛了3s鐘,假設(shè)1s鐘就寫了1MB,那么3s鐘的隊(duì)列肯定放不下,這時(shí)候就觸發(fā)全量,所以這個(gè)需要看業(yè)務(wù)調(diào)整大小。
再比如master是100MB數(shù)據(jù),slave也是1MB數(shù)據(jù),然后slave掛了。恢復(fù)的時(shí)候發(fā)現(xiàn)master已經(jīng)有110MB了,但是隊(duì)列大小只有1MB,把隊(duì)列里的數(shù)據(jù)拿來顯然不行,所以會觸發(fā)全量,這只是舉例,其實(shí)不會那么傻的判斷總大小,而是通過偏移量來的。?
2、僅開啟RDB僅僅開啟RDB持久化,關(guān)閉AOF。
首先啟動三個(gè)redis,端口分別是6379、6380、6381。我們這里設(shè)定6379為Master,其余兩個(gè)為Slaver。
1. 如何設(shè)置Slaver
可以看到Redis5.x后開始用REPLICAOF命令代替5.x版本之前的SLAVEOF命令。
2. 設(shè)置Slaver
# 設(shè)置6380是6379的從節(jié)點(diǎn)
127.0.0.1:6380>REPLICAOF localhost 6379
OK
設(shè)置完成后去看6379和6380的log
6379的log:
6380的log:
3. ????在Master執(zhí)行寫命令
127.0.0.1:6379>set k1 123
OK
127.0.0.1:6379>get k1
"123"
4. 在Slave(6380)上查看是否同步過來了
127.0.0.1:6380>keys *
1) "k1"
127.0.0.1:6380>get k1
"123"
5.?Slave是禁止執(zhí)行寫命令的
127.0.0.1:6380>set k2 123
(error) READONLY You can't write against a read only replica.
6.?設(shè)置6382也作為6379的Slave
設(shè)置從節(jié)點(diǎn)之前先在6382內(nèi)set一個(gè)值,為了確定設(shè)置完后會進(jìn)行flush操作。
127.0.0.1:6381>set k2 222
OK
127.0.0.1:6381>get k2
"222"
然后設(shè)置Slave:
127.0.0.1:6381>REPLICAOF 127.0.0.1 6379
OK
127.0.0.1:6381>keys *
1) "k1"
將Master的數(shù)據(jù)同步過來了。
如果設(shè)置Slave后進(jìn)行了flush操作(上面的log也體現(xiàn)出來了),我們之前的k2沒了。
若6381宕機(jī)了,這時(shí)候他再啟動的時(shí)候是會同步Master的數(shù)據(jù)的,增量同步的。不需要手動進(jìn)行同步。
但前提是需要作為Master的Slave,有如下三種方式:
8.?Master掛了怎么辦
從節(jié)點(diǎn)會一直報(bào)錯:
導(dǎo)致的問題:Slave無法提供寫請求,只能讀了。影響了業(yè)務(wù)使用。
解決方案:讓其中一個(gè)Slave升級為Master,然后其他Slave作為這個(gè)新升級為Master的從。?
# 升級為Master的方法:在客戶端執(zhí)行,比如我們升級6380為Master
127.0.0.1:6380>REPLICAOF no one
OK
# 這時(shí)候再看6380就不會再刷錯了,但是6381還在刷,
# 因?yàn)?381是已經(jīng)掛掉的6379的Slave,我們需要讓6381作為6380的Slave,
# 我們再操作這步驟之前,對6380set一個(gè)key,然后看6381的數(shù)據(jù)會重新復(fù)制6380的數(shù)據(jù)
# 顯示業(yè)務(wù)中幾乎不會存在此情況,因?yàn)閺墓?jié)點(diǎn)升級就是升級,所有主從的數(shù)據(jù)都一致,不會隨意改
# 這里只是演示效果而已。
127.0.0.1:6380>set kkk 3333
OK
# 6381作為6380的Slave
127.0.0.1:6381>REPLICAOF 127.0.0.1 6380
OK
127.0.0.1:6381>keys *
1) "kkk"
2) "k1"
127.0.0.1:6381>get kkk
"3333"
3、RDB+AOF混合模式1. 僅開啟AOF
和上面一樣。只是會按照aof文件進(jìn)行主從復(fù)制數(shù)據(jù)。
2. 混合模式(RDB+AOF)
流程和僅開啟RDB一樣,只是主從復(fù)制的時(shí)候會優(yōu)先按照aof來同步數(shù)據(jù),因?yàn)閍of文件丟失數(shù)據(jù)最少,更可靠。redis會判斷aof文件是否存在,若開啟了aof且文件存在,則以aof復(fù)制,若沒開啟aof則走rdb方式。
4、Redis主從復(fù)制實(shí)戰(zhàn)
1.?使用命令實(shí)現(xiàn)
1)方法一
使用命令在服務(wù)端搭建主從模式,其語法格式如下:
redis-server --port--slaveof
執(zhí)行以下命令:
#開啟開啟一個(gè)port為6300的從機(jī),它依賴的主機(jī)port=6379
>redis-server --port 6300 --slaveof 127.0.0.1 6379
接下來開啟客戶端,并執(zhí)行查詢命令,如下所示:?
>redis-cli -p 6300
127.0.0.1:6300>get name
"jack"
127.0.0.1:6300>get website
"www.biancheng.net"
#不能執(zhí)行寫命令
127.0.0.1:6300>set myname BangDe
(error) READONLY You can't write against a read only slave.
127.0.0.1:6300>keys *
1) "myset:__rand_int__"
2) "ID"
3) "title"
4) "course2"
從上述命令可以看出,port =6300 的主機(jī),完全備份了主機(jī)的數(shù)據(jù),它可以執(zhí)行查詢命令,但不能執(zhí)行寫入命令
從機(jī)服務(wù)端提示如下:
[18160] 20 Jan 17:40:34.101 # Server initialized #服務(wù)初始化
[18160] 20 Jan 17:40:34.108 * Ready to accept connections #準(zhǔn)備連接
[18160] 20 Jan 17:40:34.108 * Connecting to MASTER 127.0.0.1:6379 #連接到主服務(wù)器
[18160] 20 Jan 17:40:34.109 * MASTER<->REPLICA sync started #啟動副本同步
[18160] 20 Jan 17:40:34.110 * Non blocking connect for SYNC fired the event.#自動觸發(fā)SYNC命令,請求同步數(shù)據(jù)
[18160] 20 Jan 17:40:34.110 * Master replied to PING, replication can continue...
[18160] 20 Jan 17:40:34.112 * Partial resynchronization not possible (no cached master)
[18160] 20 Jan 17:40:34.431 * Full resync from master: 6eb220706f73107990c2b886dbc2c12a8d0d9d05:0
[18160] 20 Jan 17:40:34.857 * MASTER<->REPLICA sync: receiving 6916 bytes from master #從主機(jī)接受了數(shù)據(jù),并將其存在于磁盤
[18160] 20 Jan 17:40:34.874 * MASTER<->REPLICA sync: Flushing old data #清空原有數(shù)據(jù)
[18160] 20 Jan 17:40:34.874 * MASTER<->REPLICA sync: Loading DB in memory #將磁盤中數(shù)據(jù)載入內(nèi)存
[18160] 20 Jan 17:40:34.879 * MASTER<->REPLICA sync: Finished with success #同步數(shù)據(jù)完成
可以看出主從模式下,數(shù)據(jù)的同步是自動完成的,這個(gè)數(shù)據(jù)同步的過程,又稱為全量復(fù)制。
2)方法二
啟動一個(gè)服務(wù)端,并指定端口號。
#指定端口號為63001,不要關(guān)閉
redis-server --port 63001
打開一個(gè)客戶端,連接服務(wù)器,如下所示:
# 連接port=63001的服務(wù)器
>redis-cli -p 63001
// 現(xiàn)在處于主機(jī)模式下,所以運(yùn)行讀寫數(shù)據(jù)
127.0.0.1:63001>keys *
1) "name"
127.0.0.1:63001>get name
"aaaa"
127.0.0.1:63001>set name "bbbb"
OK
127.0.0.1:63001>get name
"bbbb"
127.0.0.1:63001># 將當(dāng)前服務(wù)器設(shè)置為從服務(wù)器,從屬于6379
127.0.0.1:63001>SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:63001>keys *
1) "master_6379" # 現(xiàn)在它的數(shù)據(jù)和主服務(wù)器的數(shù)據(jù)一樣了
#寫入命令執(zhí)行失敗
127.0.0.1:63001>SET mywebsite www.biancheng.net
(error) READONLY You can't write against a read only replica.
#再次切換為主機(jī)模式,執(zhí)行下面命令
127.0.0.1:63001>SLAVEOF no one
OK
127.0.0.1:63001>SLAVEOF no one
OK
127.0.0.1:63001>keys *
1) "master_6379" # 數(shù)據(jù)還是和之前主服務(wù)器的一樣
127.0.0.1:63001>SET mywebsite www.biancheng.net # 但是現(xiàn)在可以寫入命令了
OK
127.0.0.1:63001>keys *
1) "mywebsite"
2) "master_6379"
2. 修改配置文件實(shí)現(xiàn)
每個(gè) Redis 服務(wù)器都有一個(gè)與其對應(yīng)的配置文件,通過修改該配置文件也可以實(shí)現(xiàn)主從模式。
新建 redis_6302.conf 文件,并添加以下配置信息:
slaveof 127.0.0.1 6379 #指定主機(jī)的ip與port
port 6302 #指定從機(jī)的端口
啟動 Redis 服務(wù)器,執(zhí)行以下命令:
$ redis-server redis_6302.conf
客戶端連接服務(wù)器,并進(jìn)行簡單測試。
執(zhí)行以下命令:
$ redis-cli -p 6302
127.0.0.1:6300>HSET user:username biangcheng
#寫入失敗
(error) READONLY You can't write against a read only slave.
通過命令搭建主從模式,簡單又快捷,所以不建議使用修改配置文件的方法。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
本文題目:Redis主從復(fù)制高可用集群詳解-創(chuàng)新互聯(lián)
文章網(wǎng)址:http://vcdvsql.cn/article10/ddgego.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站、網(wǎng)站改版、外貿(mào)網(wǎng)站建設(shè)、搜索引擎優(yōu)化、定制網(wǎng)站、自適應(yīng)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容