首頁  >  文章  >  資料庫  >  Redis主從複製工作原理以及常見問題

Redis主從複製工作原理以及常見問題

咔咔
咔咔原創
2020-06-02 01:26:101901瀏覽

相信很多小夥伴都已經配置過主從複製,但是對於redis主從複製的工作流程和常見問題很多都沒有深入的了解。咔咔這次用時倆天時間為大家整理一份redis主從複製的全部知識點。

本文實作所需環境

centos7.0

#redis4.0


一、什麼是Redis主從複製?


主從複製就是現在有兩個兩台redis伺服器,把一台redis的資料同步到另一台redis資料庫上。前者稱為主節點(master),後者為從節點(slave)。資料是只能master往slave同步單向。


但是在實際過程中是不可能只有兩個台redis伺服器來做主從複製的,這也就意味著這每台redis伺服器都有可能會稱為主節點(master)


下圖案例中,我們的slave3既是master的從節點,也是slave的主節點。


先知道這麼個概念,更多詳解繼續看下文。

Redis主從複製工作原理以及常見問題


二、為什麼需要Redis主從複製?


假設我們現在就一台redis伺服器,也就是單機狀態。


在這種情況下會出現的第一個問題就是伺服器當機,直接導致資料遺失。如果專案是跟¥佔關係的,那造成的後果就可想而知。


第二個情況就是記憶體問題了,當只有一台伺服器時記憶體肯定會到達峰值的,不可能對一台伺服器進行無限升級的。

Redis主從複製工作原理以及常見問題

所以針對以上兩個問題,我們就多準備好幾台伺服器,設定主從複製。將資料保存在多個伺服器上。並且保證每個伺服器的資料是同步的。即使有一個伺服器宕機了,也不會影響使用者的使用。 redis可以繼續實現高可用、同時實現資料的冗餘備份。


這會應該會有很多疑問,master跟slave怎麼連結呢? 如何同步資料呢? 假如master伺服器宕機了呢?別急,一點一點解決你的問題。

Redis主從複製工作原理以及常見問題


三、Redis主從複製的作用


在上邊我們說了為什麼使用redis的主從複製,那麼主從複製的作用就是針對為什麼使用它來講了。


  1. 我們繼續使用這個圖來談論
  2. 第一點是資料冗餘了,實現了資料的熱備份,是持久化之外的另一種方式。
  3. 第二點是針對單機故障問題。當主節點也就是master出現問題時,可以從節點來提供服務也就是slave,實現了快速恢復故障,也就是服務冗餘。
  4. 第三點是讀寫分離,master伺服器主要是寫,slave主要用來讀數據,可以提高伺服器的負載能力。同時可以根據需求的變化,增加從節點的數量。
  5. 第四點是負載平衡,配合讀寫分離,有主節點提供寫入服務,從節點提供讀取服務,分擔伺服器負載,尤其在寫少讀多的情況下,透過多個從節點分擔讀負載,可以大幅提高redis伺服器的並發量和負載。
  6. 第五點是高可用的基石,主從複製是哨兵和叢集能夠實施的基礎,因此我們可以說主從複製是高可用的基石。


#

Redis主從複製工作原理以及常見問題


四、設定Redis主從複製


說了這麼多,我們先簡單的配置一個主從複製案例,然後在談實現的原理。


redis儲存路徑為:usr/local/redis


日誌跟設定檔儲存在:usr/local /redis/data


首先我們先設定兩個設定文件,分別為redis6379.conf  與 redis6380.conf

Redis主從複製工作原理以及常見問題

##

修改設定文件,主要就是修改連接埠。為了查看方便在把日誌檔案和持久化檔案的名字都用各自的連接埠來做標識。

Redis主從複製工作原理以及常見問題

然後分別開啟兩個redis服務,一個連接埠為6379,一個連接埠為6380。執行指令redis-server redis6380.conf,然後使用redis-cli -p 6380連接,因為redis的預設埠就是6379所以我們啟動另一個redis伺服器直接使用redis-server redis6379.conf 然後直接使用redis-cli直接連線就可以。

Redis主從複製工作原理以及常見問題

這時候我們就成功的配置了兩個redis服務,一台為6380,一台為6379,這裡只是為了示範。實際工作中是需要配置在倆台不同的伺服器的。


Redis主從複製工作原理以及常見問題


1. 使用客戶端命令列啟動


#我們先得有一個概念,就是在設定主從複製時,所有的操作都是在從節點來操作,也就是slave。


那麼我們在從節點執行一個指令為 slaveof 127.0.0.1 6379,執行完就代表我們連線上了。

Redis主從複製工作原理以及常見問題

我們先測試一下看看是否實作主從複製。在master這台伺服器上執行兩個伺服器set kaka 123 和 set master 127.0.0.1,然後在slave6380埠是可以成功取得到的,也就說明我們的主從複製就已經配置完成了。但是在實現生產環境可不是就這樣完事了,後邊會在進一步對主從複製進行優化,直到實現高可用。


Redis主從複製工作原理以及常見問題


#2. 使用設定檔啟用


#在使用設定檔啟動主從複製之前呢!先需要把之前使用客戶端命令列連接的斷開,在從主機執行slaveof no one即可斷開主從複製。

Redis主從複製工作原理以及常見問題

在哪裡可以查看從節點已經斷開了主節點!在主節點的客戶端輸入命令列info查看


這張圖是使用從節點使用客戶端命令列連接主節點後,在主節點的客戶端輸入info列印的訊息,可以看到有一個slave0的訊息。

Redis主從複製工作原理以及常見問題

這個圖表是從節點執行完slaveof no one  後,在主節點列印的info,表示從節點已經跟主節點斷開連接了。

Redis主從複製工作原理以及常見問題

在根據設定檔啟動redis服務,redis-server redis6380.conf


當從節點重新啟動後就可以在主節點直接查看到從節點的連線資訊。

Redis主從複製工作原理以及常見問題

測試數據,主節點寫的東西,從節點還是會自動同步的。

Redis主從複製工作原理以及常見問題


#3. 啟動 redis伺服器時啟動


這種方式設定也很簡單,在啟動redis伺服器時直接就啟動主從複製,執行指令:redis-server --slaveof host port  即可。


4. 主從複製啟動後的日誌資訊查看


這個是主節點的日誌資訊

Redis主從複製工作原理以及常見問題

這個是從節點的訊息,其中有連接主節點訊息,還有RDB快照保存。

Redis主從複製工作原理以及常見問題





################################### ##1. 主從複製的三個階段###############主從複製完整的工作流程分為以下三個階段。每一段都有自己的工作內部工作流程,那麼我們就會對著三個流程進程談論。 ############
  • 建立連線過程:這個過程就是slave跟master連線的過程
  • 資料同步過程:是master給slave同步資料的過程
  • 指令傳播過程:是反覆同步資料
    Redis主從複製工作原理以及常見問題


#2. 第一階段:建立連線過程


Redis主從複製工作原理以及常見問題

上圖是一個完整主從複製建立連線工作流程。然後使用簡短的話語來描述上邊的工作流程。


  1. 設定master的地址和端口,保存master的信息
  2. 建立socket連接(這個連接做的事情下文會說)
  3. 持續傳送ping指令
  4. 驗證
  5. 傳送slave連接埠資訊


#

在建立連線的過程中,從節點會儲存master的位址和連接埠、主節點master儲存從節點slave的連接埠。


3. 第二階段:資料同步階段過程


Redis主從複製工作原理以及常見問題



##這張圖是詳細描述第一次從節點連接主節點時的資料同步過程。


當從節點第一次連接主節點時,先會執行一次全量複製這次的全量複製是無法避免的。


全量複製執行完成後,主節點就會發送複製積壓緩衝區的數據,然後從節點就會執行bgrewriteaof恢復數據,也就是部分複製。


在這個階段提到了三個新點,全量複製、部分複製、複製緩衝積壓區。會在下文的常見問題詳細說明這幾個點。 ###############4. 第三階段:指令傳播階段#############

當master資料庫被修改後,主從伺服器的資料不一致後,此時就會讓主從資料同步到一致,這個過程稱之為指令傳播。


master會將接收到的資料變更指令傳送給slave,slave接收指令後執行指令,讓主從資料達到一致。


指令傳播階段的部分複製


  • #在指令傳播階段出現斷網的情況,或網路抖動時會導致連線斷開(connection  lost)
  • 這時候主節點master還是會繼續往replbackbuffer(複製緩衝積壓區)寫資料
  • #從節點會繼續嘗試連接主機(connect to master)
  • 當從節點把自己的runid和複製偏移量發送給主節點,並且執行pysnc指令同步
  • 如果master判斷偏移量是在複製緩衝區範圍內,就會回傳continue指令。並且發送複製緩衝區的資料給從節點。
  • 從節點接收資料執行bgrewriteaof,恢復資料


#六. 詳細介紹主從複製原理(全量複製部分複製)


Redis主從複製工作原理以及常見問題

這個過程就是主從複製最齊全的流程來講解。那麼下來我們對每一步進程簡單的介紹


  1. 從節點發送指令psync ? 1 psync runid offset   找對應的runid索取資料。但這裡可以考慮一下,從節點第一次連接的時候根本就不知道主節點的runid 和 offset  。所以第一次發送的指令是psync ? 1意思就是主節點的資料我全要。
  2. 主節點開始執行bgsave產生RDB文件,記錄目前的複製偏移量offset
  3. 主節點這個時候會把自己的runid  和 offset  透過FULLRESYNC  runid  offset   指令 透過socket發送RDB文件給從節點。
  4. 從節點接收到 FULLRESYNC  保存主節點的runid和offset    然後清空目前所有數據,透過socket接收RDB文件,開始恢復RDB資料。
  5. 在全量複製後,從節點已經取得到了主節點的runid和offset,開始發送指令psync runid offset
  6. 主節點接收指令,判斷runid是否匹配,判斷offset是否在複製緩衝區中。
  7. 主節點判斷runid和offset有一個不滿足,就會在回到步驟2繼續執行全量複製。這裡的runid不匹配只有的可能是從節點重啟了這個問題後邊會解決,offset(偏移量)不匹配就是複製積壓緩衝區溢位了。如果runid或offset校驗通過,從節點的offset和主節點的offset相同時則忽略。如果runid或offset檢定通過,從節點的offset與offset不相同,則會發送 CONTINUE  offset(這個offset為主節點的),透過socket發送複製緩衝區中從節點offset到主節點offset的資料。
  8. 從節點收到 CONTINUE 保存master的offset  透過socket接收到訊息後,執行bgrewriteaof,恢復資料。


1-4是全量複製   5-8是部分複製


在主節點的第3步下面 主節點在主從複製的期間是一直在接收客戶端的數據,主節點的offset是一直變化的。只有有變化就會給每個slave發送,這個發送的過程稱之為心跳機制


七. 心跳機制


#在指令傳播階段是,主節點與從節點之間一直都需要進行資訊互換,使用心跳機制進行維護,實現主節點並從節點連接保持在線。


  • master心跳
    • #指令:ping
    • 預設10秒進行一次,是由參數repl-ping-slave-period決定的
    • 主要做的事情就是判斷從節點是否在線
    • 可以使用info replication  來查看從節點租後一次連接時間的間隔, lag為0或為1就是正常狀態。
  • slave心跳任務
    • #指令:replconf ack {offset}
    • 每秒執行一次
    • 主要做的事情是向主節點發送自己的複製偏移量,從主節點獲取到最新的資料變更命令,還做一件事情就是判斷主節點是否在線上。


#心跳階段的注意事項

主節點為保障資料穩定性,當從節點掛掉的數量或延遲過高時。將會拒絕所有訊息同步。


這裡有兩個參數可以進行設定調整:


#

min-slaves-to-write   2


min-slaves-max-lag 8


這兩個參數表示喪從節點的數量就剩餘2個,或是從節點的延遲大於8秒時,主節點就會強制關閉maste功能,停止資料同步。


那麼主節點就是如果知道從節點掛掉的資料和延遲時間呢! 在心跳機制裡邊slave 會每隔一秒發送perlconf  ack  這個指令,這個指令可攜帶偏移量,也可以攜帶從節點的延遲時間和從節點的數量。


八、部分複製的三個核心要素


#1. 伺服器的運行 id (run id)


我們先來看看這個run id是什麼,執行info指令即可看到。在上文中我們查看啟動日誌資訊也可以看到。


Redis主從複製工作原理以及常見問題

redis在啟動時會自動產生一個隨機的id(這裡要注意的是每次啟動的id都會不一樣),是由40個隨機的十六進位字串組成,用來唯一識別一個redis節點。


當主從複製初次啟動時,master會把自己的runid送到slave,slave會儲存master的這個id,我們可以用info指令查看


Redis主從複製工作原理以及常見問題


#當斷線重連時,slave把這個id傳送給master ,如果slave保存的runid與master現在的runid相同,master會嘗試使用部分複製(這塊能否複製成功還有一個因素就是偏移量)。如果slave儲存的runid與master現在的runid不同,則會直接進行全量複製。


2. 複製積壓緩衝區


複製緩衝積壓區是先進先出的佇列,用戶存儲master收集資料的命令記錄。複製緩衝區的預設儲存空間是1M。


可以在設定檔修改repl-backlog-size 1mb來控制緩衝區大小,這個比例可以根據自己的伺服器記憶體來修改,咔咔這邊是預留了30%左右。


複製緩衝區到底儲存的是什麼?


當執行一個指令為set name kaka時,我們可以查看持久化檔案檢視

Redis主從複製工作原理以及常見問題

那麼複製積壓緩衝區就是儲存的aof持久化的數據,並且以位元組分開,並且每個位元組都有自己的偏移量。這個偏移量也就是複製偏移量(offset)

Redis主從複製工作原理以及常見問題

#那為什麼會說複製緩衝積壓區有可能會導致全量複製呢


在指令傳播階段,主節點會把收集的資料儲存到複製緩衝區中,然後在傳送給從節點。就是這裡出現了問題,當主節點資料量在一瞬間特別大的時候,超出了複製緩衝區的內存,就會有一部分資料會被擠出去,從而導致主節點和從節點的資料不一致。從而進行全量複製。如果這個緩衝區大小不設定合理很大可能會造成死循環,從節點就會一直全量複製,清空數據,全量複製。


3. 複製偏移(offset)


Redis主從複製工作原理以及常見問題

主節點複製偏移量是給從節點發送一次記錄一次,從節點是接收一次記錄一次。


用於同步訊息,對比主節點和從節點的差異,當slave斷聯時恢復資料使用。


這個值也就是來自己在複製緩衝積壓區裡邊的那個偏移。


4. 主從複製常見的問題


#1. 主節點重新啟動問題(內部最佳化)


當主節點重啟後,runid的值會發生變化,會導致所有的從節點進行全量複製。


這個問題我們不需要考慮,知道系統是怎麼優化的即可。


在建立完主從複製後主節點會建立master-replid變量,這個產生的策略跟runid一樣,長度是41位,runid長度是40位,然後發送給從節點。


在主節點執行shutdown  save指令時,進行了一次RDB持久化會把runid 和 offset儲存到RDB檔案中。可以使用指令redis-check-rdb查看該資訊。


Redis主從複製工作原理以及常見問題

主節點重新啟動後載入RDB文件,將文件中的repl-id  和repl-offset載入到內存中。縱使讓所有從節點認為還是之前的主節點。


2. 從節點網路中斷偏移量越界導致全量複製


由於網路環境不佳,從節點網路中斷。複製積壓緩衝區記憶體過小導致資料溢出,伴隨著從節點偏移量越界,導致全量複製。有可能會導致反覆的全量複製。


解決方案:修改複製積壓緩衝區的大小:repl-backlog-size


##設定建議:測試主節點連接從節點的時間,取得主節點每秒平均產生的指令總量write_size_per_second


複製緩衝區空間設定 =   2  

#  主從連線時間    主節點每秒產生的資料總量


3. 頻繁的網路中斷


##由於主節點的cpu佔用過高,或從節點頻繁連接。出現這種情況造成的結果就是主節點各種資源被嚴重佔用,其中包括但不限於緩衝區,寬頻,連線等。


為什麼會出現主節點資源被嚴重佔用?


在心跳機制中,從節點每秒會傳送一個指令replconf  ack指令到主節點。

從節點執行了慢查詢,佔用大量的cpu

主節點每秒呼叫複製定時函數replicationCron,然後從節點長時間沒有對應。


解決方案:

設定從節點逾時釋放


設定參數:repl-timeout


這個參數預設為60秒。超過60秒,釋放slave。


4. 資料不一致問題


#由於網路因素,多個從節點的資料會不一致。這個因素是沒有辦法避免的。


關於這個問題給出兩個解決方案:


第一個資料需要高度一致地配​​置一台redis伺服器,讀寫都用一台伺服器,這種方式僅限於少量數據,並且數據需高度一直。


第二個監控主從節點的偏移量,如果從節點的延遲過大,暫時屏蔽客戶端對該從節點的存取。設定參數為slave-serve-stale-data  yes|no。 這個參數一但設定就只能回應info  slaveof等少數指令。


十. 總結


#本文主要解說了什麼是主從複製、主從複製工作的三大階段以及工作流程、部分複製的三大核心。命令傳播階段的心跳機制。最後說明了主從複製常見問題。

以上是Redis主從複製工作原理以及常見問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn