當前位置:首頁 » 硬碟大全 » 主從分離跟redis緩存區別
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

主從分離跟redis緩存區別

發布時間: 2023-01-10 16:42:46

Ⅰ mysql讀寫分離和用Redis做緩存,這兩種方案有什麼異同

1.mysql讀寫分離 是指mysql的數據讀取操作和數據更新操作分開 這樣在大並發的情況下 資料庫不會出現長時間鎖邊的情況
2.redis做緩存是把資料庫數據緩存在內存中 當同一個數據請求過來,會直接讀取內存中的緩存數據而不會再向資料庫請求數據 降低資料庫的壓力

Ⅱ redis緩存原理

redis緩存原理是sql語句時key值,查詢結果resultSet是value,當同一個查詢語句訪問時(select * from t_proct),只要曾經查詢過,調用緩存直接返回resultSet,節省了資料庫讀取磁碟數據的時間。

redis的存儲分為內存存儲、磁碟存儲和log文件三部分,配置文件中有三個參數對其進行配置。

save seconds updates,save配置,指出在多長時間內,有多少次更新操作,就將數據同步到數據文件。這個可以多個條件配合,比如默認配置文件中的設置,就設置了三個條件。

appendonly yes/no ,appendonly配置,指出是否在每次更新操作後進行日誌記錄,如果不開啟,可能會在斷電時導致一段時間內的數據丟失。因為redis本身同步數據文件是按上面的save條件來同步的,所以有的數據會在一段時間內只存在於內存中。

(2)主從分離跟redis緩存區別擴展閱讀

redis的出現,很大程度補償了memcached這類key/value存儲的不足,在部 分場合可以對關系資料庫起到很好的補充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客戶端,使用很方便。

Redis支持主從同步。數據可以從主伺服器向任意數量的從伺服器上同步,從伺服器可以是關聯其他從伺服器的主伺服器。這使得Redis可執行單層樹復制。

存檔可以有意無意的對數據進行寫操作。由於完全實現了發布/訂閱機制,使得從資料庫在任何地方同步樹時,可訂閱一個頻道並接收主伺服器完整的消息發布記錄。同步對讀取操作的可擴展性和數據冗餘很有幫助。

redis的官網地址,redis.io。(域名後綴io屬於國家域名,是british Indian Ocean territory,即英屬印度洋領地)

Ⅲ Redis早期的主從架構原理分析,早期如何實現讀寫分離的

基於主從復制架構,實現讀寫分離,redis slave node節點只讀,默認開啟配置:slave-read-only yes。開啟了只讀的節點redis slave node,會拒絕所有寫操作,這樣可以強制搭建成讀寫分離的架構。

(1)redis採用非同步方式復制數據到slave節點。

(2)一個master node是可以配置多個slave node的。

(3)slave node也可以連接其他的slave node。

(4)slave node做復制的時候,是不會block master node的正常工作的。

(5)slave node在做復制的時候,也不會block對自己的查詢操作,它會用舊的數據集來提供服務; 但是復制完成的時候,需要刪除舊數據集,載入新數據集,這個時候就會暫停對外服務了。

(6)slave node主要用來進行橫向擴容,做讀寫分離,擴容的slave node可以提高讀的吞吐量。

如果採用了主從架構,那麼建議必須開啟master node的持久化!不建議用slave node作為master node的數據熱備,因為那樣的話,如果你關掉master的持久化,可能在master宕機重啟的時候數據是空的,然後可能一經過復制,salve node數據也丟了。

(1)當啟動一個slave node的時候,它會發送一個 PSYNC 命令給master node。

(2)如果這是slave node 重新連接 master node,那麼master node僅僅會 復制給slave部分缺少的數據 ,否則如果是slave node 第一次連接 master node,那麼會觸發一次 full resynchronization ,master會啟動一個後台線程,開始生成一份RDB快照文件,同時還會將從客戶端收到的所有寫命令 緩存在內存中 。RDB文件生成完畢之後,master會先將這個RDB發送給slave,slave會先寫入本地磁碟,然後再從本地磁碟載入到內存中。然後master會將內存中 緩存的寫命令 發送給slave,slave也會同步這些數據。

(3)slave node如果跟master node有網路故障,斷開了連接,會自動重連。master如果發現有多個slave node都來重新連接,僅僅會啟動一個rdb save操作,用一份數據服務所有slave node。

從redis 2.8開始,就支持主從復制的斷點續傳,如果主從復制過程中,網路連接斷掉了,那麼可以接著上次復制的地方,繼續復制下去,而不是從頭開始復制。master node會在內存中建一個 backlog ,master和slave都會保存一個 replica offset 還有一個 master id(run id) ,offset就是保存在backlog中的。如果master和slave網路連接斷掉了,slave會讓master從上次的replica offset開始繼續復制,但是如果沒有找到對應的offset,那麼就會執行一次full resynchronization全量同步。

master在內存中直接創建rdb,然後發送給slave,不會在自己本地落地磁碟了。

repl-diskless-sync no 改為開啟就可以了

repl-diskless-sync-delay,等待一定時長再開始復制,因為要等更多slave重新連接過來,用一分數據提供服務。

slave node不會過期key,只會等待master過期key。如果master過期了一個key,或者通過LRU淘汰了一個key,那麼會模擬一條del命令發送給slave。

(1)slave node啟動,僅僅保存master node的信息,包括master node的host和ip,但是復制流程沒開始。master host和ip是從哪兒來的?redis.conf裡面的slaveof配置的。

(2)slave node內部有個定時任務,每秒檢查是否有新的master node要連接和復制,如果發現,就跟master node建立socket網路連接。

(3)slave node發送ping命令給master node。

(4)口令認證,如果master設置了requirepass(master上啟用安全認證配置,requirepass 自己取名 ),那麼salve node必須發送masterauth的口令過去進行認證(masterauth 自己取名 )

(5)master node第一次執行全量復制,將所有數據發給slave node。

(6)master node後續持續將寫命令,增量非同步復制給slave node。

指的就是第一次slave連接msater的時候,執行的全量復制,這個過程裡面的一些細節的機制

(1)master和slave都會維護一個offset

master會在自身不斷累加offset,slave也會在自身不斷累加offset。slave每秒都會上報自己的offset給master,同時master也會保存每個slave的offset。這個倒不是說特定就用在全量復制的,主要是master和slave都要知道各自的數據的offset,才能知道互相之間的數據不一致的情況。

(2)backlog

master node有一個backlog,默認是1MB大小,master node給slave node復制數據時,也會將數據在backlog中同步寫一份。backlog主要是用來做全量復制中斷後的增量復制的。

(3)master run id

info server命令,可以看到master run id。如果根據host+ip定位master node,是不靠譜的,如果master node重啟或者數據出現了變化,那麼slave node應該根據不同的run id區分,run id不同就做全量復制。如果需要不更改run id重啟redis,可以使用redis-cli debug reload命令。

(4)psync

從節點使用psync從master node進行復制psync runid offset。master node會根據自身的情況返回響應信息,可能是FULLRESYNC runid offset觸發全量復制,可能是繼續觸發增量復制。

(1)master執行bgsave,在本地生成一份rdb快照文件。

(2)master node將rdb快照文件發送給salve node,如果rdb復制時間超過60秒(repl-timeout),那麼slave node就會認為復制失敗,可以適當調節大這個參數。

(3)對於千兆網卡的機器,一般每秒傳輸100MB,6G文件,很可能超過60s。

(4)master node在生成rdb時,會將所有新的寫命令緩存在內存中,在salve node保存了rdb之後,再將新的寫命令復制給salve node。

(5)client-output-buffer-limit slave 256MB 64MB 60,如果在復制期間,內存緩沖區持續消耗超過64MB,或者一次性超過256MB,或復制時間超過60秒,那麼停止復制,復制失敗。

(6)slave node接收到rdb之後,然後重新載入rdb到自己的內存中,同時基於舊的數據版本對外提供服務,寫入後,清空自己的舊數據,用新的對外提供讀服務。

(7)如果slave node開啟了AOF,那麼會立即執行BGREWRITEAOF,重寫AOF。在這個過程中,rdb生成、rdb通過網路拷貝、slave舊數據的清理、slave node aof rewrite,很耗費時間的。

(1)如果全量復制過程中,master-slave網路連接斷掉,那麼salve重新連接master時,會觸發增量復制。

(2)master直接從自己的backlog中獲取部分丟失的數據,發送給slave node,默認backlog就是1MB。

(3)master就是根據slave發送的psync中的offset來從backlog中獲取數據的。

下節講解哨兵架構,在講之前,你能否處理下面兩個問題呢?

1、非同步復制導致的數據丟失

哨兵可以解決主從架構下,因master宕機後不能接收寫請求而進行選舉salve為新的master,達到高可用的效果。

因為master -> slave的復制是非同步的,所以可能有部分數據還沒復制到slave,master就宕機了,此時這些部分數據就丟失了,此時應該怎麼處理?

2、腦裂導致的數據丟失

腦裂,也就是說,某個master所在機器突然脫離了正常的網路,跟其他slave機器不能連接,但是實際上master還運行著。

此時哨兵可能就會認為master宕機了,然後開啟選舉,將其他slave切換成了master這個時候,集群里就會有兩個master,也就是所謂的腦裂。

此時雖然某個slave被切換成了master,但是可能client還沒來得及切換到新的master,還繼續寫向舊master的數據可能也丟失了,因此舊master再次恢復的時候,會被作為一個slave掛到新的master上去,自己的數據會清空,重新從新的master復制數據,導致數據丟失,怎麼處理腦裂導致的數據丟失呢?

先考慮一下,我們下節進行講解。

Ⅳ redis緩存原理

1、Redis是一種內存高速cache,如果使用redis緩存,那經常被訪問的內容會被緩存在內存中,需要使用的時候直接從內存調取,不知道比硬碟調取快了多少倍,並且支持復雜的數據結構,應用於許多高並發的場景中。
2、Redis支持主從同步。數據可以從主伺服器向任意數量的從伺服器上同步,從伺服器可以是關聯其他從伺服器的主伺服器。這使得Redis可執行單層樹復制。存檔可以有意無意的對數據進行寫操作。由於完全實現了發布/訂閱機制,使得從資料庫在任何地方同步樹時,可訂閱一個頻道並接收主伺服器完整的消息發布記錄。同步對讀取操作的可擴展性和數據冗餘很有幫助。zset是set的一個升級版本,他在set的基礎上增加了一個順序屬性,這一屬性在添加修改元素的時候可以指定,每次指定後,zset會自動重新按新的值調整順序。可以理解了有兩列的mysql表,一列存value,一列存順序。操作中key理解為zset的名字。
更多關於redis緩存原理,進入:https://www.abcgonglue.com/ask/66eab61616100681.html?zd查看更多內容

Ⅳ redis主從配置與分片是一回事嗎

分片(partitioning)就是將你的數據拆分到多個 Redis 實例的過程,這樣每個實例將只包含所有鍵的子集。
主從復制則是一個master可以擁有多個slave,而一個slave又可以擁有多個slave,如此下去,形成了強大的多級伺服器集群架構
所以不一樣

Ⅵ redis和memcached的區別

如果簡單地比較Redis與Memcached的區別,大多數都會得到以下觀點:
1 Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,hash等數據結構的存儲。
2 Redis支持數據的備份,即master-slave模式的數據備份。
3 Redis支持數據的持久化,可以將內存中的數據保持在磁碟中,重啟的時候可以再次載入進行使用。

在Redis中,並不是所有的數據都一直存儲在內存中的。這是和Memcached相比一個最大的區別(我個人是這么認為的)。

Redis只會緩存所有的key的信息,如果Redis發現內存的使用量超過了某一個閥值,將觸發swap的操作,Redis根據「swappability = age*log(size_in_memory)」計算出哪些key對應的value需要swap到磁碟。然後再將這些key對應的value持久化到磁碟中,同時在內存中清除。這種特性使得Redis可以保持超過其機器本身內存大小的數據。當然,機器本身的內存必須要能夠保持所有的key,畢竟這些數據是不會進行swap操作的。

同時由於Redis將內存中的數據swap到磁碟中的時候,提供服務的主線程和進行swap操作的子線程會共享這部分內存,所以如果更新需要swap的數據,Redis將阻塞這個操作,直到子線程完成swap操作後才可以進行修改。

可以參考使用Redis特有內存模型前後的情況對比:

VM off: 300k keys, 4096 bytes values: 1.3G used
VM on: 300k keys, 4096 bytes values: 73M used
VM off: 1 million keys, 256 bytes values: 430.12M used
VM on: 1 million keys, 256 bytes values: 160.09M used
VM on: 1 million keys, values as large as you want, still: 160.09M used

當從Redis中讀取數據的時候,如果讀取的key對應的value不在內存中,那麼Redis就需要從swap文件中載入相應數據,然後再返回給請求方。這里就存在一個I/O線程池的問題。在默認的情況下,Redis會出現阻塞,即完成所有的swap文件載入後才會相應。這種策略在客戶端的數量較小,進行批量操作的時候比較合適。但是如果將Redis應用在一個大型的網站應用程序中,這顯然是無法滿足大並發的情況的。所以Redis運行我們設置I/O線程池的大小,對需要從swap文件中載入相應數據的讀取請求進行並發操作,減少阻塞的時間。

redis、memcache、mongoDB 對比
從以下幾個維度,對redis、memcache、mongoDB 做了對比,歡迎拍磚

1、性能
都比較高,性能對我們來說應該都不是瓶頸
總體來講,TPS方面redis和memcache差不多,要大於mongodb

2、操作的便利性
memcache數據結構單一
redis豐富一些,數據操作方面,redis更好一些,較少的網路IO次數
mongodb支持豐富的數據表達,索引,最類似關系型資料庫,支持的查詢語言非常豐富

3、內存空間的大小和數據量的大小
redis在2.0版本後增加了自己的VM特性,突破物理內存的限制;可以對key value設置過期時間(類似memcache)
memcache可以修改最大可用內存,採用LRU演算法
mongoDB適合大數據量的存儲,依賴操作系統VM做內存管理,吃內存也比較厲害,服務不要和別的服務在一起

4、可用性(單點問題)

對於單點問題,
redis,依賴客戶端來實現分布式讀寫;主從復制時,每次從節點重新連接主節點都要依賴整個快照,無增量復制,因性能和效率問題,
所以單點問題比較復雜;不支持自動sharding,需要依賴程序設定一致hash 機制。
一種替代方案是,不用redis本身的復制機制,採用自己做主動復制(多份存儲),或者改成增量復制的方式(需要自己實現),一致性問題和性能的權衡

Memcache本身沒有數據冗餘機制,也沒必要;對於故障預防,採用依賴成熟的hash或者環狀的演算法,解決單點故障引起的抖動問題。

mongoDB支持master-slave,replicaset(內部採用paxos選舉演算法,自動故障恢復),auto sharding機制,對客戶端屏蔽了故障轉移和切分機制。

5、可靠性(持久化)

對於數據持久化和數據恢復,

redis支持(快照、AOF):依賴快照進行持久化,aof增強了可靠性的同時,對性能有所影響

memcache不支持,通常用在做緩存,提升性能;

MongoDB從1.8版本開始採用binlog方式支持持久化的可靠性

6、數據一致性(事務支持)

Memcache 在並發場景下,用cas保證一致性

redis事務支持比較弱,只能保證事務中的每個操作連續執行

mongoDB不支持事務

7、數據分析

mongoDB內置了數據分析的功能(maprece),其他不支持

8、應用場景
redis:數據量較小的更性能操作和運算上

memcache:用於在動態系統中減少資料庫負載,提升性能;做緩存,提高性能(適合讀多寫少,對於數據量比較大,可以採用sharding)

MongoDB:主要解決海量數據的訪問效率問題

Ⅶ Redis和Memcache的區別總結

區別:

1、存儲方式不同

memecache 把數據全部存在內存之中,斷電後會掛掉,數據不能超過內存大小;redis有部份存在硬碟上,這樣能保證數據的持久性,支持數據的持久化(筆者註:有快照和AOF日誌兩種持久化方式,在實際應用的時候,要特別注意配置文件快照參數,要不就很有可能伺服器頻繁滿載做mp)。

2、數據支持類型不同

redis在數據支持上要比memecache多的多。

3、使用底層模型不同

新版本的redis直接自己構建了VM 機制 ,因為一般的系統調用系統函數的話,會浪費一定的時間去移動和請求。

4、運行環境不同

redis目前官方只支持LINUX 上去行,從而省去了對於其它系統的支持,這樣的話可以更好的把精力用於本系統 環境上的優化,雖然後來微軟有一個小組為其寫了補丁。但是沒有放到主幹上。

(7)主從分離跟redis緩存區別擴展閱讀

注意事項

1、 Redis和Memcache都是將數據存放在內存中,都是內存資料庫。不過memcache還可用於緩存其他東西,例如圖片、視頻等等。

2、Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,hash等數據結構的存儲。

3、虛擬內存–Redis當物理內存用完時,可以將一些很久沒用到的value 交換到磁碟 。

4、過期策略–memcache在set時就指定,例如set key1 0 0 8,即永不過期。Redis可以通過例如expire 設定,例如expire name 10 。

5、分布式–設定memcache集群,利用magent做一主多從;redis可以做一主多從。都可以一主一,存儲數據安全–memcache掛掉後,數據沒了;redis可以定期保存到磁碟(持久化) 。

Ⅷ 詳解Redis 主從復制及主從復制原理

Redis是一個開源的使用ANSI C語言編寫、支持網路、可基於內存亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API。從2010年3月15日起,Redis的開發工作由VMware主持。從2013年5月開始,Redis的開發由Pivotal贊助。

概述

在現有企業中80%公司大部分使用的是redis單機服務,在實際的場景當中單一節點的redis容易面臨風險。

2、容量瓶頸。 當我們有需求需要擴容 Redis 內存時,從 16G 的內存升到 64G,單機肯定是滿足不了。當然,你可以重新買個 128G 的新機器。

解決辦法

要實現分布式資料庫的更大的存儲容量和承受高並發訪問量,我們會將原來集中式資料庫的數據分別存儲到其他多個網路節點上。

Redis 為了解決這個單一節點的問題,也會把數據復制多個副本部署到其他節點上進行復制,實現 Redis的高可用,實現對數據的冗餘備份,從而保證數據和服務的高可用。

主從復制

什麼是主從復制

主從復制,是指將一台Redis伺服器的數據,復制到其他的Redis伺服器。前者稱為主節點(master),後者稱為從節點(slave),數據的復制是單向的,只能由主節點到從節點。

默認情況下,每台Redis伺服器都是主節點;且一個主節點可以有多個從節點(或沒有從節點),但一個從節點只能有一個主節點。

主從復制的作用

1、數據冗餘: 主從復制實現了數據的熱備份,是持久化之外的一種數據冗餘方式。

2、故障恢復: 當主節點出現問題時,可以由從節點提供服務,實現快速的故障恢復;實際上是一種服務的冗餘。

3、負載均衡: 在主從復制的基礎上,配合讀寫分離,可以由主節點提供寫服務,由從節點提供讀服務(即寫Redis數據時應用連接主節點,讀Redis數據時應用連接從節點),分擔伺服器負載;尤其是在寫少讀多的場景下,通過多個從節點分擔讀負載,可以大大提高Redis伺服器的並發量。

4、讀寫分離: 可以用於實現讀寫分離,主庫寫、從庫讀,讀寫分離不僅可以提高伺服器的負載能力,同時可根據需求的變化,改變從庫的數量。

5、高可用基石: 除了上述作用以外,主從復制還是哨兵和集群能夠實施的基礎,因此說主從復制是Redis高可用的基礎。

主從復制啟用

從節點開啟主從復制,有3種方式:

1、配置文件: 在從伺服器的配置文件中加入 slaveof<masterip><masterport>。

2、啟動命令: redis-server啟動命令後加入 --slaveof<masterip><masterport>。

3、客戶端命令: Redis伺服器啟動後,直接通過客戶端執行命令 slaveof<masterip><masterport>,則該Redis實例成為從節點。

通過 info replication 命令可以看到復制的一些信息。

主從復制原理

主從復制過程大體可以分為3個階段:連接建立階段(即准備階段)、數據同步階段、命令傳播階段。

在從節點執行 slaveof 命令後,復制過程便開始運作,下面圖示可以看出復制過程大致分為6個過程。

主從配置之後的日誌記錄也可以看出這個流程。

1、保存主節點(master)信息

執行 slaveof 後 Redis 會列印如下日誌:

2、從節點與主節點建立網路連接

從節點(slave)內部通過每秒運行的定時任務維護復制相關邏輯,當定時任務發現存在新的主節點後,會嘗試與該節點建立網路連接。

從節點與主節點建立網路連接。

從節點會建立一個 socket 套接字,從節點建立了一個埠為51234的套接字,專門用於接受主節點發送的復制命令。從節點連接成功後列印如下日誌:

如果從節點無法建立連接,定時任務會無限重試直到連接成功或者執行 slaveofnoone 取消復制。

關於連接失敗,可以在從節點執行 info replication 查看 master_link_down_since_seconds 指標,它會記錄與主節點連接失敗的系統時間。從節點連接主節點失敗時也會每秒列印如下日誌,方便發現問題:

3、發送 ping 命令

連接建立成功後從節點發送 ping 請求進行首次通信, ping 請求主要目的如下:

如果發送 ping 命令後,從節點沒有收到主節點的 pong 回復或者超時,比如網路超時或者主節點正在阻塞無法響應命令,從節點會斷開復制連接,下次定時任務會發起重連。

從節點發送的 ping 命令成功返回,Redis 列印如下日誌,並繼續後續復制流程:

4、許可權驗證

如果主節點設置了 requirepass 參數,則需要密碼驗證,從節點必須配置 masterauth 參數保證與主節點相同的密碼才能通過驗證。如果驗證失敗復制將終止,從節點重新發起復制流程。

5、同步數據集

主從復制連接正常通信後,對於首次建立復制的場景,主節點會把持有的數據全部發送給從節點,這部分操作是耗時最長的步驟。

6、命令持續復制

當主節點把當前的數據同步給從節點後,便完成了復制的建立流程。接下來主節點會持續地把寫命令發送給從節點,保證主從數據一致性。

作者:LoyaltyLu

鏈接:https://segmentfault.com/a/1190000018268350

Ⅸ 淺談Redis主從復制[轉載]

淺談Redis主從復制

2013.09.27 11:27:00 來源: 京東 作者:張成遠 ( 0 條評論 )

Redis是一個開源的,遵守BSD許可協議的key/value緩存系統,並由其高效的響應速度以及豐富的數據結構而聞名。Redis在京東的使用也是非常普遍的,包括很多關鍵業務上的使用,由於Redis官方集群還未發布,在使用Redis的過程中需要面對Redis的單點問題,京東採用的是一種比較通用的解決方案即由主從備份再加相應的主從切換(在一些場景下可能進行讀寫分離),使主Redis出現失效的時候可以快速的切換到從Redis上。但Redis目前存在的一個問題是主從復制在遇到網路不穩定的情況下,Slave和Master斷開(包括閃斷)會導致Master需要將內存中的數據全部重新生成rdb文件(快照文件),然後傳輸給Slave。Slave接收完Master傳遞過來的rdb文件以後會將自身的內存清空,把rdb文件重新載入到內存中。這種方式效率比較低下,尤其是在數據量大的情況下,畢竟網路閃斷未必丟數據或者說丟的數據只是少部分,但卻要為此付出將整個內存數據都重新傳輸一次的代價。如果能夠將閃斷過程的更新數據傳遞給Slave,那麼就不需要將Master內存中的所有數據都傳遞給Slave了。Redis作者在2.8的候選版(以下簡稱Redis2.8)中已經將這個部分復制的思路實現了。
那麼Redis2.4.16的全量復制與Redis2.8的部分復制是如何實現的呢?如下圖所示,這5個狀態是Slave在主從復制過程涉及到的幾個狀態,其中REDIS_REPL_NONE是Redis啟動時候默認的狀態。圖1-2所示的四個狀態表示站在Master的角度來看,Slave所處於的狀態,因為Slave在Master端看來就是一個特殊的client(同理Master在Slave端看來也是一個特殊的client)。
/* Slave replication state – Slave side */

Slave自身的狀態

Master端的Slave狀態
Redis在接收到「slaveof ip port」命令以後,首先會將自身的狀態置為REDIS_REPL_CONNECT,表示需要與自己的Master連接,此時Slave並沒有與Master做連接。Redis每隔100ms會調用serverCron()函數一次,每10次serverCron()的調用會調用replicationCron()一次,即每1s會調用一次replication()函數。在replication()函數中,會檢查Slave的狀態,如果是處於REDIS_REPL_CONNECT狀態,就會建立syncWithMaster()的事件處理函數,並將Slave的狀態改成REDIS_REPL_CONNECTING。syncWithMaster()函數主要是向Master發送sync命令,當該事件處理函數被觸發以後會將Slave的狀態改成REDIS_REPL_TRANSFER,表示Slave已經准備就緒要接收Master生成的rdb文件。
回到Master的角色,Master發現有一個Slave連接上來,如果此時的Master一個Slave都沒有且沒有後台快照進程,則啟動一個後台進程將當前內存中的數據生成一個rdb文件,同時將Slave的狀態置為REDIS_REPL_WAIT_BGSAVE_END狀態,表示該Slave等待Master的快照進程結束。在後台進行生成rdb文件的時候,如果有對redis的更新命令,Master會將這些更新命令存到該Slave的buffer中,如果buffer滿了會另外開辟list來存儲這些更新命令。當後台快照進程結束,Master會將該Slave的狀態改為REDIS_REPL_SEND_BULK,同時注冊sendBulkToSlave()事件處理函數用於將生成的rdb文件傳輸給Slave。等rdb傳輸結束以後,sendBulkToSlave()事件函數會被刪除,Slave的狀態會被更改為REDIS_REPL_ONLINE,另外再注冊sendReplyToClient()事件函數,將Master在快照內過程中的所有更新操作(Slave的buffer里存的命令)發給Slave。
再回到Slave的角色,當Master向Slave傳輸完rdb文件以後,Slave自身會將狀態改為REDIS_REPL_CONNECTED,表示復制已完成,處於與Master保持實時同步的狀態。
上述描述的狀態轉換如圖1-3所示,由圖中可知,站在Slave角色看,當出現網路中斷的時候不管Slave本身是處於REDIS_REPL_CONNECTING、REDIS_REPL_REPL_TRANSFER還是REDIS_REPL_CONNECTED,都會調用相應的處理函數使Slave進入REDIS_REPL_CONNECT狀態,這就意味著Slave需要重新向Master發送sync命令,重新進行一次全量同步過程。圖中的REDIS_REPL_WAIT_BGSAVE_START狀態是在Slave連接上Master的時候(站在Master的角色看),當時Master剛好後台有快照進程且該快照進程生成的rdb不適合直接傳給該Slave時出現的狀態,則將Slave的狀態置為REDIS_REPL_WAIT_BGSAVE_START。如果此時有快照進程且找到了另外的發起快照進程的Slave,只需要將另外的Slave的buffer內容拷貝到該Slave的buffer中,然後直接進入REDIS_REPL_WAIT_BGSAVE_END狀態。如果此時沒有後台快照進程,Slave直接進入REDIS_REPL_WAIT_BGSAVE_END狀態,同時啟動一個後台快照進程。