2. 主從同步
? Redis可以實(shí)現(xiàn)一主N從,為了減少主庫(kù)的復(fù)制壓力,還可以做到從從復(fù)制。例如:一個(gè)主庫(kù)掛兩個(gè)從庫(kù),兩個(gè)從庫(kù)又各自掛了兩個(gè)從庫(kù)。
? 一個(gè)slaveof命令即可綁定主從關(guān)系,綁定完之后,主庫(kù)會(huì)將從庫(kù)信息記錄在主庫(kù)redisServer結(jié)構(gòu)體的list *slaves中,從庫(kù)會(huì)將主庫(kù)信息記錄在從庫(kù)redisServer結(jié)構(gòu)體的char *masterhost和int masterport之中,當(dāng)然除了列舉的這些信息還有其他數(shù)據(jù)會(huì)記錄,比如認(rèn)證信息char *masterauth。(詳細(xì)可參閱《3.1.2.1 Redis服務(wù)啟動(dòng)流程》中的redisServer結(jié)構(gòu)體)
? 當(dāng)綁定完成之后,便會(huì)進(jìn)行同步操作。當(dāng)?shù)谝淮谓壎P(guān)系或主從diff過(guò)大時(shí),會(huì)使用全量同步。反之則使用增量同步。
2.1 全量同步
? 全量同步大概分三步:
- 從服務(wù)器向主服務(wù)器發(fā)送PSYNC命令
- 主服務(wù)器接到PSYNC命令并生成RDB文件(Redis2.8.18開(kāi)始,這個(gè)RDB文件可以通過(guò)流傳輸直接讓從服務(wù)器生成,這就節(jié)省了主服務(wù)器的IO操作,稱之為“無(wú)盤復(fù)制”)
- 主服務(wù)器將RDB文件發(fā)送給從服務(wù)器,并且在從服務(wù)器在加載完RDB文件之前,會(huì)將所有寫命令保存在發(fā)送緩沖區(qū)(大小默認(rèn)1M),當(dāng)從服務(wù)器完成RDB的載入后,主服務(wù)器將成為從服務(wù)器的客戶端(這里其實(shí)是互為客戶端)將緩沖區(qū)的寫命令發(fā)送給從服務(wù)器。
? 由于主服務(wù)器生成RDB文件需要很多系統(tǒng)資源,所以非必要情況下是不會(huì)去執(zhí)行BGSAVE的,所以全量同步出現(xiàn)在第一次綁定關(guān)系或主從diff過(guò)大時(shí)。
? 值得注意的是,這里很容易出現(xiàn)的問(wèn)題是無(wú)限全量同步,例如:從服務(wù)器接到RDB文件,還未載入完成,而主服務(wù)器的發(fā)送緩沖區(qū)已經(jīng)超出了1M(緩沖區(qū)采用隊(duì)列,F(xiàn)IFO)。這時(shí)從服務(wù)器完成載入會(huì)發(fā)現(xiàn)自己和主服務(wù)器的diff過(guò)大,然后再執(zhí)行一次全量同步,如此循環(huán)往復(fù)。這樣會(huì)嚴(yán)重影響主服務(wù)器對(duì)外提供服務(wù)的性能,所以為了避免這種情況的出現(xiàn),我們必須在配置的時(shí)候就預(yù)估好發(fā)送緩沖區(qū)的大小。
2.2 增量同步
? 全量同步中的第三步已經(jīng)大致說(shuō)明了增量同步的內(nèi)容。在從服務(wù)器綁定主服務(wù)器的時(shí)候,我們可以理解成從服務(wù)器是主服務(wù)器的客戶端,而進(jìn)入增量同步的階段,主服務(wù)器其實(shí)也成為了從服務(wù)器的客戶端,因?yàn)橹鞣?wù)器需要將發(fā)送緩沖區(qū)中的寫命令發(fā)送給從服務(wù)器。
? 增量同步的功能由三個(gè)部分構(gòu)成:
主從服務(wù)器的復(fù)制偏移量
主服務(wù)器的發(fā)送緩沖器(復(fù)制積壓緩沖區(qū))
服務(wù)器的運(yùn)行ID(這個(gè)ID由40個(gè)隨機(jī)的十六進(jìn)制字符串組成,主要是為了處理從服務(wù)器斷線后,主服務(wù)器剛好也被替換了的問(wèn)題。)
? 主服務(wù)器每次向從服務(wù)器發(fā)送N個(gè)字節(jié)的數(shù)據(jù)時(shí),就將自己復(fù)制偏移量的值加上N,從服務(wù)器每次收到主服務(wù)器傳過(guò)來(lái)的N個(gè)字節(jié)的數(shù)據(jù)時(shí),也會(huì)將自己的復(fù)制偏移量加上N。可以理解成從服務(wù)器一直在追主服務(wù)器的偏移量,直到兩個(gè)偏移量一致。
2.3 心跳檢測(cè)
? 主從同步除了同步數(shù)據(jù)以外還有心跳檢測(cè)來(lái)保證服務(wù)及數(shù)據(jù)的正常,包括:
- 檢測(cè)主從服務(wù)器的網(wǎng)絡(luò)連接狀態(tài)
- 輔助實(shí)現(xiàn)min-slaves選項(xiàng)
- 檢測(cè)命令丟失
? 從服務(wù)器會(huì)每秒向主服務(wù)器發(fā)送命令:REPLCONF ACK <replication_offset>
? 在主服務(wù)器的INFO replication中,從服務(wù)器列表lag里有從服務(wù)器向主服務(wù)器發(fā)送REPLCONF ACK命令距現(xiàn)在的時(shí)間,如果超過(guò)一秒,則表示連接出現(xiàn)故障。
? 除此之外,配置文件中有min-slaves-to-write和min-slaves-max-lag兩個(gè)選項(xiàng),語(yǔ)義為當(dāng)存在幾個(gè)從服務(wù)器的連接時(shí)長(zhǎng)超過(guò)lag秒的時(shí)候,主服務(wù)就拒絕執(zhí)行寫命令,這樣來(lái)規(guī)避主服務(wù)器在不安全的情況下執(zhí)行寫命令。
? 由于增量同步是主服務(wù)器給從服務(wù)器通過(guò)網(wǎng)絡(luò)發(fā)送寫命令,但是由于網(wǎng)絡(luò)的不確定性,所以需要ACK機(jī)制來(lái)保證從服務(wù)器收到了相關(guān)數(shù)據(jù),所以每次ACK的時(shí)候從服務(wù)器都會(huì)帶上自己的偏移量,當(dāng)主服務(wù)器發(fā)現(xiàn)從服務(wù)器偏移量比自己小的時(shí)候,就回再次同步差值的這部分?jǐn)?shù)據(jù)給從服務(wù)器。