自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Redis主從復(fù)制原理和復(fù)制方式那點(diǎn)事!

數(shù)據(jù)庫 Redis
在主從服務(wù)器發(fā)送 pysnc 進(jìn)行第一次同步的時(shí)候,采用的是全量復(fù)制,而在同步完成之后,主從服務(wù)器都會(huì)維護(hù)著一個(gè)長連接,主服務(wù)器在接收到新的寫操作命令后,通過這個(gè)連接發(fā)送給從服務(wù)器,從而保持?jǐn)?shù)據(jù)的一致性。

通過學(xué)習(xí)我們知道通過持久化技術(shù)讓服務(wù)器重啟的情況下盡可能少或者不會(huì)丟失數(shù)據(jù)。

但是問題在于持久化的數(shù)據(jù)在單一的服務(wù)器上,萬一服務(wù)器的硬盤出現(xiàn)了故障,那就可能數(shù)據(jù)就真的沒了!

而在Redis中主從復(fù)制,是指將一臺(tái)Redis服務(wù)器的數(shù)據(jù),復(fù)制到其他的Redis服務(wù)器(數(shù)據(jù)備份了)。被復(fù)制的服務(wù)器稱為主服務(wù)器(master),對(duì)主服務(wù)器進(jìn)行復(fù)制操作的為從服務(wù)器(slave)。

?? 要注意的是數(shù)據(jù)的復(fù)制是單向的,只能由主節(jié)點(diǎn)到從節(jié)點(diǎn)!

主從服務(wù)器庫之間采用的是讀寫分離的方式

? 讀操作:主庫、從庫都可以接收讀操作

? 寫操作:首先到主庫執(zhí)行寫,然后,主庫將寫操作同步給從庫

圖片圖片

主從復(fù)制的好處

? 數(shù)據(jù)冗余 :實(shí)現(xiàn)數(shù)據(jù)的熱備份

? 故障恢復(fù) :避免單點(diǎn)故障帶來的服務(wù)不可用,可以由從節(jié)點(diǎn)提供服務(wù),實(shí)現(xiàn)快速的故障恢復(fù)

? 讀寫分離 :在主從復(fù)制的基礎(chǔ)上,配合讀寫分離,可以由主節(jié)點(diǎn)提供寫服務(wù),由從節(jié)點(diǎn)提供讀服務(wù),可分擔(dān)服務(wù)器負(fù)載;尤其是在寫少讀多的場景下,通過多個(gè)從節(jié)點(diǎn)分擔(dān)讀負(fù)載,可以大大提高Redis服務(wù)器的并發(fā)量

? 高可用基礎(chǔ) :是哨兵機(jī)制和集群實(shí)現(xiàn)的基礎(chǔ)

圖片圖片

今天小許將分享Redis高可用知識(shí)點(diǎn)之【Redis主從復(fù)制】,可能你在其他地方看過,相信你跟著小許思路,能幫你重新回憶一遍、不會(huì)的同學(xué)好好學(xué)一波!

內(nèi)容比較多,在地鐵上看文章的你可以先關(guān)注、收藏一下,用電腦看舒服!

圖片圖片

實(shí)現(xiàn)原理

進(jìn)行復(fù)制之前我們要確定的是誰是主和從服務(wù)器,我們將在從從服務(wù)器上使用 slaveof命令形成主從關(guān)系,命令如下:

redis 5.0之前使用 salveof 命令(salveof <master IP 地址> <master 端口號(hào)>)

redis 5.0之后使用 replicaof 命令(replicaof <master IP 地址> <master 端口號(hào)>)

文章后續(xù)將用 master 表示主服務(wù)器 , slave 表示從服務(wù)器。

Redis服務(wù)器執(zhí)行上述命令的成為了從服務(wù)器slave,我們看下進(jìn)行復(fù)制涉及了哪些流程,然后一個(gè)個(gè)看看每個(gè)流程具體干了什么,了解Master和Slave復(fù)制的實(shí)現(xiàn)!

圖片圖片

設(shè)置master 地址和端口

在準(zhǔn)備成為slave的Redis服務(wù)器上執(zhí)行下面命令:

127.0.0.1:12345> SLAVEOF 127.0.0.1 6379
OK

salve服務(wù)器執(zhí)行salveof命令【異步命令】的目的是,將給定的master服務(wù)器IP地址127.0.0.1和端口6379,保存到從服務(wù)器的masterhost屬性和masterport屬性里面。

redisServer 結(jié)構(gòu)體的字段太多了,這里只展示復(fù)制是master的一部分,還有slave的部分屬性就不展示了!

//salve的服務(wù)器結(jié)構(gòu)體值
struct redisServer{
    //...
    /* Replication (slave) */
    // 驗(yàn)證信息
    char *masterauth;  
    // 命令執(zhí)行成功后值 127.0.0.1
    char *masterhost; 
    // 6379
    int masterport;
    //...
};

建立socket連接

slave將根據(jù)命令(slave或replicaof)設(shè)置的IP地址和端口,創(chuàng)建連向master的套接字(socket)連接。

socket連接到master之后,會(huì)注冊(cè)一個(gè)文件事件【syncWithMaster】,接收后續(xù)RDB文件、實(shí)時(shí)寫命令,當(dāng)然在連接建立之后,master也會(huì)創(chuàng)建相應(yīng)的客戶端狀態(tài)啦!

圖片圖片

發(fā)送 ping 命令

slave成為mater的客戶端之后先發(fā)送PING命令,主要作用如下:

1. 檢查salve和master的套接字讀寫狀態(tài)

2. 檢查master是否能正常處理命令

slave收到PONG回復(fù)后才會(huì)繼續(xù)執(zhí)行后續(xù)步驟!

身份驗(yàn)證

客戶端如果開啟了密碼保護(hù)的話,在每次連接 Redis 服務(wù)器之后,就要使用 AUTH 命令解鎖,解鎖之后才能使用其他 Redis 命令。

也就是說如果slave設(shè)置了 masterauth 屬性,那么將會(huì)向master發(fā)送一條AUTH命令進(jìn)行身份驗(yàn)證,目的是檢驗(yàn)給定的密碼 password 和master配置文件中requirepass 項(xiàng)的值是否相符。

向master發(fā)送監(jiān)聽端口

slave身份驗(yàn)證之后,發(fā)送執(zhí)行以下命令向mater發(fā)送監(jiān)聽端口信息

REPLCONF listening-port <salve監(jiān)聽端口號(hào)>

master接收到到命令后,會(huì)記錄在主服務(wù)器對(duì)應(yīng)的客戶端狀態(tài) salve_listening_port屬性中

圖片圖片

我們可以在master上執(zhí)行“info replication”命令可以看到從服務(wù)器的port

圖片圖片

同步

slave會(huì)向master發(fā)送一個(gè) psync 命令來進(jìn)行數(shù)據(jù)同步,并且數(shù)據(jù)同步將分為全量同步和部分同步。

命令持續(xù)復(fù)制

在完成同步之后,master -- slave 會(huì)進(jìn)入到命令傳播階段、這個(gè)階段master將寫命令發(fā)送給slave,slave接收并執(zhí)行增量的命令同步實(shí)現(xiàn)主從一致。

畫個(gè)圖總結(jié)一下實(shí)現(xiàn)原理的流程吧:

圖片圖片

?? 怎么判斷slave是第一次進(jìn)行主從復(fù)制呢?

Redis核心結(jié)構(gòu)server的cached_master保存了master節(jié)點(diǎn)的信息,只有進(jìn)行過主從復(fù)制才會(huì)賦值,否則為空。

復(fù)制方式

Redis復(fù)制的方式可分為全量復(fù)制和增量復(fù)制,不過在第一次全量復(fù)制之后,master和slave雙方之間就會(huì)維護(hù)一個(gè) TCP 長連接,后續(xù)master可以通過這個(gè)連接繼續(xù)將新寫操作命令同步給slave。

全量復(fù)制

全量復(fù)制意思是master當(dāng)前全部數(shù)據(jù)進(jìn)行復(fù)制同步到slave。

全量復(fù)制可分為三個(gè)階段,我們先看下圖有個(gè)整體印象,然后再看每個(gè)階段都干了啥!

圖片圖片

?? 階段一 建立鏈接、協(xié)商同步

這部分流程我們?cè)凇緦?shí)現(xiàn)原理】章節(jié)講比較明白了,這個(gè)階段建立連接,并告訴master需要進(jìn)行同步,等確認(rèn)后就可以為后續(xù)的全量復(fù)制做準(zhǔn)備。

具體來說就是在 slave給master發(fā)送 psync 命令,表示要進(jìn)行數(shù)據(jù)同步,master會(huì)根據(jù)這個(gè)命令的參數(shù)來啟動(dòng)復(fù)制!

?? psync ? -1,命令參數(shù) ‘?’和 ‘-1’是什么意思?

這兩個(gè)參數(shù)分別表示 master 的唯一表示 runID 和復(fù)制進(jìn)度 offset ,因?yàn)槭堑谝淮螐?fù)制,此時(shí)是不知道m(xù)aster的runID的,所以設(shè)置‘ ?’,而 -1 表示第一次復(fù)制。

注:每個(gè) Redis 實(shí)例啟動(dòng)時(shí)都會(huì)自動(dòng)生成的一個(gè)隨機(jī) ID,這個(gè)就是runID

master在收到 psync 命令之后會(huì)用 FULLRESYNC 響應(yīng)命令帶上兩個(gè)參數(shù):master 的runID 和的復(fù)制進(jìn)度 offset,這個(gè)時(shí)候 salve 就可以記下這兩個(gè)參數(shù)值了。

FULLRESYNC : 意思是完全重新同步,就是會(huì)把當(dāng)前master的所有數(shù)據(jù)復(fù)制同步給salve

???? 階段是二 master同步數(shù)據(jù)給從slave

master 收到 psync 命令后,會(huì)執(zhí)行bgsave命令, fork 出一個(gè)子進(jìn)程,子進(jìn)程中將所有的數(shù)據(jù)按特定編碼存儲(chǔ)到 RDB(Redis Database) 文件中。

RDB生成完成之后就會(huì)把文件發(fā)送給salve,從庫接收到RDB文件后,先清空當(dāng)前數(shù)據(jù)庫數(shù)據(jù),然后才會(huì)加載RDB文件。

?? salve在加載RDB前清除數(shù)據(jù)的目的是什么?

salve 在執(zhí)行replicaof 或 slaveof 命令開始復(fù)制前,可能保存了其他數(shù)據(jù),清除是為了避免之前數(shù)據(jù)的影響

?? master在執(zhí)行bgsave期間新寫的命令并沒有生成到RDB中,數(shù)據(jù)丟失了嗎?

生成RDB的是fork出的子進(jìn)程做的,此時(shí)主進(jìn)程還是可以正常處理寫入命令的,此時(shí)為了保證主從的數(shù)據(jù)一致性master 會(huì)用專門的 replication buffer 來記錄 RDB 文件生成、加載RDB文件期間收到的所有寫操作。

?????? 階段三 master發(fā)送新寫操作命令給slave

master會(huì)把階段二期間記錄在 replication buffer 的寫命令,發(fā)送給salve,通過這種方式來實(shí)現(xiàn)主從的同步一致性。

?? 在什么情況下會(huì)進(jìn)行全量同步呢?

1. slave連接上master第一次復(fù)制的時(shí)候

2. 從節(jié)點(diǎn)發(fā)送 psync {runid} {offset} 時(shí),runid 與當(dāng)前主節(jié)點(diǎn)的 runid 不匹配則進(jìn)行全量復(fù)制

3. 從節(jié)點(diǎn)所需要同步數(shù)據(jù)的偏移量 offset 不在復(fù)制積壓緩沖區(qū)中

命令傳播

master在完成第一次同步后,就會(huì)基于長連接進(jìn)行后續(xù)命令傳播,master通過這個(gè)連接將寫命令傳播給slave,salve執(zhí)行得到的寫命令,從而保正主從數(shù)據(jù)的同步。

圖片圖片

增量復(fù)制

我們知道在第一次全量復(fù)制后,主從之間使用長連接進(jìn)行命令傳播,但是如果網(wǎng)絡(luò)出現(xiàn)問題,出現(xiàn)閃斷(斷了一會(huì)又恢復(fù)了)那麻煩了,用戶可能從salve讀到舊數(shù)據(jù)。

這種情況下Redis 2.8開始會(huì)采用增量復(fù)制的方式繼續(xù)同步,如下圖流程:

圖片圖片

問題的關(guān)鍵在于如何知道哪些數(shù)據(jù)作為增量發(fā)送給slave,在分析之前我們先了解幾個(gè)概念:

? 復(fù)制偏移量 (replication offset)

? 復(fù)制積壓緩沖區(qū) (replication backlog)

? 服務(wù)器運(yùn)行ID (runID)

?? 復(fù)制偏移量 ( replication offset)

主從節(jié)點(diǎn)都維護(hù)這一個(gè)復(fù)制偏移量,它代表著當(dāng)前節(jié)點(diǎn)接受數(shù)據(jù)的字節(jié)數(shù),注意這里表示的是【字節(jié)數(shù)】

圖片圖片

上圖中master和slave的offset一開始是相等的,可以理解為數(shù)據(jù)一致,但是master此時(shí)增加了6個(gè)字節(jié)數(shù)據(jù),此時(shí)需要向salve傳播長度為6字節(jié)的數(shù)據(jù),從而保持主從數(shù)據(jù)的一致,offset一致。

? 想要知道主從是否一致,通過對(duì)比offset,也能知道

???? 復(fù)制積壓緩沖區(qū) ( replication backlog buffer )

復(fù)制積壓緩沖區(qū)是由master維護(hù)的一個(gè)固定長度的環(huán)形緩沖區(qū)、是先進(jìn)先出(FIFO)隊(duì)列,默認(rèn)大小為 1MB。

圖片圖片

在命令傳播階段,除了發(fā)送命令給salve之外,還會(huì)寫入到復(fù)制積壓緩沖區(qū),此時(shí)salve還會(huì)做一個(gè)重要的事情,發(fā)送 REPLCONF ACK 命令給master,傳遞 replication_offset(slave當(dāng)前的復(fù)制偏移量),這個(gè)命令有三個(gè)作用:

? 檢測(cè)主從服務(wù)器的網(wǎng)絡(luò)狀態(tài)

? 輔助實(shí)現(xiàn) min-slaves 選項(xiàng)

? 檢測(cè)命令丟失

?????? 服務(wù)器運(yùn)行ID (runID)

不論主從都會(huì)有自己的運(yùn)行ID,在Redis服務(wù)器啟動(dòng)時(shí)會(huì)自動(dòng)生成,由40個(gè)隨機(jī)16進(jìn)制字符組成,第一次復(fù)制master會(huì)發(fā)送這個(gè)ID給到slave,而斷線重連時(shí)slave會(huì)帶上這個(gè)ID發(fā)送給master!

了解這些知識(shí)后,我們?cè)倮硪焕?,在網(wǎng)絡(luò)短暫斷開后,salve重新連上master時(shí),salve會(huì)通過 psync 命令將自己的復(fù)制偏移量 offset 發(fā)送給master,而master根據(jù)自己的offset 和 slave的offset 之間的差距,然后來決定對(duì)salve執(zhí)行哪種同步操作。

? 判斷出salve要讀取的數(shù)據(jù)還在 replication_backlog_buffer 里,那么主服務(wù)器將采用增量同步的方式;

? 判斷出讀取的數(shù)據(jù)已經(jīng)不存在 replication_backlog_buffer 里 (比如被覆蓋掉了),那么主服務(wù)器將采用全量同步的方式

?? replication_backlog_buffer 大小只有1M,數(shù)據(jù)被覆蓋的概率挺大,該如何配置避免呢?

replication_backlog_buffer 最小的大小可以這樣估算

repl_backlog_buffer = second * write_size_per_second

? second 為salve斷線后重新連接上master所需的平均 時(shí)間(以秒計(jì)算)。

? write_size_per_second 則是master平均每秒產(chǎn)生的寫命令數(shù)據(jù)量大小

這個(gè)配置我們看情況去定,這個(gè)參數(shù)在配置文件中如下,我們可以去修改它

repl-backlog-size 1mb

主從復(fù)制配置

配置方式

進(jìn)行配置主從復(fù)制還是比較簡單的,可以用 兩種方式:

1. 在從服務(wù)器中添加配置 slaveof 選項(xiàng),不過在5.0版本中使用了replicaof 代替了slaveof,雖然 slaveof可以繼續(xù)使用,建議使用 replicaof

2. 直接使用 slaveof 命令

# redis.conf文件進(jìn)行主從配置
# replicaof <masterip> <masterport>
replicaof 192.168.127.20 6379

配置好 redis.conf之后,我們分別啟動(dòng)主從服務(wù)器,可以用戶命令 info replication 查看復(fù)制信息

AUTH設(shè)置密碼

如果需要在 slave對(duì)master的建立連接是進(jìn)行驗(yàn)證,可以在master中配置requirepass選項(xiàng)設(shè)置密碼

那么需要在從服務(wù)器salve中使用該密碼,可以使用命令config set masterauth ,或者在配置文件中設(shè)置masterauth

總結(jié)

進(jìn)行主從復(fù)制之前需要master和slave進(jìn)行連接,只有連接成功之后才能進(jìn)行后續(xù)的復(fù)制動(dòng)作。

在主從服務(wù)器發(fā)送 pysnc 進(jìn)行第一次同步的時(shí)候,采用的是全量復(fù)制,而在同步完成之后,主從服務(wù)器都會(huì)維護(hù)著一個(gè)長連接,主服務(wù)器在接收到新的寫操作命令后,通過這個(gè)連接發(fā)送給從服務(wù)器,從而保持?jǐn)?shù)據(jù)的一致性。

如果遇到網(wǎng)絡(luò)閃斷情況,此時(shí)就進(jìn)行增量復(fù)制,不過需要確定復(fù)制積壓緩沖區(qū)是否覆蓋等情況才決定是進(jìn)行全量還是增量復(fù)制。

責(zé)任編輯:武曉燕 來源: 小許code
相關(guān)推薦

2023-09-24 14:32:15

2024-07-04 08:00:24

2023-03-19 22:38:12

邏輯復(fù)制PostgreSQL

2023-03-19 11:53:27

2018-05-16 15:26:43

數(shù)據(jù)庫MySQL主從復(fù)制

2025-01-15 15:47:36

2017-09-05 16:00:49

MySQL主從復(fù)制備份

2023-07-03 08:57:45

Master服務(wù)TCP

2023-03-15 08:30:37

2020-11-13 07:11:23

MySQL復(fù)制日志

2021-01-12 09:03:17

MySQL復(fù)制半同步

2024-07-04 17:22:23

2020-04-14 16:26:22

MySQL線程同步

2023-04-06 13:15:48

MySQL復(fù)制原理應(yīng)用實(shí)踐

2024-03-01 18:33:59

MySQL節(jié)點(diǎn)數(shù)據(jù)

2021-06-08 07:48:27

MySQL主從配置

2025-02-10 10:55:16

2024-11-15 15:27:09

2025-02-28 00:00:00

2025-04-07 00:00:00

MySQL數(shù)據(jù)庫服務(wù)器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)