微信:tangy8080
電子郵箱:914661180@qq.com
更新時間:2019-08-26 20:53:04 星期一node
歡迎您訂閱和分享個人訂閱號,訂閱號內會不按期分享一些我本身學習過程當中的編寫的文章
如您在閱讀過程當中發現文章錯誤,可添加個人微信 tangy8080 進行反饋.感謝您的支持。
git
瞭解Redis主從複製的過程
主從複製則側重解決數據的多機熱備,主從複製是實現負載均衡和故障恢復的基礎github
[無]redis
在分佈式系統中爲了解決單點問題,一般會把數據複製多個副本部署到 其餘機器,知足故障恢復和負載均衡等需求。Redis也是如此,它爲咱們提供了複製功能,實現了相同數據的多個Redis副本。複製功能是高可用Redis的基礎,哨兵和集羣都是在複製的基礎上實現高可用的。
參與複製的Redis實例劃分爲主節點(master)和從節點(slave)。默認 狀況下,Redis都是主節點。每一個從節點只能有一個主節點,而主節點能夠同時具備多個從節點。複製的數據流是單向的,只能由主節點複製到從節點shell
https://github.com/helm/charts/tree/master/stable/redis
數據庫
[root@k8s-180 ~]# kubectl exec -it redis-master-0 redis-cli 127.0.0.1:6379> auth SbN8nBfMWh OK 127.0.0.1:6379> info replication # Replication role:master connected_slaves:2 slave0:ip=172.30.104.11,port=6379,state=online,offset=350,lag=1 slave1:ip=172.30.160.8,port=6379,state=online,offset=350,lag=0 master_replid:60809f9cc34104686610bab1a41d727382f50ac0 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:350 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:350 127.0.0.1:6379>
[root@k8s-181 ~]# kubectl exec -it redis-slave-0 redis-cli 127.0.0.1:6379> auth SbN8nBfMWh OK 127.0.0.1:6379> info replication # Replication role:slave master_host:redis-master-0.redis-headless.default.svc.cluster.local master_port:6379 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_repl_offset:504 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:60809f9cc34104686610bab1a41d727382f50ac0 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:504 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:29 repl_backlog_histlen:476 127.0.0.1:6379>
[root@k8s-181 ~]# kubectl exec -it redis-slave-1 redis-cli 127.0.0.1:6379> auth SbN8nBfMWh OK 127.0.0.1:6379> info replication # Replication role:slave master_host:redis-master-0.redis-headless.default.svc.cluster.local master_port:6379 master_link_status:up master_last_io_seconds_ago:8 master_sync_in_progress:0 slave_repl_offset:588 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:60809f9cc34104686610bab1a41d727382f50ac0 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:588 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:588 127.0.0.1:6379>
能夠看出172.30.104.11和172.30.160.8這兩個節點做爲了從節點
服務器
經過slaveof
我在k8s-181節點上斷開和主節點的同步,能夠觀察到斷開鏈接後從節點又變回爲主節點
網絡
再看k8s-180節點,從之前的兩個從節點鏈接變成了一個
負載均衡
使用 slaveof host port再次鏈接上主節點
127.0.0.1:6379> slaveof 172.30.104.10 6379 OK
通常來講線上的redis環境,從庫是隻讀的.主要是因爲
可使用config get slave-read-only 來查看從庫是否開啓了只讀模式,從下面的命令能夠看到.我這裏的從庫是隻讀的
127.0.0.1:6379> config get slave-read-only 1) "slave-read-only" 2) "yes" 127.0.0.1:6379>
127.0.0.1:6379> config get repl-disable-tcp-nodelay 1) "repl-disable-tcp-nodelay" 2) "no" 127.0.0.1:6379>
repl-disable-tcp-nodelay no:該配置做用於命令傳播階段,控制主節點是否禁止與從節點的TCP_NODELAY;默認no,即不由止TCP_NODELAY。當設置爲yes時,TCP會對包進行合併從而減小帶寬,可是發送的頻率會下降,從節點數據延遲增長,一致性變差;具體發送頻率與Linux內核的配置有關,默認配置爲40ms。當設置爲no時,TCP會立馬將主節點的數據發送給從節點,帶寬增長但延遲變小。
通常來講,只有當應用對Redis數據不一致的容忍度較高,且主從節點之間網絡情況很差時,纔會設置爲yes;多數狀況使用默認值no。
複製的前提是主從節點之間能感知到對方的存在,須要知道對方的IP和端口
發送ping命令
從節點成爲主節點的客戶端以後,發送ping命令進行首次請求,目的是:檢查socket鏈接是否可用,以及主節點當前是否可以處理請求。
從節點發送ping命令後,可能出現3種狀況:
(1)返回pong:說明socket鏈接正常,且主節點當前能夠處理請求,複製過程繼續。
(2)超時:必定時間後從節點仍未收到主節點的回覆,說明socket鏈接不可用,則從節點斷開socket鏈接,並重連。
(3)返回pong之外的結果:若是主節點返回其餘結果,如正在處理超時運行的腳本,說明主節點當前沒法處理命令,則從節點斷開socket鏈接,並重連。
身份驗證
若是從節點中設置了masterauth選項,則從節點須要向主節點進行身份驗證;沒有設置該選項,則不須要驗證
127.0.0.1:6379> config get masterauth 1) "masterauth" 2) "" 127.0.0.1:6379>
在我這裏沒有爲主節點設置masterauth
在Redis2.8及之後,從節點能夠發送psync命令請求同步數據,此時根據主從節點當前狀態的不一樣,同步方式多是全量複製或部分複製
psync命令運行須要如下組件支持:
A.主Redis的複製偏移量(replication offset)和從Redis的複製偏移量。
B.主Redis的複製積壓緩衝區(replication backlog)。
C.Redis的運行ID(run ID)。
127.0.0.1:6379> config get repl-backlog-size 1) "repl-backlog-size" 2) "1048576"
複製積壓緩衝區是由主服務器維護的一個固定長度(fixed-size)先進先出(FIFO)隊列,默認大小爲1MB。
當主服務器進行命令傳播時,它不只會將寫命令發送給全部從服務器,還會將寫命令入隊到複製積壓緩衝區裏面
所以,主服務器的複製積壓緩衝區裏面會保存着一部分最近傳播的寫命令,而且複製積壓緩衝區會爲隊列中的每一個字節記錄相應的複製偏移量,就像下表所示的那樣。
當從服務器從新連上主服務器時,從服務器會經過PSYNC命令將本身的複製偏移量offset發送給主服務器,主服務器會根據這個複製偏移量來決定對從服務器執行何種同步操做:
a、若是offset偏移量以後的數據(也便是偏移量offset+1開始的數據)仍然存在於複製積壓緩衝區裏面,那麼主服務器將對從服務器執行部分重同步操做;
b、相反,若是offset偏移量以後的數據已經不存在於複製積壓緩衝區,那麼主服務器將對從服務器執行完整重同步操做。
舉例: 從服務器偏移量爲10086,若是能在積壓緩衝區裏找到10086+1的數據,執行部分同步.因爲隊列長度有限,可能已經超對隊列.
通常用於初次複製場景,Redis早期支持的複製功能只有全量複製,它會把主節點所有數據一次性發送給從節點,當數據量較大時,會對主從節點和網絡形成很大的開銷。
1.Redis內部會發出一個同步命令,剛開始是Psync命令,Psync ? -1表示要求master主機同步數據
2.主機會向從機發送run_id和offset,由於slave並無對應的 offset,因此是全量複製
3.從機slave會保存主機master的基本信息
4.主節點收到全量複製的命令後,執行bgsave(異步執行),在後臺生成RDB文件(快照),並使用一個緩衝區(稱爲複製緩衝區)記錄從如今開始執行的全部寫命令
5.主機發送RDB文件給從機
6.發送緩衝區數據
7.刷新舊的數據。從節點在載入主節點的數據以前要先將老數據清除
8.加載RDB文件將數據庫狀態更新至主節點執行bgsave時的數據庫狀態和緩衝區數據的加載。
用於網絡中斷等狀況後的複製,只將中斷期間主節點執行的寫命令發送給從節點,與全量複製相比更加高效。須要注意的是,若是網絡中斷時間過長,致使主節點沒有可以完整地保存中斷期間執行的寫命令,則沒法進行部分複製,仍使用全量複製。
1.若是網絡抖動(鏈接斷開 connection lost)
2.主機master 仍是會寫 repl_back_buffer(複製緩衝區)
3.從機slave 會繼續嘗試鏈接主機
4.從機slave 會把本身當前 run_id 和偏移量傳輸給主機 master,而且執行 pysnc 命令同步
5.若是master發現你的偏移量是在緩衝區的範圍內,就會返回 continue命令
同步了offset的部分數據,因此部分複製的基礎就是偏移量 offset。
https://www.iteye.com/blog/uule-2429825