跟隨槓精的視角一起來了解Redis的主從複製
不想彈好吉他的擼鐵狗,都不是好的程式猿
雖然說單機的Redis效能很好,也有完備的持久化機制,那如果你的業務體量真的很大,超過了單機能夠承載的上限了怎麼辦?不做任何處理的話Redis掛了怎麼辦?帶著這個問題開始我們今天的主題-「Redis高可用」,由於篇幅原因,本章就只聊聊主從複製。
為啥要先從主從複製開始聊,是因為「主從複製」可以說是整個Redis高可用實現的基石,你可以先有這麼一個概念,至於具體為什麼是基石,這個後面聊到Sentinel和Redis叢集的時候會說到。
首先我們需要知道,對於我們開發人員來說,為什麼需要「主從架構」?一個Redis例項難道不行嗎?
其實除了開篇提到的負載超過了Redis單機能夠處理的上限,還有一種情況Redis也無法保證自身的高可用性。那就是即便Redis能夠扛住所有流量,但是如果這個Redis程序所在的機器掛了呢?請求會直接調轉槍口,大量的流量會瞬間把你的DB打掛,然後你就可以背個P0,打包回家了。
而且,假設你對Redis的需求真的超過了單機的容量,你怎麼辦?搞多臺獨立的Redis例項嗎?那如果使用者快取的資料這一次存在了例項一,下一次如果使用者又訪問到了例項二,難道又要去走一遍DB嗎?除非你能夠維護好使用者和Redis例項的對應關係(但是通常這樣的邏輯比較複雜),否則部署多個Redis例項也就失去了它的意義,沒有辦法做到橫向擴充套件了。
那換成主從架構就能解決這個問題嗎?
我們可以從一個圖來直觀的瞭解一下。
在主從同步中,我們將節點的角色劃分為master
和slave
,形成「一主多從」。slave對外提供讀操作,而master負責寫操作,形成一個讀寫分離的架構,這樣一來就能夠承載更多的業務請求。
在多數的業務場景下,對於Redis的「讀操作」都要多於「寫操作」,所以當讀請求量特別大的時候,我們可以通過增加slave節點來使Redis扛住更多的流量。
你這不行啊老弟,你往master寫資料,那我要是連線到slave上去了,不就拿不到之前的資料了?
我這個小標題的不是寫了嗎?「主從複製」,slave會按照某種策略從master同步資料。Redis中我們可以通過slaveof
命令讓一個Redis例項去複製(replicate)另外一臺Redis的狀態。被複制的Redis例項就是master節點,而執行slaveof
命令的機器就是slave節點。
Redis的主從複製分為兩個步驟,分別是「同步」和「命令傳播」。
「同步操作」用於將Master節點記憶體狀態複製給Slave節點,而「命令傳播」則是在同步時,客戶端又執行了一些「寫」操作改變了伺服器的狀態,此時master節點的狀態與同步操作執行的時候不一致了,所以需要命令傳播來使master和slave狀態重新一致。
同步的大致的流程如下:
slave節點向master節點發送 sync
命令master收到 sync
命令之後會執行bgsave
命令,Redis會fork出一個子程序在後臺生成RDB檔案,同時將同步過程中的寫命令記錄到緩衝區中檔案生成後,master會把RDB檔案傳送給slave,從伺服器接收到RDB檔案會將其載入記憶體 然後master將記錄在緩衝區的所有寫命令傳送給slave,slave對這些命令進行「重放」,將其資料庫的狀態更新至和master一致
為了讓大家更加清晰的認識到這個過程,我們通過圖再來了解一下。