前面介紹Redis,我們都在一台伺服器上進行操作的,也就是說讀和寫入以及備份操作都是在一台Redis伺服器上進行的,那麼隨著專案存取量的增加,對Redis伺服器的操作也越頻繁,雖然Redis讀寫速度都很快,但是一定程度上也會造成一定的延時,那麼為了解決訪問量大的問題,通常會採取的一種方式是主從架構Master/ Slave,Master 以寫為主,Slave 以讀為主,Master 主節點更新後根據配置,自動同步到從機Slave 節點。
接下來我們就來介紹如何進行主從架構的建構。
ps:這裡我是在一台機器上模擬多個Redis伺服器,與實際生產環境中相比,基本配置都是一樣,只是IP位址和連接埠號碼變化。
先將redis.conf 設定檔複製三份,透過修改埠分別模擬三台Redis伺服器。
然後我們分別對這三個redis.conf 檔案進行修改。
①、修改 daemonize yes
表示指定Redis以守護程式的方式啟動(背景啟動)
## 表示指定Redis以守護程式的方式啟動(背景啟動)②、配置PID檔案路徑pidfile
表示當redis作為守護程式運行的時候,它會把pid 預設寫到/var/redis /run/redis_6379.pid 檔案裡面
③、設定埠port
# ④、設定log 檔案名稱
#
④、設定log 檔案名字##
④、設定log 檔案名字##④、設定log 檔案名字
####
⑤、配置rdb文件名
接下來我們分別啟動這三個服務。 透過指令查看Redis是否啟動: |
1 | 3
①、通過 info replication 命令查看節點角色
我們發現這三個節點都是扮演的Master 角色。如何將節點6380和6381轉換為從節點角色?
②、選擇6380端口和6381端口,執行命令:SLAVEOF 127.0.0.1 6379
#節點## 我們資訊6399 再看
#3、測試主從關係
①、增量複製主節點執行set k1 v1 指令,從節點get k1 能取得嗎?
#由上圖可知是可以取得的。
②、全量複製透過執行 SLAVEOF 127.0.0.1 6379,如果主節點6379 以前還存在一些key,那麼執行指令之後,從節點會以前的資訊也都複製過來嗎?
答案也是肯定的,這裡我就不貼測試結果了。
③、主從讀寫分離主節點能夠執行寫入指令,從節點能夠執行寫入指令嗎?
這裡的原因是在配置文件6381redis.conf 中對於slave-read-only 的配置
如果我們將其修改為no 之後,執行寫入命令是可以的。
但是從節點寫指令的資料從節點或主節點都不能取得的。
④、主節點宕機主節點 Maste 掛掉,兩個從節點角色會改變嗎?
# 上圖可知主節點 Master 掛掉之後,從節點角色還是不會改變的。
⑤、主節點宕機後恢復主節點Master掛掉之後,馬上啟動主機Maste,主節點扮演的角色還是 Master 嗎?
4、哨兵模式
透過前面的配置,主節點Master 只有一個,一旦主節點掛掉之後,從節點沒辦法擔起主節點的任務,那麼整個系統也無法運行。哨兵模式由此誕生,因為從節點能夠自動接手主節點的職責,解決了主節點宕機的問題。
哨兵模式就是不時地監控redis是否按照預期良好地運作(至少是保證主節點是存在的),若一台主機出現問題時,哨兵會自動將該主機下的某一個從機設定為新的主機,並讓其他從機和新主機建立主從關係。
哨兵模式建構步驟:
①、在設定檔目錄下新建sentinel.conf 文件,名字絕不能錯,然後設定對應內容
###1### |
|
| 分別配置被監控的名字,ip位址,連接埠號,以及得票數。當主機宕機時,從機需要投票決定誰接替成為主機,得票數達到1時不足以成為主機,必須超過1才可成為主機
啟動介面:
接下來,我們幹掉主機 6379,然後看從節點有啥變化。
幹掉主節點之後,我們查看後台列印日誌,發現 6381投票變成主節點了。
這時候我們查看從節點 6381的節點資訊:
# 6381 節點自動變成主節點了。
PS:哨兵模式也存在單點故障問題,如果哨兵機器掛了,那麼就無法進行監控了,解決辦法是哨兵也建立集群,Redis哨兵模式是支援集群的。
Redis的複製功能包括同步(sync)和命令傳播(command propagate)兩種操作。
①、舊版同步
當從節點發出 SLAVEOF 指令,要求從伺服器複製主伺服器時,從伺服器透過向主伺服器發送 SYNC 指令來完成。此指令執行步驟:
1、從伺服器向主伺服器發送SYNC 指令
2、收到SYNC 指令的主伺服器執行BGSAVE 指令,在後台產生一個RDB 文件,並使用一個緩衝區記錄從開始執行的所有寫入指令
3、當主伺服器的BGSAVE 指令執行完畢時,主伺服器會將BGSAVE 指令產生的RDB 檔案傳送給從伺服器,從伺服器接收此RDB 文件,並將伺服器狀態更新為RDB檔案記錄的狀態。
4、主伺服器將緩衝區的所有寫入命令也傳送給從伺服器,從伺服器執行對應命令。
②、命令傳播
當同步操作完成之後,主伺服器會進行對應的修改命令,這時候從伺服器和主伺服器狀態就會不一致。
為了讓主伺服器和從伺服器保持狀態一致,主伺服器需要對從伺服器執行指令傳播操作,主伺服器會將自己的寫入指令傳送給從伺服器執行。從伺服器執行相應的命令之後,主從伺服器狀態繼續保持一致。
總結:透過同步操作以及指令傳播功能,能夠很好的保證了主從一致的特性。
但是我們考慮一個問題,如果從伺服器在同步主伺服器期間,突然斷開了連接,而這時候主伺服器進行了一些寫入操作,這時候從伺服器恢復連接,如果我們在進行同步,那麼就必須將主伺服器從新生成一個RDB文件,然後給從伺服器加載,這樣雖然能夠保證一致性,但是其實斷開連接之前主從伺服器狀態是保持一致的,不一致的是從伺服器斷開連接,而主伺服器執行了一些寫入指令,那麼從伺服器恢復連線後能不能只要斷線的哪些寫指令,而不是整個RDB快照呢?
同步操作其實是一個非常耗時的操作,主伺服器需要先透過BGSAVE 指令來產生一個RDB 文件,然後需要將該檔案傳送給從伺服器,從伺服器接收該檔案之後,接著載入該文件,並且在載入期間,從伺服器是無法處理其他命令的。
為了解決這個問題,Redis從2.8版本之後,使用了新的同步指令 PSYNC 來取代 SYNC 指令。此指令的部分重同步功能用於處理斷線後重複製的效率問題。也就是說當從伺服器在斷線後重新連接主伺服器時,主伺服器只將斷開連接後執行的寫入命令傳送給從伺服器,從伺服器只需要接收並執行這些寫入命令即可保持主從一致。
主從複製雖然解決了主節點的單點故障問題,但是由於所有的寫入操作都是在Master 節點上操作,然後同步到Slave 節點,那麼同步就會有一定的延時,當系統很繁忙的時候,延時問題就會更加嚴重,而且會隨著從節點slave的增加而愈加嚴重。
以上是Redis如何實現主從複製的詳細內容。更多資訊請關注PHP中文網其他相關文章!