bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

Redis主從復(fù)制高可用集群詳解-創(chuàng)新互聯(lián)

一、Redis單點(diǎn)故障 1、單機(jī)故障問題?

1. 單機(jī)故障

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名與空間、虛擬空間、營銷軟件、網(wǎng)站建設(shè)、瓊中黎族網(wǎng)站維護(hù)、網(wǎng)站推廣。

如果發(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ù)載均衡的需求。

  • 主(Master)和從(Slave)分別部署在不同的服務(wù)器上,當(dāng)主節(jié)點(diǎn)服務(wù)器寫入數(shù)據(jù)時(shí),同時(shí)也會將數(shù)據(jù)同步到從節(jié)點(diǎn)服務(wù)器。
  • 通常情況下,主節(jié)點(diǎn)負(fù)責(zé)寫入數(shù)據(jù),從節(jié)點(diǎn)負(fù)責(zé)讀出數(shù)據(jù)

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ù)副本的一致,主從庫之間采用的是讀寫分離的方式。

  • 讀操作:主庫、從庫都可以接收;
  • 寫操作:首先到主庫執(zhí)行,然后,主庫將寫操作同步給從庫。

即:

說明:?

  • redis主機(jī)會一直將自己的數(shù)據(jù)復(fù)制給redis從機(jī),從而實(shí)現(xiàn)主從同步;
  • 在這個(gè)過程中,只有master主機(jī)可以執(zhí)行寫命令,其他slave從機(jī)只能執(zhí)行讀命令;
  • 這種讀寫分離模式可以大大減輕redis主機(jī)的數(shù)據(jù)讀取壓力,從而提高了redis的效率,并同時(shí)提供了多個(gè)數(shù)據(jù)備份;
  • 主從模式是搭建Redis Cluster 集群最簡單的一種方式;
二、CAP原理 1、CAP原理簡介

在了解 Redis 的主從復(fù)制之前,讓我們先來理解一下現(xiàn)代分布式系統(tǒng)的理論基石——CAP 原理。

CAP 原理是分布式存儲的理論基石:

  • C:Consistent,一致性
  • A:Availability,可用性
  • P:Partition tolerance,分區(qū)容忍性

分布式系統(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。

原理圖:

  • 優(yōu)點(diǎn):數(shù)據(jù)強(qiáng)一致性(但是會破壞可用性,也就是CAP的A)。
  • 缺點(diǎn):效率低,同步阻塞。

2. 異步非阻塞

Redis采取的這種方式。沒有采取下面同步阻塞mq的方式可能也是因?yàn)樾拾桑驗(yàn)镽edis就是要高效。客戶端發(fā)完請求到Redis Master后,立馬給客戶端返回,我不管你Slaver是否同步完成。保留CAP的A,舍棄C。

原理圖:

  • 優(yōu)點(diǎn):效率高,異步非阻塞。
  • 缺點(diǎn):會丟失數(shù)據(jù),滿足了CAP的A,舍棄了CAP的C。

3. 同步阻塞MQ

大數(shù)據(jù)hive采取的就是這種方式,他會保證最終一致性。相對于第二種方式好處在于能保證數(shù)據(jù)的最終一致性,壞處在于沒第二種方式高效,但第二種存在丟數(shù)據(jù)的風(fēng)險(xiǎn)。

  • 優(yōu)點(diǎn):效率相對較高、能保證數(shù)據(jù)最終一致性。
  • 缺點(diǎn):沒發(fā)現(xiàn)啥缺點(diǎn)。非要說缺點(diǎn)那就是有可能取到不一致的數(shù)據(jù),因?yàn)椴皇菑?qiáng)一致性。為什么Redis不采取這個(gè)?因?yàn)镽edis要高效率,不想融入太多組件(MQ)進(jìn)來。
四、Redis主從復(fù)制實(shí)現(xiàn)原理 1、Redis主從復(fù)制簡介

主從復(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)聽:

  • 127.0.0.1 6379(主)
  • 127.0.0.1 6380(從)?

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種情況:

  1. 返回 PONG:說明socket連接正常,且主節(jié)點(diǎn)當(dāng)前可以處理請求,復(fù)制過程繼續(xù)。
  2. 超時(shí):一定時(shí)間后從節(jié)點(diǎn)仍未收到主節(jié)點(diǎn)的回復(fù),說明socket連接不可用,則從節(jié)點(diǎn)斷開socket連接,并重連。
  3. 返回pong以外的結(jié)果:如果主節(jié)點(diǎn)返回其他結(jié)果,如正在處理超市運(yùn)行的腳本,說明主節(jié)點(diǎn)當(dāng)前無法處理命令,則從節(jié)點(diǎn)端口socket連接,并重連。

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 配置如下:

  • 假如設(shè)置成yes,則redis會合并小的TCP包從而節(jié)省帶寬,但會增加同步延遲(40ms),造成master與slave數(shù)據(jù)不一致;
  • 假如設(shè)置成no,則redis master會立即發(fā)送同步數(shù)據(jù),沒有延遲;

概括來說就是:前者關(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ù)是否是全量分為全量同步和增量同步。

一主一從:

  • 一主一從是最簡單的復(fù)制拓?fù)浣Y(jié)構(gòu),用于主節(jié)點(diǎn)出現(xiàn)宕機(jī)時(shí)從節(jié)點(diǎn)提供故障轉(zhuǎn)移支持
  • 當(dāng)應(yīng)用寫命令并發(fā)量較高而且需要持久化時(shí),可以只在從節(jié)點(diǎn)開啟AOF,這樣即保證了數(shù)據(jù)安全性同時(shí)也避免了持久化對主節(jié)點(diǎn)的性能干擾
  • 但需要注意的是, 當(dāng)主節(jié)點(diǎn)關(guān)閉持久化功能時(shí),如果主節(jié)點(diǎn)脫機(jī)要避免自動重啟操作。 因?yàn)橹鞴?jié)點(diǎn)之前沒有開啟持久化功能自動重啟后數(shù)據(jù)集為空, 這時(shí)從節(jié)點(diǎn)如果繼續(xù)復(fù)制主節(jié)點(diǎn)會導(dǎo)致從節(jié)點(diǎn)數(shù)據(jù)也被清空的情況, 喪失了持久化的意義。 安全的做法是在從節(jié)點(diǎn)上執(zhí)行slaveof no one斷開與主節(jié)點(diǎn)的復(fù)制關(guān)系, 再重啟主節(jié)點(diǎn)從而避免這一問題。

一主多從:

  • 一主多從結(jié)構(gòu)(又稱為星形拓?fù)浣Y(jié)構(gòu)) 使得應(yīng)用端可以利用多個(gè)從節(jié)點(diǎn)實(shí)現(xiàn)讀寫分離(見圖) 。?對于讀占比較大的場景, 可以把讀命令發(fā)送到從節(jié)點(diǎn)來分擔(dān)主節(jié)點(diǎn)壓力。
  • 同時(shí)在日常開發(fā)中如果需要執(zhí)行一些比較耗時(shí)的讀命令, 如: keys、 sort等, 可以在其中一臺從節(jié)點(diǎn)上執(zhí)行, 防止慢查詢對主節(jié)點(diǎn)造成阻塞從而影響線上服務(wù)的穩(wěn)定性。
  • 對于寫并發(fā)量較高的場景, 多個(gè)從節(jié)點(diǎn)會導(dǎo)致主節(jié)點(diǎn)寫命令的多次發(fā)送從而過度消耗網(wǎng)絡(luò)帶寬, 同時(shí)也加重了主節(jié)點(diǎn)的負(fù)載影響服務(wù)穩(wěn)定性。

樹狀主從結(jié)構(gòu):

  • 樹狀主從結(jié)構(gòu)(又稱為樹狀拓?fù)浣Y(jié)構(gòu)) 使得從節(jié)點(diǎn)不但可以復(fù)制主節(jié)點(diǎn)數(shù)據(jù), 同時(shí)可以作為其他從節(jié)點(diǎn)的主節(jié)點(diǎn)繼續(xù)向下層復(fù)制
  • 通過引入復(fù)制中間層, 可以有效降低主節(jié)點(diǎn)負(fù)載和需要傳送給從節(jié)點(diǎn)的數(shù)據(jù)量。
  • 如圖所示, 數(shù)據(jù)寫入節(jié)點(diǎn)A后會同步到B和C節(jié)點(diǎn), B節(jié)點(diǎn)再把數(shù)據(jù)同步到D和E節(jié)點(diǎn), 數(shù)據(jù)實(shí)現(xiàn)了一層一層的向下復(fù)制。
  • 當(dāng)主節(jié)點(diǎn)需要掛載多個(gè)從節(jié)點(diǎn)時(shí)為了避免對主節(jié)點(diǎn)的性能干擾, 可以采用樹狀主從結(jié)構(gòu)降低主節(jié)點(diǎn)壓力。

在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ù)制一份。

具體步驟如下:?

  • 從服務(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ù)器完成對快照的載入,開始接收命令請求,并執(zhí)行來自主服務(wù)器緩沖區(qū)的寫命令;

完成上面幾個(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:

  • 主節(jié)點(diǎn)每次向從節(jié)點(diǎn)同步了N字節(jié)數(shù)據(jù)后,將自己的復(fù)制偏移量offset+N
  • 從節(jié)點(diǎn)每次從主節(jié)點(diǎn)同步了N字節(jié)數(shù)據(jù)后,將修改自己的復(fù)制偏移量offset+N

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ù)制:

  • 如果offset偏移量之后的數(shù)據(jù),仍然都在復(fù)制積壓緩沖區(qū)例,則執(zhí)行部分復(fù)制;
  • 如果offset偏移量之后的數(shù)據(jù)已不在復(fù)制積壓緩沖區(qū)中(數(shù)據(jù)已被擠出),則執(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ù)制的過程如下:

  1. 從節(jié)點(diǎn)判斷無法進(jìn)行部分復(fù)制,向主節(jié)點(diǎn)發(fā)送全量復(fù)制的請求;或從節(jié)點(diǎn)發(fā)送部分復(fù)制的請求,但主節(jié)點(diǎn)判斷無法進(jìn)行部分復(fù)制;
  2. 主節(jié)點(diǎn)收到全量復(fù)制的命令后,執(zhí)行bgsave,在后臺生成RDB文件,并使用一個(gè)緩沖區(qū)(稱為復(fù)制緩沖區(qū))記錄從現(xiàn)在開始執(zhí)行的所有寫命令;
  3. 主節(jié)點(diǎn)的bgsave執(zhí)行完成后,將RDB文件發(fā)送給從節(jié)點(diǎn);從節(jié)點(diǎn)首先清除自己的舊數(shù)據(jù),然后載入接收的RDB文件,將數(shù)據(jù)庫狀態(tài)更新至主節(jié)點(diǎn)執(zhí)行bgsave時(shí)的數(shù)據(jù)庫狀態(tài);
  4. 主節(jié)點(diǎn)將前述復(fù)制緩沖區(qū)中的所有寫命令發(fā)送給從節(jié)點(diǎn),從節(jié)點(diǎn)執(zhí)行這些寫命令,將數(shù)據(jù)庫狀態(tài)更新至主節(jié)點(diǎn)的最新狀態(tài);
  5. 如果從節(jié)點(diǎn)開啟了AOF,則會觸發(fā)bgrewriteaof的執(zhí)行,從而保證AOF文件更新至主節(jié)點(diǎn)的最新狀態(tài);

通過全量復(fù)制的過程可以看出,全量復(fù)制是非常重型的操作:

  1. 主節(jié)點(diǎn)通過bgsave命令fork子進(jìn)程進(jìn)行RDB持久化,該過程是非常消耗CPU、內(nèi)存(頁表復(fù)制)、磁盤IO的;
  2. 主節(jié)點(diǎn)通過網(wǎng)絡(luò)將RDB文件發(fā)送給從節(jié)點(diǎn),對主從節(jié)點(diǎn)的帶寬都會帶來很大的消耗;
  3. 從節(jié)點(diǎn)清空老數(shù)據(jù)、載入新RDB文件的過程是阻塞的,無法響應(yīng)客戶端的命令;如果從節(jié)點(diǎn)bgrewriteaof,也會帶來額外的消耗;

心跳檢測機(jī)制的作用有三個(gè):

  1. 檢查主從服務(wù)器的網(wǎng)絡(luò)連接狀態(tài);
  2. 輔助實(shí)現(xiàn)min-slaves選項(xiàng);
  3. 檢測命令丟失;

檢查主從服務(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):

  1. 采用異步復(fù)制;
  2. 一個(gè)主redis可以含有多個(gè)從redis;
  3. 每個(gè)從redis可以接收來自其他從redis服務(wù)器的連接;
  4. 主從復(fù)制對于主redis服務(wù)器來說是非阻塞的,這意味著當(dāng)從服務(wù)器在進(jìn)行主從復(fù)制同步過程中,主redis仍然可以處理外界的訪問請求;
  5. 主從復(fù)制對于從redis服務(wù)器來說也是非阻塞的,這意味著,即使從redis在進(jìn)行主從復(fù)制過程中也可以接受外界的查詢請求,只不過這時(shí)候從redis返回的是以前老的數(shù)據(jù),如果你不想這樣,那么在啟動redis時(shí),可以在配置文件中進(jìn)行設(shè)置,讓redis在復(fù)制同步過程中對來自外界的查詢請求都返回錯誤給客戶端;(雖然說主從復(fù)制過程中,對于從redis是非阻塞的,但是當(dāng)從redis從主redis同步過來最新的數(shù)據(jù)后,還需要將新數(shù)據(jù)加載到內(nèi)存中,在加載到內(nèi)存的過程中是阻塞的,在這段時(shí)間內(nèi)的請求將會被阻);
  6. 主從復(fù)制提高了redis服務(wù)的擴(kuò)展性,避免單個(gè)redis服務(wù)器的讀寫訪問壓力過大的問題,同時(shí)也可以給為數(shù)據(jù)備份及冗余提供一種解決方案;
  7. 為了避免主redis服務(wù)器寫磁盤壓力帶來的開銷,可以配置讓主redis不在將數(shù)據(jù)持久化到磁盤,而是通過連接讓一個(gè)配置的從redis服務(wù)器及時(shí)的將相關(guān)數(shù)據(jù)持久化到磁盤,不過這樣會存在一個(gè)問題,就是主redis服務(wù)器一旦重啟,因?yàn)橹鱮edis服務(wù)器數(shù)據(jù)為空,這時(shí)候通過主從同步可能導(dǎo)致從redis服務(wù)器上的數(shù)據(jù)也被清空;所以要避免主redis自動重啟。
8、主從模式不足

主從模式并不完美,它也存在許多不足之處,下面做了簡單地總結(jié):

  • redis主從模式不具備自動容錯和恢復(fù)功能,如果主節(jié)點(diǎn)宕機(jī),redis集群將無法工作,此時(shí)需要人為干預(yù),將從節(jié)點(diǎn)提升為主節(jié)點(diǎn)
  • 如果主機(jī)宕機(jī)前有一部分?jǐn)?shù)據(jù)未能及時(shí)同步到從機(jī),及時(shí)切換主機(jī)后也會造成數(shù)據(jù)不一致的問題,從而降低了系統(tǒng)的可用性
  • 因?yàn)橹挥幸粋€(gè)主節(jié)點(diǎn),所以其寫入能力和存儲能力都受到一定的限制
  • 在進(jìn)行數(shù)據(jù)全量同步時(shí),如果同步的數(shù)據(jù)量較大可能會造成卡頓的現(xiàn)象

雖然主從模式存在上述不足,但他仍然是實(shí)現(xiàn)分布式集群的基礎(chǔ)。Sentinel哨兵模式同樣是依賴于主從模式實(shí)現(xiàn)。

五、Redis主從復(fù)制實(shí)戰(zhàn) 1、主從復(fù)制配置文件

redis.config配置文件相關(guān)配置:

  • slaveof:復(fù)制選項(xiàng),slave復(fù)制對應(yīng)的master的ip和端口。
  • masterauth:如果master設(shè)置了requirepass,那么slave要連上master,需要有master的密碼才行。masterauth就是用來配置master的密碼,這樣可以在連上master后進(jìn)行認(rèn)證。
  • slave-serve-stale-data yes:當(dāng)從庫同主機(jī)失去連接或者復(fù)制正在進(jìn)行,從機(jī)庫有兩種運(yùn)行方式:1) 如果slave-serve-stale-data設(shè)置為yes(默認(rèn)設(shè)置),從庫會繼續(xù)響應(yīng)客戶端的請求;2) 如果slave-serve-stale-data設(shè)置為no,除去INFO和SLAVOF命令之外的任何請求都會返回一個(gè)錯誤”SYNC with master in progress”。
  • slave-read-only yes:作為從服務(wù)器,默認(rèn)情況下是只讀的(yes),可以修改成NO,用于寫(不建議)。
  • repl-diskless-sync no:是否使用socket方式復(fù)制數(shù)據(jù)。目前redis復(fù)制提供兩種方式,disk和socket。如果新的slave連上來或者重連的slave無法增量同步,就會執(zhí)行全量同步,master會生成rdb文件。有2種方式:1)disk方式是master創(chuàng)建一個(gè)新的進(jìn)程把rdb文件保存到磁盤,再把磁盤上的rdb文件傳遞給slave;2)socket是master創(chuàng)建一個(gè)新的進(jìn)程,直接將RDB通過網(wǎng)絡(luò)發(fā)送給slave,不使用磁盤作為中間存儲。disk方式的時(shí)候,rdb是作為一個(gè)文件保存在磁盤上,因此多個(gè)slave都能共享這個(gè)rdb文件。socket方式的復(fù)制(無盤復(fù)制)是基于順序的串行復(fù)制(master會等待一個(gè)repl-diskless-sync-delay的秒數(shù),如果沒slave來注冊話,就直接傳,后來的slave得排隊(duì)等待。已注冊的就可以一起傳)。在磁盤速度緩慢,網(wǎng)速快的情況下推薦用socket方式。
  • repl-diskless-sync-delay 5:無磁盤復(fù)制的延遲時(shí)間,不要設(shè)置為0。因?yàn)橐坏?fù)制開始,master節(jié)點(diǎn)不會再接收新slave的復(fù)制請求,直到這個(gè)rdb傳輸完畢。所以最好等待一段時(shí)間,等更多的slave注冊上到master后一起傳輸,提供同步性能。
  • repl-ping-slave-period 10:slave根據(jù)指定的時(shí)間間隔向服務(wù)器發(fā)送ping請求。時(shí)間間隔可以通過 repl_ping_slave_period 來設(shè)置,默認(rèn)10秒。
  • repl-timeout 60:復(fù)制連接超時(shí)時(shí)間。master和slave都有超時(shí)時(shí)間的設(shè)置。master檢測到slave上次發(fā)送的時(shí)間超過repl-timeout,即認(rèn)為slave離線,清除該slave信息。slave檢測到上次和master交互的時(shí)間超過repl-timeout,則認(rèn)為master離線。需要注意的是repl-timeout需要設(shè)置一個(gè)比repl-ping-slave-period更大的值,不然會經(jīng)常檢測到超時(shí)。
  • repl-backlog-size 5mb:復(fù)制緩沖區(qū)大小,這是一個(gè)環(huán)形復(fù)制緩沖區(qū),用來保存最新復(fù)制的命令。這樣在slave離線的時(shí)候,不需要完全復(fù)制master的數(shù)據(jù),如果可以執(zhí)行部分同步,只需要把緩沖區(qū)的部分?jǐn)?shù)據(jù)復(fù)制給slave,就能恢復(fù)正常復(fù)制狀態(tài)。緩沖區(qū)的大小越大,slave離線的時(shí)間可以更長,復(fù)制緩沖區(qū)只有在有slave連接的時(shí)候才分配內(nèi)存。沒有slave的一段時(shí)間,內(nèi)存會被釋放出來,默認(rèn)1m。
  • repl-backlog-ttl 3600:master沒有slave一段時(shí)間會釋放復(fù)制緩沖區(qū)的內(nèi)存,repl-backlog-ttl用來設(shè)置該時(shí)間長度。單位為秒。

配置主從:

# 相當(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,有如下三種方式:

  • 客戶端執(zhí)行REPLICAOF;
  • 啟動Redis的時(shí)候添加 --REPLICAOF 127.0.0.1 6379,比如?service redis_6381 start --REPLICAOF 127.0.0.1 6379;
  • 修改配置文件;

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)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司