1. 程式人生 > >Redis叢集主從複製(一主兩從)搭建配置教程【Windows環境】

Redis叢集主從複製(一主兩從)搭建配置教程【Windows環境】

由於本地環境的使用,所以搭建一個本地的Redis叢集,本篇講解Redis主從複製叢集的搭建,使用的平臺是Windows,搭建的思路和Linux上基本一致! (精讀閱讀本篇可能花費您15分鐘,略讀需5分鐘左右)

Redis主從複製簡單介紹

為了使得叢集在一部分節點下線或者無法與叢集的大多數節點進行通訊的情況下, 仍然可以正常運作, Redis 叢集對節點使用了主從複製功能: 叢集中的每個節點都有 1 個至 N 個複製品(replica), 其中一個複製品為主節點(master), 而其餘的 N-1 個複製品為從節點(slave)。[ 摘自 Redis 叢集中的主從複製 ]

那麼上面是主從複製呢,簡單的來說就是一個主節點master可以擁有一個甚至多個從節點的slave,而一個slave又可以擁有多個slave,如此下去,形成了強大的多級伺服器叢集架構。 Master-Slave主從

其中主節點以寫為主(可寫也可以讀),從節點只能讀不可寫入!【讀寫分離場景】  其中主節點寫入的資料會同步(不是準實時的)到salve上,這樣如果主節點出現故障,資料丟失,則可以通過salve進行恢復。【容災恢復場景,注:因為資料不是實時同步的,可能會存在從salve恢復資料後有資料丟失問題】

綜上:下面是關於redis主從複製的一些特點:  1.一個master可以有多個slave  2.除了多個slave連到相同的master外,slave也可以連線其他slave形成圖狀結構  3.主從複製不會阻塞master。也就是說當一個或多個slave與master進行初次同步資料時,master可以繼續處理client發來的請求。相反slave在初次同步資料時則會阻塞不能處理client的請求。  4.主從複製可以用來提高系統的可伸縮性,我們可以用多個slave 專門用於client的讀請求,比如sort操作可以使用slave來處理。也可以用來做簡單的資料冗餘  5.可以在master禁用資料持久化,只需要註釋掉master 配置檔案中的所有save配置,然後只在slave上配置資料持久化。  6.可以用於讀寫分離和容災恢復。

Redis主從複製的常用的幾種方式

  1. 一主二僕 A(B、C) 一個Master兩個Slave
  2. 薪火相傳(去中心化)A - B - C ,B既是主節點(C的主節點),又是從節點(A的從節點)
  3. 反客為主(主節點down掉後,手動操作升級從節點為主節點) & 哨兵模式(主節點down掉後,自動升級從節點為主節點)

本次主要介紹一主二僕,和反客為主的操作,薪火相傳不做介紹。哨兵模式後面專門寫一篇進行介紹!

Redis主從複製的搭建(一主二僕)

1.下載Windows環境的Redis安裝包

2.下載完成進行解壓

解壓收的目錄如下圖: Window的Redis解壓圖

3.相關配置操作

(1)複製三份解壓後Redis

我自己本地修改了名稱,複製後文件夾名稱顯示如下:

<span style="color:#000000"><code>Redis-x64<span style="color:#4f4f4f">-</span><span style="color:#006666">3.2</span><span style="color:#006666">.100</span><span style="color:#4f4f4f">-</span><span style="color:#006666">6379</span>
Redis-x64<span style="color:#4f4f4f">-</span><span style="color:#006666">3.2</span><span style="color:#006666">.100</span><span style="color:#4f4f4f">-</span><span style="color:#006666">6380</span>
Redis-x64<span style="color:#4f4f4f">-</span><span style="color:#006666">3.2</span><span style="color:#006666">.100</span><span style="color:#4f4f4f">-</span><span style="color:#006666">6381</span>
</code></span>

(2)修改redis.windows.conf

6379資料夾,不做修改!

6380資料夾,修改如下:

<span style="color:#000000"><code>port 6380

# slaveof <span style="color:#006666"><<span style="color:#4f4f4f">masterip</span>></span> <span style="color:#006666"><<span style="color:#4f4f4f">masterport</span>></span>
slaveof 127.0.0.1 6379
</code></span>

6381資料夾,修改如下:

<span style="color:#000000"><code><span style="color:#000088">port</span> <span style="color:#006666">6381</span>
slaveof <span style="color:#006666">127.0</span><span style="color:#006666">.0</span><span style="color:#006666">.1</span> <span style="color:#006666">6379</span>
</code></span>

(3)加入簡單的window指令碼,方便快速啟動!

在對應的redis資料夾下面新建

startRedisServer.bat

指令碼的內容為:

<span style="color:#000000"><code>@echo off
redis-server<span style="color:#009900">.exe</span> redis<span style="color:#009900">.windows</span><span style="color:#009900">.conf</span>
@pause
</code></span>

然後在redis資料夾同級的目錄下在新建

start6379.cmd

<span style="color:#000000"><code>@<span style="color:#4f4f4f">echo</span> off
<span style="color:#4f4f4f">cd</span> Redis-x64-<span style="color:#006666">3.2</span>.<span style="color:#006666">100</span>-<span style="color:#006666">6379</span>
startRedisServer.bat
</code></span>

然後6380和6381和上面操作一樣,操作完成後如下圖:

目錄結構圖

4.啟動測試

啟動規則:先啟動主節點,然後在啟動從節點!

(1)可以使用命令啟動

進入相應的資料夾目錄,使用啟動命令:

redis-server.exe

(2)使用指令碼啟動

如上面圖片,分別執行start6379.cmd,  start6380.cmd,start6381.cmd。

先啟動Master。使用客戶端登入,檢視資訊如圖:

Master啟動後資訊

然後啟動6380和6381,然後可以看到:如圖

Salve啟動

在此檢視6378的主從複製資訊:如圖

主節點詳細資訊

在登入6380和6381的客戶端,檢視節點資訊:如圖

從節點詳細資訊

測試讀寫,【主節點可讀可寫,從節點只能讀不可寫】,如下圖:

讀寫測試

測試當主節點shutdown後,從節點的狀態【從節點可讀,從節點也不會升級為主節點】:

<span style="color:#000000"><code>127<span style="color:#9b703f">.0</span><span style="color:#9b703f">.0</span><span style="color:#9b703f">.1</span><span style="color:#000000">:6381</span>> <span style="color:#000000">info</span> <span style="color:#000000">replication</span>
# <span style="color:#000000">Replication</span>
<span style="color:#000000">role</span><span style="color:#000000">:slave</span>
<span style="color:#000000">master_host</span><span style="color:#000000">:127</span><span style="color:#9b703f">.0</span><span style="color:#9b703f">.0</span><span style="color:#9b703f">.1</span>
<span style="color:#000000">master_port</span><span style="color:#000000">:6379</span>
<span style="color:#000000">master_link_status</span><span style="color:#000000">:up</span>
<span style="color:#000000">master_last_io_seconds_ago</span><span style="color:#000000">:1</span>
<span style="color:#000000">master_sync_in_progress</span><span style="color:#000000">:0</span>
<span style="color:#000000">slave_repl_offset</span><span style="color:#000000">:15</span>
<span style="color:#000000">slave_priority</span><span style="color:#000000">:100</span>
<span style="color:#000000">slave_read_only</span><span style="color:#000000">:1</span>
<span style="color:#000000">connected_slaves</span><span style="color:#000000">:0</span>
<span style="color:#000000">master_repl_offset</span><span style="color:#000000">:0</span>
<span style="color:#000000">repl_backlog_active</span><span style="color:#000000">:0</span>
<span style="color:#000000">repl_backlog_size</span><span style="color:#000000">:1048576</span>
<span style="color:#000000">repl_backlog_first_byte_offset</span><span style="color:#000000">:0</span>
<span style="color:#000000">repl_backlog_histlen</span><span style="color:#000000">:0</span>
127<span style="color:#9b703f">.0</span><span style="color:#9b703f">.0</span><span style="color:#9b703f">.1</span><span style="color:#000000">:6381</span>>
127<span style="color:#9b703f">.0</span><span style="color:#9b703f">.0</span><span style="color:#9b703f">.1</span><span style="color:#000000">:6381</span>> <span style="color:#000000">get</span> <span style="color:#000000">hello</span>
"<span style="color:#000000">world</span>"
</code></span>

測試當主節點重新啟動後,從節點的狀態【從節點依然可以連線主節點】:

<span style="color:#000000"><code><span style="color:#006666">127.0</span><span style="color:#006666">.0</span><span style="color:#006666">.1</span>:<span style="color:#006666">6379</span>> info replication
<span style="color:#009900"># Replication</span>
role:master
connected_slaves:<span style="color:#006666">2</span>
slave0:ip=<span style="color:#006666">127.0</span><span style="color:#006666">.0</span><span style="color:#006666">.1</span>,port=<span style="color:#006666">6380</span>,state=online,offset=<span style="color:#006666">43</span>,lag=<span style="color:#006666">0</span>
slave1:ip=<span style="color:#006666">127.0</span><span style="color:#006666">.0</span><span style="color:#006666">.1</span>,port=<span style="color:#006666">6381</span>,state=online,offset=<span style="color:#006666">43</span>,lag=<span style="color:#006666">0</span>
master_repl_offset:<span style="color:#006666">43</span>
repl_backlog_active:<span style="color:#006666">1</span>
repl_backlog_size:<span style="color:#006666">1048576</span>
repl_backlog_first_byte_offset:<span style="color:#006666">2</span>
repl_backlog_histlen:<span style="color:#006666">42</span>
<span style="color:#006666">127.0</span><span style="color:#006666">.0</span><span style="color:#006666">.1</span>:<span style="color:#006666">6379</span>>
</code></span>

小插曲【反客為主】  測試當主節點shutdown後,使用slaveof no one 是的6380成為主節點,但是也只是主節點,沒有任何從節點!:如圖

<span style="color:#000000"><code><span style="color:#006666">127.0</span><span style="color:#006666">.0</span><span style="color:#006666">.1</span>:<span style="color:#006666">6381</span>> info replication
<span style="color:#880000"># Replication</span>
role:slave
master_host:<span style="color:#006666">127.0</span><span style="color:#006666">.0</span><span style="color:#006666">.1</span>
master_port:<span style="color:#006666">6379</span>
master_link_status:down
master_last_io_seconds_ago:-<span style="color:#006666">1</span>
master_sync_in_progress:<span style="color:#006666">0</span>
slave_repl_offset:<span style="color:#006666">155</span>
master_link_down_since_seconds:jd
slave_priority:<span style="color:#006666">100</span>
slave_read_only:<span style="color:#006666">1</span>
connected_slaves:<span style="color:#006666">0</span>
master_repl_offset:<span style="color:#006666">0</span>
repl_backlog_active:<span style="color:#006666">0</span>
repl_backlog_size:<span style="color:#006666">1048576</span>
repl_backlog_first_byte_offset:<span style="color:#006666">0</span>
repl_backlog_histlen:<span style="color:#006666">0</span>
<span style="color:#006666">127.0</span><span style="color:#006666">.0</span><span style="color:#006666">.1</span>:<span style="color:#006666">6381</span>>
<span style="color:#006666">127.0</span><span style="color:#006666">.0</span><span style="color:#006666">.1</span>:<span style="color:#006666">6381</span>>
<span style="color:#006666">127.0</span><span style="color:#006666">.0</span><span style="color:#006666">.1</span>:<span style="color:#006666">6381</span>> slave no <span style="color:#009900">one</span>
(error) ERR unknown <span style="color:#000088">command</span> <span style="color:#009900">'slave'</span>
<span style="color:#006666">127.0</span><span style="color:#006666">.0</span><span style="color:#006666">.1</span>:<span style="color:#006666">6381</span>> slaveof no <span style="color:#009900">one</span>
OK
<span style="color:#006666">127.0</span><span style="color:#006666">.0</span><span style="color:#006666">.1</span>:<span style="color:#006666">6381</span>> info replication
<span style="color:#880000"># Replication</span>
role:master
connected_slaves:<span style="color:#006666">0</span>
master_repl_offset:<span style="color:#006666">0</span>
repl_backlog_active:<span style="color:#006666">0</span>
repl_backlog_size:<span style="color:#006666">1048576</span>
repl_backlog_first_byte_offset:<span style="color:#006666">0</span>
repl_backlog_histlen:<span style="color:#006666">0</span>
<span style="color:#006666">127.0</span><span style="color:#006666">.0</span><span style="color:#006666">.1</span>:<span style="color:#006666">6381</span>> <span style="color:#4f4f4f">set</span> test <span style="color:#006666">11</span>
OK
<span style="color:#006666">127.0</span><span style="color:#006666">.0</span><span style="color:#006666">.1</span>:<span style="color:#006666">6381</span>> <span style="color:#4f4f4f">get</span> test
<span style="color:#009900">"11"</span>
<span style="color:#006666">127.0</span><span style="color:#006666">.0</span><span style="color:#006666">.1</span>:<span style="color:#006666">6381</span>>
</code></span>

Redis主從複製的原理

第一種介紹

  1. 當設定好slave伺服器後,slave會建立和master的連線,然後傳送sync命令。
  2. Master接到命令啟動後臺的存檔程序,同時收集所有接收到的用於修改資料集命令,在後臺程序執行完畢之後,master將傳送整個資料檔案到slave,以完成一次完全同步。
  3. 全量複製:而slave服務在接收到資料庫檔案資料後,將其存檔並載入到記憶體中。(第一次全量)
  4. 增量複製:Master繼續將新的所有收集到的修改命令依次傳給slave,完成同步。(之後增量)
  5. 但是隻要是重新連線master,一次完全同步(全量複製)將被自動執行。

當設定好slave伺服器後,slave會建立和master的連線,然後傳送sync命令。無論是第一次同步建立的連線還是連線斷開後的重新連線,master都會啟動一個後臺程序,將資料庫快照儲存到檔案中,同時master主程序會開始收集新的寫命令並快取起來。後臺程序完成寫檔案 後,master就傳送檔案給slave,slave將檔案儲存到磁碟上,然後載入到記憶體恢復資料庫快照到slave上。接著master就會把快取的命令轉發給slave。而且後續master收到的寫命令都會通過開始建立的連線傳送給slave。從master到slave的同步資料的命令和從 client傳送的命令使用相同的協議格式。當master和slave的連線斷開時slave可以自動重新建立連線。如果master同時收到多個 slave發來的同步連線命令,只會使用啟動一個程序來寫資料庫映象,然後傳送給所有slave。

第二種介紹:

圖片內容來源網路:

redis主從複製原理

第三種介紹:

Redis 主從同步有兩種方式(或者所兩個階段):全同步和部分同步。  主從剛剛連線的時候,進行全同步;全同步結束後,進行部分同步。當然,如果有需要,Slave 在任何時候都可以發起全同步。Redis 策略是,無論如何,首先會嘗試進行部分同步,如不成功,要求從機進行全同步,並啟動 BGSAVE……BGSAVE 結束後,傳輸 RDB 檔案;如果成功,允許從機進行部分同步,並傳輸積壓空間中的資料。 同步原理圖

Redis主從複製(一主兩從/一主多從)的分析

  • IO劇增  每次slave斷開以後(無論是主動斷開,還是網路故障)再連線master都要將master全部dump出來rdb,在aof,即同步的過程都要重新執行一遍;所以要記住多臺slave不要一下都啟動起來,否則master可能IO劇增(間隔1-2分)

  • 複製延遲  由於所有的寫操作都是先在Master上操作,然後同步更新到Slave上,所以從Master同步到Slave機器有一定的延遲,當系統很繁忙的時候,延遲問題會更加嚴重,Slave機器數量的增加也會使這個問題更加嚴重。

  • 可用性不高  當有主節點發生異常情況,就會導致不能寫入,導致業務出錯![解決方法是可以使用Redis-Sentinel模式,詳情見系列文章第二篇]

注意:  Redis 叢集不保證資料的強一致性(strong consistency)Redis 叢集的一致性保證(guarantee): 在特定條件下, Redis 叢集可能會丟失已經被執行過的寫命令。

參考文章

附件

如果想直接使用本篇講解使用的主從配置!我已經打包好了 點選 下載地址 進行下載!

本系列文章:

如果您覺得這篇博文對你有幫助,請點個贊,謝謝!

如果帥氣(美麗)、睿智(聰穎),和我一樣簡單善良的你看到本篇博文中存在問題,請指出,我虛心接受你讓我成長的批評,謝謝閱讀! 祝你今天開心愉快!

歡迎訪問我的csdn部落格,我們一同成長!

不管做什麼,只要堅持下去就會看到不一樣!在路上,不卑不亢!