分析:Redis主從復(fù)制_第1頁(yè)
分析:Redis主從復(fù)制_第2頁(yè)
分析:Redis主從復(fù)制_第3頁(yè)
已閱讀5頁(yè),還剩2頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

分析:Redis主從復(fù)制

那么Redis2.4.16的全量復(fù)制與Redis2.8的部分復(fù)制是如何實(shí)現(xiàn)的呢?如下圖所示,這5個(gè)狀態(tài)是Slave在主從復(fù)制過(guò)程涉及到的幾個(gè)狀態(tài),其中REDIS_REPL_NONE是Redis啟動(dòng)時(shí)候默認(rèn)的狀態(tài)。圖1-2所示的四個(gè)狀態(tài)表示站在Master的角度來(lái)看,Slave所處于的狀態(tài),因?yàn)镾lave在Master端看來(lái)就是一個(gè)特殊的client(同理Master在Slave端看來(lái)也是一個(gè)特殊的client)。/*Slavereplicationstate–Slaveside*/#defineREDIS_REPL_NONE0/*Noactivereplication*/#defineREDIS_REPL_CONNECT1/*MustconnecttoMaster*/#defineREDIS_REPL_CONNECTING2/*ConnectingtoMaster*/#defineREDIS_REPL_TRANSFER3/*Receiving.rdbfromMaster*/#defineREDIS_REPL_CONNECTED4/*ConnectedtoMaster*/Slave自身的狀態(tài)#defineREDIS_REPL_WAIT_BGSAVE_START3/*Masterwaitsbgsavetostartfeedingit*/#defineREDIS_REPL_WAIT_BGSAVE_END4/*MasterwaitsbgsavetostartbulkDBtransmission*/#defineREDIS_REPL_SEND_BULK5/*MasterissendingthebulkDB*/#defineREDIS_REPL_ONLINE6/*bulkDBalreadytransmitted,receiveupdates*/Master端的Slave狀態(tài)Redis在接收到“slaveofipport”命令以后,首先會(huì)將自身的狀態(tài)置為REDIS_REPL_CONNECT,表示需要與自己的Master連接,此時(shí)Slave并沒(méi)有與Master做連接。Redis每隔100ms會(huì)調(diào)用serverCron()函數(shù)一次,每10次serverCron()的調(diào)用會(huì)調(diào)用replicationCron()一次,即每1s會(huì)調(diào)用一次replication()函數(shù)。在replication()函數(shù)中,會(huì)檢查Slave的狀態(tài),如果是處于REDIS_REPL_CONNECT狀態(tài),就會(huì)建立syncWithMaster()的事件處理函數(shù),并將Slave的狀態(tài)改成REDIS_REPL_CONNECTING。syncWithMaster()函數(shù)主要是向Master發(fā)送sync命令,當(dāng)該事件處理函數(shù)被觸發(fā)以后會(huì)將Slave的狀態(tài)改成REDIS_REPL_TRANSFER,表示Slave已經(jīng)準(zhǔn)備就緒要接收Master生成的rdb文件?;氐組aster的角色,Master發(fā)現(xiàn)有一個(gè)Slave連接上來(lái),如果此時(shí)的Master一個(gè)Slave都沒(méi)有且沒(méi)有后臺(tái)快照進(jìn)程,則啟動(dòng)一個(gè)后臺(tái)進(jìn)程將當(dāng)前內(nèi)存中的數(shù)據(jù)生成一個(gè)rdb文件,同時(shí)將Slave的狀態(tài)置為REDIS_REPL_WAIT_BGSAVE_END狀態(tài),表示該Slave等待Master的快照進(jìn)程結(jié)束。在后臺(tái)進(jìn)行生成rdb文件的時(shí)候,如果有對(duì)redis的更新命令,Master會(huì)將這些更新命令存到該Slave的buffer中,如果buffer滿了會(huì)另外開(kāi)辟list來(lái)存儲(chǔ)這些更新命令。當(dāng)后臺(tái)快照進(jìn)程結(jié)束,Master會(huì)將該Slave的狀態(tài)改為REDIS_REPL_SEND_BULK,同時(shí)注冊(cè)sendBulkToSlave()事件處理函數(shù)用于將生成的rdb文件傳輸給Slave。等rdb傳輸結(jié)束以后,sendBulkToSlave()事件函數(shù)會(huì)被刪除,Slave的狀態(tài)會(huì)被更改為REDIS_REPL_ONLINE,另外再注冊(cè)sendReplyToClient()事件函數(shù),將Master在快照內(nèi)過(guò)程中的所有更新操作(Slave的buffer里存的命令)發(fā)給Slave。再回到Slave的角色,當(dāng)Master向Slave傳輸完rdb文件以后,Slave自身會(huì)將狀態(tài)改為REDIS_REPL_CONNECTED,表示復(fù)制已完成,處于與Master保持實(shí)時(shí)同步的狀態(tài)。上述描述的狀態(tài)轉(zhuǎn)換如圖1-3所示,由圖中可知,站在Slave角色看,當(dāng)出現(xiàn)網(wǎng)絡(luò)中斷的時(shí)候不管Slave本身是處于REDIS_REPL_CONNECTING、REDIS_REPL_REPL_TRANSFER還是REDIS_REPL_CONNECTED,都會(huì)調(diào)用相應(yīng)的處理函數(shù)使Slave進(jìn)入REDIS_REPL_CONNECT狀態(tài),這就意味著Slave需要重新向Master發(fā)送sync命令,重新進(jìn)行一次全量同步過(guò)程。圖中的REDIS_REPL_WAIT_BGSAVE_START狀態(tài)是在Slave連接上Master的時(shí)候(站在Master的角色看),當(dāng)時(shí)Master剛好后臺(tái)有快照進(jìn)程且該快照進(jìn)程生成的rdb不適合直接傳給該Slave時(shí)出現(xiàn)的狀態(tài),則將Slave的狀態(tài)置為REDIS_REPL_WAIT_BGSAVE_START。如果此時(shí)有快照進(jìn)程且找到了另外的發(fā)起快照進(jìn)程的Slave,只需要將另外的Slave的buffer內(nèi)容拷貝到該Slave的buffer中,然后直接進(jìn)入REDIS_REPL_WAIT_BGSAVE_END狀態(tài)。如果此時(shí)沒(méi)有后臺(tái)快照進(jìn)程,Slave直接進(jìn)入REDIS_REPL_WAIT_BGSAVE_END狀態(tài),同時(shí)啟動(dòng)一個(gè)后臺(tái)快照進(jìn)程。在上述狀態(tài)轉(zhuǎn)圖中存在的最大問(wèn)題在于任何網(wǎng)絡(luò)閃斷都會(huì)導(dǎo)致Slave與Master重連,然后重新進(jìn)入快照過(guò)程,需要花費(fèi)較長(zhǎng)的時(shí)間重新傳輸rdb文件,而Slave在接收完rdb文件以后試圖將rdb文件恢復(fù)到內(nèi)存的過(guò)程中是不能服務(wù)的(除info命令外)。所以提供部分復(fù)制至少可以做到在網(wǎng)絡(luò)閃斷且更新命令不太多的情景下能夠盡量的避免全量復(fù)制的方案就顯得尤為重要。慶幸的是Redis2.8中里已經(jīng)能夠做到在網(wǎng)絡(luò)閃斷的情況下,Slave重新連接上Master以后,僅僅只傳輸閃斷期間的更新命令。在Redis2.8中redisServer結(jié)構(gòu)中增加了一個(gè)成員:charrunid[REDIS_RUN_ID_SIZE+1];/*IDalwaysdifferentateveryexec.*/該runid是由一個(gè)getRandomHexChars()函數(shù)生成的每次不同的一個(gè)唯一標(biāo)識(shí),不同Redis實(shí)例之間該runid是不同的,同一個(gè)Redis重啟以后,其runid和之前的runid也是不同的。還增加了比較重要的幾項(xiàng)數(shù)據(jù)成員char*repl_backlog;/*Replicationbacklogforpartialsyncs*/longlongrepl_backlog_size;/*Backlogcircularbuffersize*/longlongrepl_backlog_histlen;/*Backlogactualdatalength*/longlongrepl_backlog_idx;/*Backlogcircularbuffercurrentoffset*/longlongrepl_backlog_off;/*Replicationoffsetoffirstbyteinthebacklogbuffer.*/time_trepl_backlog_time_limit;/*TimewithoutSlavesafterthebackloggetsreleased.*/time_trepl_no_Slaves_since;/*WehavenoSlavessincethattime.Onlyvalidifserver.Slaveslenis0.*/repl_backlog是redis用于存儲(chǔ)更新命令的一塊buffer,在部分復(fù)制的時(shí)候Slave會(huì)請(qǐng)求Master從這塊buffer中獲取閃斷情況下丟失的更新操作。repl_backlog在redis啟動(dòng)的時(shí)候初始化為NULL,當(dāng)有Slave連接上來(lái)的時(shí)候,會(huì)被指向創(chuàng)建的buffer,默認(rèn)為1024*1024(即1Mb)。repl_backlog_size表示該buffer的大小(默認(rèn)1024*1024,即1Mb)。該buffer是作為一個(gè)環(huán)形緩存區(qū)使用的,當(dāng)有數(shù)據(jù)超過(guò)buffer的大小以后就會(huì)重新從buffer的頭部開(kāi)始寫(xiě)入。repl_backlog_idx表示當(dāng)前緩存數(shù)據(jù)的尾部(因?yàn)槭黔h(huán)形buffer)。repl_backlog_off是全局緩存的偏移量,從開(kāi)始緩存數(shù)據(jù)起一直在增長(zhǎng)。如果Master一個(gè)Slave都沒(méi)有,則超過(guò)一段時(shí)間以后repl_backlog會(huì)被釋放,默認(rèn)超時(shí)時(shí)間是1小時(shí)。Redis2.8的主從復(fù)制如圖1-5所示,Slave如果與Master的連接超時(shí)了,Slave會(huì)將調(diào)用freeClient(server.Master)把連接關(guān)閉。該freeClient()函數(shù)與2.4版本的相比做了改動(dòng),會(huì)將Master對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)的一些信息存起來(lái)作為cacheMaster,其中后續(xù)被用于部分復(fù)制的最重要的兩個(gè)信息一個(gè)是Masterrunid,另一個(gè)是reploff。reploff是Slave端接收到Master端傳遞過(guò)來(lái)的命令以后不斷更新記錄的全局偏移量的值,該值和Master端的repl_backlog_off對(duì)應(yīng),正常情況下reploff<=repl_backlog_off。如果Slave嘗試部分復(fù)制失敗以后,就會(huì)將該cacheMaster釋放。Redis2.8中主從復(fù)制的過(guò)程增加了REDIS_RECIVE_PONG狀態(tài),該狀態(tài)作為試圖與Master同步的時(shí)候先ping一下的一個(gè)中間狀態(tài)。當(dāng)ping通以后,Slave首先會(huì)嘗試部分復(fù)制,從cacheMaster中拿出Masterrunid和reploff傳給Master,表示請(qǐng)求部分復(fù)制。第一次的時(shí)候,由于Slave端的cacheMaster是NULL,所以Slave向Master發(fā)送的runid是“?”,偏移量是“-1”,當(dāng)Master收到這兩個(gè)變量以后會(huì)將自身的runid和實(shí)際偏移量發(fā)送給Slave,同時(shí)讓Slave發(fā)起一次全量同步。Slave與Master完全同步以后,maste的更新命令會(huì)被存到repl_backlog中,同時(shí)不斷更新偏移量等相關(guān)變量。這些更

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論