文章目錄
一、主從復(fù)制流程
1. 主從復(fù)制流程圖
第一條線(全量同步):
①slave從節(jié)點發(fā)送FULL SYNC全量同步請求命令
②master執(zhí)行bgsave
③將內(nèi)存中數(shù)據(jù)通過copy-on-write方式 寫入到磁盤
④將磁盤的數(shù)據(jù)生成rdb快照
⑤master把rdb快照文件發(fā)送給slave從節(jié)點
⑥從節(jié)點丟棄舊的數(shù)據(jù),接收新的rdb快照文件
⑦加載rdb文件
⑧slave復(fù)制完成
第二條線(增量同步):
①slave從節(jié)點發(fā)送FULL SYNC全量同步請求命令
②master執(zhí)行bgsave
③主節(jié)點會往從節(jié)點連接緩沖區(qū)寫一份數(shù)據(jù),同時往repl_backlog也寫一份數(shù)據(jù),所有從節(jié)點共享同一份repl_backlog
④slave節(jié)點接收緩存區(qū)的命令
⑤增量數(shù)據(jù)同步/復(fù)制完成
2. 主從復(fù)制日志
master復(fù)制日志查看
* Ready to accept connections # 準(zhǔn)備就緒等待鏈接
* Replica 1xxx.xxx.xxx.101:6379 asks for synchronization
# 102節(jié)點向主節(jié)點發(fā)起了一個全量resync 的請求
* Full resync requested by replica 1xxx.xxx.xxx.101:6379
# 主節(jié)點創(chuàng)建緩沖區(qū),
* Replication backlog created, my new replication IDs are 'b1f446c9ea7c0d5e95c8c47f31b000000000000000000000000000'
# 通過BGSAVE 將數(shù)據(jù)寫入磁盤,生成rdb快照,發(fā)給子節(jié)點
* Starting BGSAVE for SYNC with target: disk
* Background saving started by pid 11978
* DB saved on disk
# 通過copy-on-write的方式將4m數(shù)據(jù)寫入磁盤
* RDB: 6 MB of memory used by copy-on-write
* Background saving terminated with success
# 101 節(jié)點的復(fù)制結(jié)束了 子節(jié)點加載rdb快照文件讀取數(shù)據(jù)
* Synchronization with replica 1xxx.xxx.xxx.101:6379 succeeded
* Replica 1xxx.xxx.xxx.102:6379 asks for synchronization
* Full resync requested by replica 1xxx.xxx.xxx.102:6379
* Starting BGSAVE for SYNC with target: disk
* Background saving started by pid 11979
* DB saved on disk
* RDB: 4 MB of memory used by copy-on-write
* Background saving terminated with success
* Synchronization with replica 1xxx.xxx.xxx.102:6379 succeeded
# Disconnecting timedout replica: 1xxx.xxx.xxx.101:6379
# Connection with replica 1xxx.xxx.xxx.101:6379 lost.
# Disconnecting timedout replica: 1xxx.xxx.xxx.102:6379
二、主從復(fù)制信息剖析
通過什么可以查看主從節(jié)點信息呢?
info replcatipon
2.1. 主節(jié)點信息剖析
[root@bigdata01 bin]# /usr/local/redis/bin/redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> info replication
# Replication
role:master # 角色主節(jié)點
connected_slaves:2 #它所連接到的從節(jié)點的數(shù)量
# 從節(jié)點ip地址、 端口、狀態(tài):在線 當(dāng)前從節(jié)點讀取命令的偏移量 延遲時間:單位:秒
#offset指的是從節(jié)點已經(jīng)復(fù)制的命令偏移量是266
# 這里的offset=master_repl_offset說明主從偏移量是一致的
slave0:ip=1xxx.xxx.xxx.101,port=6379,state=online,offset=266,lag=1 #當(dāng)前連接從01 slave節(jié)點信息
slave1:ip=1xxx.xxx.xxx.102,port=6379,state=online,offset=266,lag=1 #當(dāng)前連接從02 slave節(jié)點信息
master_failover_state:no-failover
# 主從的id
master_replid:b1f446c9ea7c0d5e95c8c47f31bb007cea158ce8
# 主從發(fā)生變化之后id
master_replid2:0000000000000000000000000000000000000000
# 主節(jié)點會把所有的命令轉(zhuǎn)換成子字節(jié)。寫到隊里額里面,最終寫入的值就是master_repl_offset
# 主節(jié)點已寫入的命令偏移量是266
master_repl_offset:266
# 判斷是否全量復(fù)制的標(biāo)識
second_repl_offset:-1
# 2.8之后 緩沖區(qū)
repl_backlog_active:1 # 是否開啟緩沖區(qū) 1-開啟 0-關(guān)閉
repl_backlog_size:1048576 # 緩沖區(qū)大小 1m,可以調(diào)控
repl_backlog_first_byte_offset:1 # 從偏移量為1開始寫入
repl_backlog_histlen:266 # 當(dāng)前緩存沖區(qū)長度
127.0.0.1:6379>
2.2. 從節(jié)點信息剖析
[root@bigdata02 ~]# /usr/local/redis/bin/redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> info replication
# Replication
# 角色
role:slave
# 主節(jié)點ip
master_host:1xxx.xxx.xxx.100
# 主節(jié)點端口
master_port:6379
# 主節(jié)點當(dāng)前狀態(tài)
master_link_status:up
# 主從復(fù)制最后一次 4秒之前
master_last_io_seconds_ago:4
# 現(xiàn)在主從同步狀態(tài) 0-未同步 1-正在同步
master_sync_in_progress:0
# 從節(jié)點復(fù)制的偏移量
slave_repl_offset:3xxx
# 從節(jié)點在選舉時,成為主節(jié)點的權(quán)重優(yōu)先級,這個參數(shù)越大,晉升主節(jié)點的優(yōu)先級越高
slave_priority:100
# 從節(jié)點只讀模式是否開啟 1-開啟 0-未開啟
slave_read_only:1
# 從節(jié)點連接從節(jié)點數(shù)量
connected_slaves:0
master_failover_state:no-failover
# 連接主節(jié)點的id
#當(dāng)前主節(jié)點宕機(jī)后master_replid會變成一個信心的,master_replid2存儲老的主節(jié)點master_replid
master_replid:b1f446c9ea7c0d5e95c8c47f31bb007cea158ce8
master_replid2:0000000000000000000000000000000000000000
# 主節(jié)點寫入的偏移量
master_repl_offset:3xxx
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:3xxx
127.0.0.1:6379>
三、關(guān)鍵術(shù)語
3.1. 復(fù)制功能開啟
通過什么配置項開啟主從之間的復(fù)制功能呢?
slaveof
在從節(jié)點的配置中添加slaveof,從節(jié)點就會識別主節(jié)點是誰?跟主節(jié)點建立連接,然后開始同步數(shù)據(jù)。
同步數(shù)據(jù)就是主從復(fù)制。復(fù)制的又分為全量復(fù)制和增量復(fù)制2種概念。
3.2. 全量復(fù)制場景
全量復(fù)制:從節(jié)點把主節(jié)點的數(shù)據(jù)全量復(fù)制過來
發(fā)生的場景:
1.初始化環(huán)境(剛搭建完主從復(fù)制集群,初始化主節(jié)點數(shù)據(jù),從節(jié)點全量復(fù)制)
2.新增從節(jié)點,需要把主節(jié)點數(shù)據(jù)全量復(fù)制過來,才能對外提供讀服務(wù)
3.在redis2.8之前,主節(jié)點故障(run_id發(fā)生變化),重新選舉主節(jié)點,從節(jié)點為了保證安全性和一致性就會全量復(fù)制。
假設(shè)如果數(shù)據(jù)沒問題,進(jìn)行一次全量復(fù)制就是多余的。
在2.8之后,多了一個second_repl_offset為了避免主從節(jié)點發(fā)生變化或者故障轉(zhuǎn)移都要全量復(fù)制。就會把主節(jié)點的偏移量記錄下來,當(dāng)重新選擇舉主節(jié)點后,就會先判斷偏移量,根據(jù)偏移量做增復(fù)制。
例如:
從節(jié)點偏移量2590
主節(jié)點偏移量2591
主從節(jié)點偏移量相差1
就會只同步1偏移量而不會全量復(fù)制了
增量復(fù)制:
- 增量復(fù)制是Slave初始化后開始正常工作時,主服務(wù)器發(fā)生的寫操作同步到從服務(wù)器的過程。
- 復(fù)制過程是主服務(wù)器每執(zhí)行一個寫命令就會向從服務(wù)器發(fā)送相同的寫命令,從服務(wù)器接收并執(zhí)行收到的寫命令。
3.3. 主從復(fù)制異步性
- 主從復(fù)制對于主從redis服務(wù)器是非阻塞的,當(dāng)從服務(wù)器在進(jìn)行主從復(fù)制過程中,主redis仍然可以處理外界的訪問請求。
- 主從復(fù)制對于從redis服務(wù)器是非阻塞,從redis在進(jìn)行主從復(fù)制過程中也可以接收外界的查詢請求,只不過這時候從redis返回以前的數(shù)據(jù)。
主從復(fù)制過程,主節(jié)點是非阻塞的,復(fù)制的流程中,主節(jié)點開啟了一個后臺子守護(hù)進(jìn)程去做主從復(fù)制的,比如,bgsave、生成rdb快照、發(fā)送等等。同時,當(dāng)前服務(wù)器的主節(jié)點仍然可以對外提供讀寫服務(wù),這時他的異步性。
從節(jié)點也是一樣,比如,從節(jié)點正在復(fù)制主節(jié)點的數(shù)據(jù),這個sync同步也是異步的,復(fù)制的過程中就會有問題。
什么問題呢?
比如,正在復(fù)制,這時一個查詢請求發(fā)過來,就會查詢的是老數(shù)據(jù),這里面就會有臟讀、數(shù)據(jù)不一致的問題。
3.4. 過期key的處理
Slave不睡讓key過期,而是等待Master讓KEY過期。當(dāng)Master讓KEY過期是,它會合成一個DEL命令并傳輸?shù)剿腟Lave節(jié)點。
3.5. 加速復(fù)制
默認(rèn)情況下,master節(jié)點接收SYNC命令后,執(zhí)行BGSAVE操作,將數(shù)據(jù)先保存到磁盤,如果磁盤性能差,那么寫入磁盤會消耗大量的性能,因此,在redis2.8.18時進(jìn)行改進(jìn),可以設(shè)置無需寫入磁盤的直接發(fā)送RDB快照給slave,加快復(fù)制速度。
修改配置:repl_diskless-sync yes (默認(rèn)no)