欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

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

一、Redis單點故障 1、單機故障問題?

1. 單機故障

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

如果發(fā)生機器故障,例如磁盤損壞,主板損壞等,未能在短時間內(nèi)修復好,客戶端將無法連接redis。

當然如果僅僅是redis節(jié)點掛掉了,可以進行問題排查然后重啟,姑且不考慮這段時間對外服務的可用性,那還是可以接受的。而發(fā)生機器故障,基本是無濟于事。除非把redis遷移到另一臺機器上,并且還要考慮數(shù)據(jù)同步的問題。

2. 容量瓶頸

假如一臺機器是16G內(nèi)存,redis使用了12G內(nèi)存,而其他應用還需要使用內(nèi)存,假設(shè)我們總共需要60G內(nèi)存要如何去做呢,是否有必要購買64G內(nèi)存的機器呢?

3. QPS瓶頸

redis官方數(shù)據(jù)顯示可以達到10w的QPS,如果業(yè)務需要100w的QPS怎么去做呢?

關(guān)于容量瓶頸和QPS瓶頸是redis分布式需要解決的問題,而機器故障就是高可用的問題了。

2、單機故障解決方法

在分布式系統(tǒng)中為了解決單點問題,通常會把數(shù)據(jù)復制多個副本部署到其他機器(主從模式),滿足故障恢復和負載均衡的需求。

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

redis也是如此,它為我們提供了復制功能,實現(xiàn)了相同數(shù)據(jù)的多個redis副本(復制功能是高可用redis的基礎(chǔ),哨兵和集群都是在復制的基礎(chǔ)上實現(xiàn)高可用的)。

但是這樣會有如下問題,多個副本之間的數(shù)據(jù)如何保持一致呢?數(shù)據(jù)讀寫操作可以發(fā)送給所有實例呢?

實際上,Redis 提供了主從庫模式,以保證數(shù)據(jù)副本的一致,主從庫之間采用的是讀寫分離的方式。

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

即:

說明:?

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

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

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

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

分布式系統(tǒng)的節(jié)點往往都是分布在不同的機器上進行網(wǎng)絡隔離開的,這意味著必然會有網(wǎng)絡斷開的風險,這個網(wǎng)絡斷開的場景的專業(yè)詞匯叫做”網(wǎng)絡分區(qū)“。

在網(wǎng)絡分區(qū)發(fā)生時,兩個分布式節(jié)點無法進行通信,我們對一個節(jié)點進行的修改操作將無法同步到另外一個節(jié)點,所以數(shù)據(jù)的”一致性“將無法滿足,因為兩個分布式節(jié)點的數(shù)據(jù)不再保持一致。除非我們犧牲”可用性“,也就是暫停分布式節(jié)點服務,在網(wǎng)絡分區(qū)發(fā)生時,不再提供修改數(shù)據(jù)的功能,直到網(wǎng)絡狀況完全恢復正常再繼續(xù)對外提供服務。

一句話概括 CAP 原理就是——網(wǎng)絡分區(qū)發(fā)生時,一致性和可用性兩難全。

2、Redis主從同步最終一致性

Redis 的主從數(shù)據(jù)是 異步 復制的,所以分布式的 Redis 系統(tǒng)并不滿足一致性要求。當客戶端在 Redis 的主節(jié)點修改了數(shù)據(jù)后,立即返回,即使在主從網(wǎng)絡斷開的情況下,主節(jié)點依舊可以正常對外提供服務,所以 Redis 滿足可用性。

而 Redis 其實是保證 ”最終一致性“,從節(jié)點會努力追趕主節(jié)點,最終從節(jié)點的狀態(tài)會和主節(jié)點的狀態(tài)保持一致。如果網(wǎng)絡斷開了,主從節(jié)點的數(shù)據(jù)將會出現(xiàn)大量不一致,一旦網(wǎng)絡恢復,從節(jié)點會采用多種策略努力追趕上落后的數(shù)據(jù),繼續(xù)盡力保持和主節(jié)點一致。

三、主從復制類型 1、主備與主從

1. 主備

請求都只能打到Master主節(jié)點上,備機只是等主機掛了后來自動升級為客戶端繼續(xù)提供服務。也就是說他不會為主節(jié)點分攤請求壓力。

2. 主從

讀請求會均攤到主節(jié)點和從節(jié)點上,而不是等主機掛了才提供服務。寫請求在master上進行,然后同步到slaver。讀請求會分攤,比如10w個請求,一主雙從的話,可能M上3w個,兩個S上處理6w個,他會為主節(jié)點分攤壓力。所以可以解決單點故障問題。

2、主從復制三種類型

1.?同步阻塞

這種方式講究強一致性,必須等所有Slave都寫入成功后我才會給客戶端響應,否則一直阻塞。也是CAP中的C。

原理圖:

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

2. 異步非阻塞

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

原理圖:

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

3. 同步阻塞MQ

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

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

主從復制其實就是實現(xiàn)高可用(雖然是人工操作),避免單點故障問題。掛掉一個節(jié)點,我其他節(jié)點可以接著提供服務,但是明顯缺點發(fā)現(xiàn)是Slave掛掉還好,Master掛掉可就難受了,Slave太多的話那就夠運維折騰的了,這時候就有了哨兵。 同時,Redis雖然讀取寫入的速度都特別快,但是也會產(chǎn)生讀壓力特別大的情況,主從復制也能夠分擔讀壓力。

主從復制原理圖:

其實就跟MySQL一個道理,mysql是靠binlog,而Redis靠的是rdb文件和aof文件。

2、主從復制實現(xiàn)原理

總的來說主從復制功能的詳細步驟可以分為7個步驟:

設(shè)置主節(jié)點的地址和端口-》建立套接字鏈接-》發(fā)送PING命令-》權(quán)限驗證-》同步-》命令傳播

接下來分別敘述每個步驟,整個流程圖如下:

假設(shè)在本地機開啟兩個Redis節(jié)點,分別監(jiān)聽:

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

1. 設(shè)置主服務器的地址和端口

第一步首先是在從服務器設(shè)置需要同步的主服務器信息,包括機器IP,端口。

主從復制的開啟,完全是從節(jié)點發(fā)起;不需要我們在主節(jié)點做任何事情。

從節(jié)點開啟主從復制,有3種方式:

(1)配置文件

在從服務器的配置文件中加入:

slaveof masterip masterport

(2)啟動命令

redis-server啟動命令后加入:

slaveof masterip masterport

(3)客戶端命令

Redis服務器啟動后,直接通過客戶端執(zhí)行命令:

slaveof masterip masterport

則該Redis實例稱為從節(jié)點。

上述3種方法是等效的,下面以客戶端命令的方式為例,看一下當執(zhí)行了slaveof后,Redis主節(jié)點和從節(jié)點的變化。從服務器會將主服務器的ip地址和端口號保存到服務器狀態(tài)的屬性里面,可以使用Redis命令 info replication 分別查看從服務器和主服務器的主從信息。

2. 建立套接字連接

在slaveof命令執(zhí)行之后,從服務器會根據(jù)設(shè)置的ip和端口,向主服務器建立socket連接。

在6380從服務器里面執(zhí)行完 slave of 127.0.0.1 6379 后意味著,從服務器向主服務器發(fā)起 socket 連接。

在執(zhí)行info Replication 命令分別查看從服務器的主從信息:

而6379服務器已經(jīng)成為主服務器角色:?

3. 發(fā)送PING命令

從節(jié)點成為了主節(jié)點的客戶端之后,發(fā)送 ping 命令進行首次請求,目的是:檢查socket連接是否可用,以及主節(jié)點當前是否能夠處理請求。

從節(jié)點發(fā)送 ping 命令后,可能出現(xiàn)3種情況:

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

4. 身份驗證

如果從節(jié)點中設(shè)置了masterauth選項,則從節(jié)點需要向主節(jié)點進行身份驗證;沒有設(shè)置該選項,則不需要驗證。從節(jié)點進行身份驗證是通過向主節(jié)點發(fā)送auth命令進行的,auth命令的參數(shù)即為配置文件中的masterauth的值。

如果主節(jié)點設(shè)置密碼的狀態(tài),與從節(jié)點masterauth的狀態(tài)一致(一致是指都存在,且密碼相同,或者都不存在),則身份驗證通過,復制過程繼續(xù);如果不一致,則從節(jié)點斷開socket連接,并重連。

5. 同步

同步就是將從節(jié)點的數(shù)據(jù)庫狀態(tài)更新成主節(jié)點當前的數(shù)據(jù)庫狀態(tài)。具體執(zhí)行的方式是:從節(jié)點向主節(jié)點發(fā)送psync命令(Redis2.8以前是sync命令),開始同步。

數(shù)據(jù)同步階段是主從復制最核心的階段,根據(jù)主從節(jié)點當前狀態(tài)的不同,可以分為 全量復制 和 部分復制。

6. 命令傳播

經(jīng)過上面同步操作,此時主從的數(shù)據(jù)庫狀態(tài)其實已經(jīng)一致了,但這種一致的狀態(tài)并不是一成不變的。

在完成同步之后,也許主服務器馬上就接受到了新的寫命令,執(zhí)行完該命令后,主從的數(shù)據(jù)庫狀態(tài)又不一致。

數(shù)據(jù)同步階段完成后,主從節(jié)點進入命令傳播階段;在這個階段主節(jié)點將自己執(zhí)行的寫命令發(fā)送給從節(jié)點,從節(jié)點接受命令并執(zhí)行,從而保證主從節(jié)點數(shù)據(jù)的一致性。

另外命令傳播我們需要關(guān)注兩個點:延遲與不一致 和 心跳機制。

  • 延遲與不一致

需要注意的是,命令傳播是異步的過程,即主節(jié)點發(fā)送寫命令后并不會等待從節(jié)點的回復;因此實際上主從節(jié)點之間很難保持實時的一致性,延遲在所難免。數(shù)據(jù)不一致的程度,與主從節(jié)點之間的網(wǎng)路狀況、主節(jié)點寫命令執(zhí)行頻率、以及主節(jié)點中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)注一致性。

一般來說,只有當應用對Redis數(shù)據(jù)不一致的容忍度較高,且主從節(jié)點之間網(wǎng)絡狀態(tài)不好時,才會設(shè)置為yes;多數(shù)情況使用默認值no

命令傳播階段,從服務器會利用心跳檢測機制定時的向主服務發(fā)送消息。

3、Redis主從復制結(jié)構(gòu)

Redis的主從結(jié)構(gòu)可以采用一主一從、一主多從或者樹狀主從結(jié)構(gòu),Redis主從復制可以根據(jù)是否是全量分為全量同步和增量同步。

一主一從:

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

一主多從:

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

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

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

在Redis2.8以前,從接待你向主節(jié)點發(fā)送sync命令請求同步數(shù)據(jù),此時的同步方式是全量復制;在Redis2.8及以后,從節(jié)點可以發(fā)送psync命令請求同步數(shù)據(jù),此時根據(jù)主從節(jié)點當前狀態(tài)的不同,同步方式可能是全量復制或部分復制。

全量復制:用于初次復制或其他無法進行部分復制的情況,將主節(jié)點中的所有數(shù)據(jù)都發(fā)送給從節(jié)點,是一個非常重型的操作。

部分復制:用于網(wǎng)絡中斷等情況后的復制,只將中斷期間主節(jié)點執(zhí)行的寫命令發(fā)送給從節(jié)點,與全量復制相比更加高效,需要注意的是,如果網(wǎng)絡中斷時間過長,導致主節(jié)點沒有能夠完整地保存中斷期間執(zhí)行地寫命令,則無法進行部分復制,仍使用全量復制。

1. 全量同步

Redis全量復制一般發(fā)生在Slave初始化階段,這時Slave需要將Master上的所有數(shù)據(jù)都復制一份。

具體步驟如下:?

  • 從服務器連接主服務器,發(fā)送SYNC命令;?
  • 主服務器接收到SYNC命名后,開始執(zhí)行BGSAVE命令生成RDB文件并使用緩沖區(qū)記錄此后執(zhí)行的所有寫命令;?
  • 主服務器BGSAVE執(zhí)行完后,向所有從服務器發(fā)送快照文件,并在發(fā)送期間繼續(xù)記錄被執(zhí)行的寫命令;?
  • 從服務器收到快照文件后丟棄所有舊數(shù)據(jù),載入收到的快照;?
  • 主服務器快照發(fā)送完畢后開始向從服務器發(fā)送緩沖區(qū)中的寫命令;?
  • 從服務器完成對快照的載入,開始接收命令請求,并執(zhí)行來自主服務器緩沖區(qū)的寫命令;

完成上面幾個步驟后就完成了從服務器數(shù)據(jù)初始化的所有操作,從服務器此時可以接收來自用戶的讀請求。

2. 增量同步

由于全量復制在主節(jié)點數(shù)據(jù)量較大時效率太低,因此Redis2.8開始提供部分復制,用于處理網(wǎng)絡中斷時的數(shù)據(jù)同步。

部分復制的實現(xiàn),依賴于三個重量的概念:復制偏移量、復制積壓緩沖區(qū)、服務器運行id(runid)

1)復制偏移量

執(zhí)行復制的雙方,主從節(jié)點,分別會維護一個復制偏移量offset:

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

offset用于判斷主從節(jié)點的數(shù)據(jù)庫狀態(tài)是否一致:如果二者offset相同,則一致;如果offset不同,則不一致,此時可以根據(jù)兩個offset找出從節(jié)點缺少的那部分數(shù)據(jù)。例如,如果主節(jié)點offset是1000,而從節(jié)點的offset是500,那么部分復制舊需要將offset為501-1000的數(shù)據(jù)傳遞給從節(jié)點。而offset為501-1000的數(shù)據(jù)存儲的位置,就是下面要介紹的復制積壓緩沖區(qū)。

2)復制積壓緩沖區(qū)(replication-backlog-buffer)

主節(jié)點內(nèi)部維護了一個固定長度的、先進先出(FIFO)隊列作為復制積壓緩沖區(qū),默認大小為1MB,在主節(jié)點進行命令傳播時,不僅會將寫命令同步到從節(jié)點,還會將寫命令寫入復制積壓緩沖區(qū)。

由于復制積壓緩沖區(qū)定長且是先進先出,所以他保存的是主節(jié)點最近執(zhí)行的寫命令;時間較早的寫命令會被擠出緩沖區(qū)。因此,當主從節(jié)點offset的差距過大超過緩沖區(qū)長度時,將無法執(zhí)行部分復制,只能執(zhí)行全量復制。

為了提高網(wǎng)絡中斷時部分復制執(zhí)行的概率,可以根據(jù)需要增大復制積壓緩沖區(qū)的大?。ㄍㄟ^配置repl-backlog-size);例如如果網(wǎng)絡中斷的平均時間是60s,而主節(jié)點平均每秒產(chǎn)生的寫命令(某些特定協(xié)議格式)所占據(jù)的字節(jié)數(shù)為100KB,則復制積壓緩沖區(qū)的平均需求為6MB,保險起見,可以設(shè)置為12MB,來保證絕大多數(shù)斷線情況都可以使用部分復制。

從節(jié)點將offset發(fā)送給主節(jié)點后,主節(jié)點根據(jù)offset和緩沖區(qū)大小決定能否執(zhí)行部分復制:

  • 如果offset偏移量之后的數(shù)據(jù),仍然都在復制積壓緩沖區(qū)例,則執(zhí)行部分復制;
  • 如果offset偏移量之后的數(shù)據(jù)已不在復制積壓緩沖區(qū)中(數(shù)據(jù)已被擠出),則執(zhí)行全量復制。

3)服務器運行ID(runid)

每個Redis節(jié)點,都有其運行ID,運行ID由節(jié)點在啟動時自動生成,主節(jié)點會將自己的運行ID發(fā)送給從節(jié)點,從節(jié)點會將主節(jié)點的運行ID存起來。從節(jié)點Redis斷開重連的時候,就是根據(jù)運行ID來判斷同步的進度:

如果從節(jié)點保存的runid與主節(jié)點現(xiàn)在的runid相同,說明主從節(jié)點之前同步過,主節(jié)點會繼續(xù)嘗試使用部分復制(到底能不能部分復制還要看offset和復制積壓緩沖區(qū)的情況);

如果從節(jié)點保存的runid與主節(jié)點現(xiàn)在的runid不同,說明從節(jié)點在斷線前同步的Redis節(jié)點并不是當前的主節(jié)點,只能進行全量復制。

4、psync命令的執(zhí)行

在了解了復制偏移量、復制積壓緩沖區(qū)、節(jié)點運行id之后,這里psync命令的參數(shù)和返回值,從而說明psync命令執(zhí)行過程中,主從節(jié)點是如何確定使用全量復制還是部分復制的。

psync命令流程圖如下:

psync命令的大體流程如下:

如果從節(jié)點之前沒有復制過任何主節(jié)點,或者之前執(zhí)行過slaveof no one 命令,從節(jié)點就會向主節(jié)點發(fā)送psync 命令,請求主節(jié)點進行數(shù)據(jù)的全量同步。

如果前面從節(jié)點已經(jīng)同步過部分數(shù)據(jù),此時從節(jié)點就會發(fā)送psync runid offset 命令給主節(jié)點,其中runid是上一次主節(jié)點的運行ID,offset是當前從節(jié)點的復制偏移量

主節(jié)點收到psync命令后,會出現(xiàn)以下三種可能:

主節(jié)點返回 fullresync runid offset 回復,表示主節(jié)點要求與從節(jié)點進行數(shù)據(jù)的完整全量復制,其中runid表示主節(jié)點的運行ID,offset表示當前主節(jié)點的復制偏移量。

如果主服務器返回+continue,表示從節(jié)點與從節(jié)點會進行部分數(shù)據(jù)的同步操作,將從節(jié)點缺失的數(shù)據(jù)復制過來即可。

如果主服務器返回-err,表示主服務器的Redis版本低于2.8,無法是別psync命令,此時從服務器會向主服務器發(fā)送sync,進行完整的數(shù)據(jù)全量復制。

Redis通過psnyc命令進行全量復制的過程如下:

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

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

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

心跳檢測機制的作用有三個:

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

檢查主從服務器的網(wǎng)絡連接狀態(tài),主節(jié)點信息中可以看到所屬的從節(jié)點的連接信息:

state 表示從節(jié)點狀態(tài)、offset表示復制偏移量、lag表示延遲值(幾秒之前有過心跳檢測機制)

輔助實現(xiàn)min-slaves選項,Redis.conf 配置文件中有下方兩個參數(shù):

# 未達到下面兩個條件時,寫操作就不會被執(zhí)行
# 最少包含的從服務器
# min-slaves-to-write 3
# 延遲值
# min-slaves-max-lag 10

如果將兩個參數(shù)注釋取消,那么如果從服務器的數(shù)量少于3個,或者三個從服務器的延遲(lag)大于等于10秒時,主服務器都會拒絕執(zhí)行寫命令。

檢測命令丟失時,在從服務器的連接信息中可以看到復制偏移量,如果此時主服務器的復制偏移量與從服務器的復制偏移量不一致時,主服務器會補發(fā)缺失的數(shù)據(jù)。

5、無磁盤復制

通常來講,一個完全重新同步需要在磁盤上創(chuàng)建一個RDB文件,然后加載這個文件以便為從服務器發(fā)送數(shù)據(jù)。如果使用比較低速的磁盤,這種操作會給主服務器帶來較大的壓力。Redis從2.8.18版本開始嘗試支持無磁盤的復制。使用這種設(shè)置時,子進程直接將RDB通過網(wǎng)絡發(fā)送給從服務器,不使用磁盤作為中間存儲,避免了IO性能差問題。

可以使用repl-diskless-sync 配置參數(shù)來啟動無磁盤復制。使用repl-diskless-sync-delay參數(shù)來配置傳輸開始的延遲時間,以便等待更多的從服務器連接上來。

開啟無磁盤復制:

repl-diskless-sync yes
6、主從復制架構(gòu)中出現(xiàn)宕機情況

如果在主從復制架構(gòu)中出現(xiàn)宕機的情況,需要分情況看:

1. 從Redis宕機

這個相對而言比較簡單,在Redis中從庫重新啟動后會自動加入到主從架構(gòu)中,自動完成同步數(shù)據(jù),這是因為在Redis2.8版本后就新增了增量復制功能,主從斷線后恢復是通過增量復制實現(xiàn)的。所以這種情況無需擔心。

2. 主Redis宕機

這個情況相對而言就會復雜一些,需要以下2步才能完成:

第一步,在從數(shù)據(jù)庫中執(zhí)行SLAVEOF NO ONE命令,斷開主從關(guān)系并且提升為主庫繼續(xù)服務;

第二步,將主庫修復重新啟動后,執(zhí)行SLAVEOF命令,將其設(shè)置為其他庫的從庫,這時數(shù)據(jù)就能更新回來;

這兩個步驟要通過手動完成恢復,過程其實是比較麻煩的并且容易出錯,有沒有好辦法解決呢?有的,Redis提供的哨兵(sentinel)功能就可以實現(xiàn)主Redis宕機的自動切換。

7、Redis主從復制總結(jié)

1. Redis主從復制策略

主從剛剛連接的時候,進行全量同步;全同步結(jié)束后,進行增量同步。當然,如果有需要,slave 在任何時候都可以發(fā)起全量同步。redis的策略是,無論如何,首先會嘗試進行增量同步,如不成功,要求從機進行全量同步。

2. 主從復制的特點

主從復制的特點:

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

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

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

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

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

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

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

配置主從:

# 相當于我們上面客戶端執(zhí)行的REPLICAOF命令,配置到配置文件每次重啟就不用手動再執(zhí)行命令了。
replicaof# master的密碼
masterauth

主從傳輸數(shù)據(jù)這期間,從節(jié)點是否允許對外提供服務:

# 默認是ye,允許
slave-serve-stale-data yes

看下面的log(這是我們建立主從關(guān)系的時候產(chǎn)生的log)。

意思是說在和Master建立連接,獲取完Master數(shù)據(jù)之間,也就是從庫進行flush操作之前,是否允許對外繼續(xù)提供請求(就是Slave完成配置之前的那些flush之前的老數(shù)據(jù)是否還允許被訪問)。

是否開啟Slave從節(jié)點也支持寫命令:

# 默認只讀,yes代表只讀
slave-read-only yes

先落磁盤再傳輸還是直接網(wǎng)絡傳輸:

# 默認是先落盤,再進行網(wǎng)絡傳輸
repl-diskless-sync no

因為默認是Master先生成rdb文件到磁盤,這時候產(chǎn)生一次磁盤IO,然后將磁盤上rdb文件以網(wǎng)絡的方式傳遞給Slave,這時候又產(chǎn)生一次IO,如果rdb幾個GB的話那還不如直接走網(wǎng)絡傳輸,就不走磁盤io了。 改為yes的話直接Master通過網(wǎng)絡的方式發(fā)送rdb給Slave。默認是no,從日志也可以看出先落盤了

原理圖:

全量還是增量:

repl-backlog-size 1mb

可以發(fā)現(xiàn)比主從復制原理圖中多了個隊列和偏移量。

這個隊列代表repl-backlog-size參數(shù)設(shè)置的值大小,是決定全量復制還是增量復制的關(guān)鍵參數(shù)。

RDB每次同步到slave的時候,slave都會記錄一個offset偏移量,然后每次同步數(shù)據(jù)的時候都會看隊列里的數(shù)據(jù)偏移量是否符合slave上次同步的數(shù)據(jù)大小,若符合則增量,否則全量。

舉例:

如果設(shè)置的1MB,你掛了3s鐘,假設(shè)1s鐘就寫了1MB,那么3s鐘的隊列肯定放不下,這時候就觸發(fā)全量,所以這個需要看業(yè)務調(diào)整大小。

再比如master是100MB數(shù)據(jù),slave也是1MB數(shù)據(jù),然后slave掛了?;謴偷臅r候發(fā)現(xiàn)master已經(jīng)有110MB了,但是隊列大小只有1MB,把隊列里的數(shù)據(jù)拿來顯然不行,所以會觸發(fā)全量,這只是舉例,其實不會那么傻的判斷總大小,而是通過偏移量來的。?

2、僅開啟RDB

僅僅開啟RDB持久化,關(guān)閉AOF。

首先啟動三個redis,端口分別是6379、6380、6381。我們這里設(shè)定6379為Master,其余兩個為Slaver。

1. 如何設(shè)置Slaver

可以看到Redis5.x后開始用REPLICAOF命令代替5.x版本之前的SLAVEOF命令。

2. 設(shè)置Slaver

# 設(shè)置6380是6379的從節(jié)點
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é)點之前先在6382內(nèi)set一個值,為了確定設(shè)置完后會進行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后進行了flush操作(上面的log也體現(xiàn)出來了),我們之前的k2沒了。

若6381宕機了,這時候他再啟動的時候是會同步Master的數(shù)據(jù)的,增量同步的。不需要手動進行同步。

但前提是需要作為Master的Slave,有如下三種方式:

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

8.?Master掛了怎么辦

從節(jié)點會一直報錯:

導致的問題:Slave無法提供寫請求,只能讀了。影響了業(yè)務使用。

解決方案:讓其中一個Slave升級為Master,然后其他Slave作為這個新升級為Master的從。?

# 升級為Master的方法:在客戶端執(zhí)行,比如我們升級6380為Master
127.0.0.1:6380>REPLICAOF no one
OK
# 這時候再看6380就不會再刷錯了,但是6381還在刷,
# 因為6381是已經(jīng)掛掉的6379的Slave,我們需要讓6381作為6380的Slave,
# 我們再操作這步驟之前,對6380set一個key,然后看6381的數(shù)據(jù)會重新復制6380的數(shù)據(jù)
# 顯示業(yè)務中幾乎不會存在此情況,因為從節(jié)點升級就是升級,所有主從的數(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文件進行主從復制數(shù)據(jù)。

2. 混合模式(RDB+AOF)

流程和僅開啟RDB一樣,只是主從復制的時候會優(yōu)先按照aof來同步數(shù)據(jù),因為aof文件丟失數(shù)據(jù)最少,更可靠。redis會判斷aof文件是否存在,若開啟了aof且文件存在,則以aof復制,若沒開啟aof則走rdb方式。

4、Redis主從復制實戰(zhàn)

1.?使用命令實現(xiàn)

1)方法一

使用命令在服務端搭建主從模式,其語法格式如下:

redis-server --port--slaveof

執(zhí)行以下命令:

#開啟開啟一個port為6300的從機,它依賴的主機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 的主機,完全備份了主機的數(shù)據(jù),它可以執(zhí)行查詢命令,但不能執(zhí)行寫入命令

從機服務端提示如下:

[18160] 20 Jan 17:40:34.101 # Server initialized #服務初始化
[18160] 20 Jan 17:40:34.108 * Ready to accept connections #準備連接
[18160] 20 Jan 17:40:34.108 * Connecting to MASTER 127.0.0.1:6379 #連接到主服務器
[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 #從主機接受了數(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ù)的同步是自動完成的,這個數(shù)據(jù)同步的過程,又稱為全量復制。

2)方法二

啟動一個服務端,并指定端口號。

#指定端口號為63001,不要關(guān)閉
redis-server --port 63001

打開一個客戶端,連接服務器,如下所示:

# 連接port=63001的服務器
>redis-cli -p 63001
// 現(xià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># 將當前服務器設(shè)置為從服務器,從屬于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ù)和主服務器的數(shù)據(jù)一樣了
#寫入命令執(zhí)行失敗
127.0.0.1:63001>SET mywebsite www.biancheng.net
(error) READONLY You can't write against a read only replica.
#再次切換為主機模式,執(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ù)還是和之前主服務器的一樣
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. 修改配置文件實現(xiàn)

每個 Redis 服務器都有一個與其對應的配置文件,通過修改該配置文件也可以實現(xiàn)主從模式。

新建 redis_6302.conf 文件,并添加以下配置信息:

slaveof 127.0.0.1 6379 #指定主機的ip與port
port 6302 #指定從機的端口

啟動 Redis 服務器,執(zhí)行以下命令:

$ redis-server redis_6302.conf

客戶端連接服務器,并進行簡單測試。

執(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)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

本文題目:Redis主從復制高可用集群詳解-創(chuàng)新互聯(lián)
文章網(wǎng)址:http://chinadenli.net/article10/ddgego.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應式網(wǎng)站、網(wǎng)站改版、外貿(mào)網(wǎng)站建設(shè)、搜索引擎優(yōu)化、定制網(wǎng)站、自適應網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

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