天天看點

Redis Cluster 叢集的實作和管理系統環境叢集規劃建立步驟需要注意的問題

系統環境

CentOS 7

叢集規劃

在一台實體機(實際部署應當分散到多個實體機上),建立6個redis節點,其中3個主節點、3個從節點。

節點表:

IP 端口 主從 路徑

192.168.1.21 7001 主 ~/redis-cluster/7001/

192.168.1.21 7002 主 ~/redis-cluster/7002/

192.168.1.21 7003 主 ~/redis-cluster/7003/

192.168.1.21 7011 從 ~/redis-cluster/7011/

192.168.1.21 7012 從 ~/redis-cluster/7012/

192.168.1.21 7013 從 ~/redis-cluster/7013/

建立步驟

01. 準備環境

# yum install gcc
# yum install ruby
# yum install ruby-devel.x86_64
# yum install rubygems
# gem sources -r https://rubygems.org
# gem sources -a http://rubygems.org  
# gem install redis
           

02. 下載下傳安裝 redis

# cd~
# wget http://download.redis.io/releases/redis-3.0.7.tar.gz
# tar zxfv redis-3.0.7.tar.gz
# cd redis-3.0.7
# make MALLOC=libc
# cp src/redis-server /usr/local/bin
# cp src/redis-cli /usr/local/bin
# cp src/redis-trib.rb /usr/local/bin
           

03. 獨立啟動/停止 redis

# redis-server &
# redis-cli shutdown
           

04. 測試獨立 redis

# redis-cli -p 7001
:> set mykey myval01
:> get mykey
"myval01"
           

05. 建立叢集環境

# cd~
# mkdir redis-cluster
# cd redis-cluster
# mkdir 7001 7002 7003 7011 7012 7013
           

建立配置檔案 ~/redis-cluster/redis.conf,内容如下:

port 
daemonize yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 
appendonly yes
           

檔案中的 cluster-enabled 選項用于開執行個體的叢集模式, 而 cluster-conf-file 選項則設定了儲存節點配置檔案的路徑, 預設值為 nodes.conf。該節點配置檔案無須人為修改,它由Redis叢集在啟動時自動建立, 并在有需要時自動進行更新。

若要讓叢集正常運作至少需要三個主節點,我們的環境中,每個主節點附帶一個從節點,是以一共六個節點。

為每個節點建立配置檔案

# cd ~/redis-cluster
# cp redis.conf ./7001/
# …
# cp redis.conf ./7013/
           

修改各個目錄下的 redis.conf 檔案中的 port 為各自對應的端口

06. 啟動各個節點

# cd ~/redis-cluster
# cd 7001
# redis-server redis.conf
# cd ../7002
# redis-server redis.conf
# …
# cd ../7013
# redis-server redis.conf
           

檢視redis的啟動情況

07. 建立叢集

現在我們已經有了六個正在運作中的 Redis 執行個體, 接下來我們需要使用這些執行個體來建立叢集。

通過使用 Redis 叢集指令行工具 redis-trib , 編寫節點配置檔案的工作可以非常容易地完成: redis-trib 位于 Redis 源碼的 src 檔案夾中, 它是一個 Ruby 程式, 這個程式通過向執行個體發送特殊指令來完成建立新叢集, 檢查叢集, 或者對叢集進行重新分片(reshared)等工作。這裡通過create指令來建立叢集。

# cd ~/redis-3.0.0/src
# ./redis-trib.rb create --replicas 1 192.168.1.21:7001 192.168.1.21:7002 192.168.1.21:7003 192.168.1.21:7011 192.168.1.21:7012 192.168.1.21:7013
           

說明:

這裡的IP位址必須是真實的IP,不能使用回環 127.0.0.1 位址。

–replicas 1 即每一個master有1個slave;順序為 m m m s s s

redis-trib 會列印出一份預想中的配置給你看, 如果你覺得沒問題的話, 就可以輸入 yes , redis-trib 就會将這份配置應用到叢集當中,讓各個節點開始互相通訊。

輸入yes,然後配置完成。

以上資訊的其中一部分可以通過向叢集中的任意節點(主節點或者從節點都可以)發送 CLUSTER NODES 指令來獲得。該指令還可以獲得節點 ID , IP 位址和端口号, 标志(flag), 最後發送 PING 的時間, 最後接收 PONG 的時間, 連接配接狀态, 節點負責處理的槽。

08. 叢集檢查

./redis-trib.rb check .:
           

09. 連接配接Redis叢集

通過上面的輸出,我們可以看出Redis三個主節點的slot範圍。一個 Redis 用戶端可以向叢集中的任意節點(包括從節點)發送指令請求。我們首先連接配接第一個節點:

# redis-cli -p 7001

:> set a  
(error) MOVED  :
:> get a
(error) MOVED  :
:> set b 
OK
           

雖然我們用Node ID來辨別叢集中的節點, 但是為了讓用戶端的轉向操作盡可能地簡單, 節點在 MOVED 錯誤中直接傳回目标節點的 IP 和端口号, 而不是目标節點的 ID 。用戶端應該記錄槽15495由節點127.0.0.1:7003負責處理“這一資訊, 這樣當再次有指令需要對槽15495執行時, 用戶端就可以加快尋找正确節點的速度。這樣,當叢集處于穩定狀态時,所有用戶端最終都會儲存有一個哈希槽至節點的映射記錄,使得叢集非常高效: 用戶端可以直接向正确的節點發送指令請求, 無須轉向、代理或者其他任何可能發生單點故障(single point failure)的實體(entiy)。

10. 添加新master節點

a. 啟動節點

# cd ~/redis-cluster
# mkdir 8001
# cp ./redis.conf ./8001
# cd 8001
# redis-server redis.conf
           

b. 将節點加入到叢集

說明:

第一個 ip:port 為新節點

第二個 ip:port 是任意一個已經存在的節點

新節點沒有包含任何資料,也沒有包含任何slot。

當叢集需要将某個從節點更新為新的主節點時, 這個新節點不會被選中,同時新的主節點因為沒有包含任何slot,不參加選舉和failover。

c. 為新節點配置設定 slot

# redis-trib.rb reshard 127.0.0.1:8001  
#根據提示選擇要遷移的slot數量(ps:這裡選擇500)  
How many slots do you want to move (from  to )?   
#選擇要接受這些slot的node-id  
What is the receiving node ID? f51e26b5d5ff74f85341f06f28f125b7254e61bf  
#選擇slot來源:  
#all表示從所有的master重新配置設定,  
#或者資料要提取slot的master節點id,最後用done結束  
Please enter all the source node IDs.  
  Type 'all' to use all the nodes as source nodes for the hash slots.  
  Type 'done' once you entered all the source nodes IDs.  
Source node #1:all  
#列印被移動的slot後,輸入yes開始移動slot以及對應的資料.  
#Do you want to proceed with the proposed reshard plan (yes/no)? yes  
#結束  
           

11. 添加新的 Slave 節點

a. 啟動節點

# cd ~/redis-cluster
# mkdir 8011
# cp ./redis.conf ./8011
# cd 8011
# redis-server redis.conf
           

b. 将節點加入到叢集

方法一:

說明:

第一個 ip:port 為新節點

第二個 ip:port 是任意一個已經存在的節點

新的節點會作為叢集中其中一個主節點的從節點,一般來說是從節點最少的主節點。

方法二:

說明:

-master-id xxxx 主節點的 ID

第一個 ip:port 為新節點

第二個 ip:port 是任意一個已經存在的節點

注意:線上添加slave 時,需要bgsave整個master資料,并傳遞到slave,再由 slave加載rdb檔案到記憶體,rdb生成和傳輸的過程中消耗Master大量記憶體和網絡IO,以此不建議單執行個體記憶體過大,線上小心操作。

12. 線上 reshard 資料

對于負載/資料不均勻的情況,可以線上reshard slot來解決,方法與添加新master的reshard一樣,隻是需要reshard的master節點是已存在的老節點。

13. 删除一個 slave 節點

# redis-trib.rb del-node ip:port '<node-id>'  
# redis-trib.rb del-node : 'c7ee2fca17cb79fe3c9822ced1d4f6c5e169e378' 
           

說明:

ip:port 叢集中已有的任意一節點(不是被删除的節點)

被删除節點的 ID

14. 删除一個 master 節點(7003)

删除master節點之前首先要使用reshard移除master的全部slot,然後再删除目前節點。 (目前redis-trib.rb隻能把被删除master的slot對應的資料遷移到一個節點上)。

a. 遷移 slot

#把127.0.0.1:7003目前master遷移到127.0.0.1:7002上  
redis-trib.rb reshard :  
#根據提示選擇要遷移的slot數量(ps:這裡選擇500)  
How many slots do you want to move (from  to )? (被删除master的所有slot數量)  
#選擇要接受這些slot的node-id(172.0.0.1:7002)  
What is the receiving node ID? c4a31c852f81686f6ed8bcd6d1b13accdc947fd2 (ps::的node-id)  
Please enter all the source node IDs.  
  Type 'all' to use all the nodes as source nodes for the hash slots.  
  Type 'done' once you entered all the source nodes IDs.  
Source node #1:f51e26b5d5ff74f85341f06f28f125b7254e61bf(被删除master的node-id)  
Source node #2:done  
#列印被移動的slot後,輸入yes開始移動slot以及對應的資料.  
#Do you want to proceed with the proposed reshard plan (yes/no)? yes  
           

b. 删除空的 master 節點

說明:

ip:port 叢集中已有的任意一節點(不是被删除的節點)

被删除節點的 ID

15. 改變從節點的隸屬關系(從節點 7013)

# redis-cli -p 7013
:> cluster replicate b9ebcbd627ff0fd7a7bbcc5332fb09e72788835
說明:
  b9ebcbd627ff0fd7a7bbcc5332fb09e72788835  為新的主節點的 ID
           

16. 叢集的關閉和重新開機

redis cluster官方文檔,沒發現有關叢集重新開機和關閉的方法。主要是因為在正式的環境中叢集一般都由3台實體機構成,3台實體機同時挂掉的可能性極小。隻要不同時挂掉,挂掉的機器修複後在加入叢集,叢集都能良好的運作,萬一同時挂掉,資料又沒有備份的話,就有大麻煩了。

redis cluster叢集中的節點基本上都對等的,沒有管理節點。如果要讓所有節點都關閉,隻能關閉所有 redis-server 程序。

然後重新啟動,如果直接重新開機會報告錯誤。

會報以下錯誤,

[ERR] Node : is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 
           

第一次啟動叢集時,~/redis-cluster/7001/ 下隻有 redis.conf,而現在重新開機時,此目錄下有了别的檔案,所有報錯。簡單的方法是将除了 redis.conf 外的其他檔案全部删除,在啟動肯定是可以的,但是叢集是有資料的,是以需要保留了配置檔案 redis.conf 和資料檔案 *.rdb。

這樣是可以啟動的,但是原來的資料還是丢失了,不知道是自己的想法不對。

需要注意的問題

  1. 執行06步驟時,節點目錄下(7001/7002/…/7013/ 應當隻有 redis.conf 檔案)
  2. 一定要嚴格執行 01 步驟準備好環境。

    此步驟中 gem sources 預設位址好像無法通路,建議用下面方法替換

# gem sources -r https://rubygems.org
# gem sources -a http://rubygems.org