Redis總結(八)如何搭建高可用的Redis集羣

之前總結Redis 的一些基本的安裝和使用,你們能夠這這裏查看Redis 系列文章:https://www.cnblogs.com/zhangweizhong/category/771056.htmlhtml

今天補一下redis集羣功能吧。須要注意,Redis 3.0 之後纔有集羣的功能,下載Redis的時候注意下版本。 

node

1. Redis集羣原理

先看看redis-cluster架構圖:redis

 

架構細節:算法

(1)全部的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬。centos

(2)節點的fail是經過集羣中超過半數的節點檢測失效時才生效。ruby

(3)客戶端與redis節點直連,不須要中間proxy層,客戶端不須要鏈接集羣全部節點,鏈接集羣中任何一個可用節點便可。服務器

(4)redis-cluster把全部的物理節點映射到[0-16383]slot(哈希槽)上,cluster 負責維護node<->slot<->value。網絡

Redis 集羣中內置了 16384 個slot(哈希槽),當須要在 Redis 集羣中放置一個 key-value 時,redis 先對 key 使用 crc16 算法算出一個結果,而後把結果對 16384 求餘數,這樣每一個 key 都會對應一個編號在 0-16383 之間的哈希槽,redis 會根據節點數量大體均等的將哈希槽映射到不一樣的節點。架構

 

容錯機制: redis-cluster投票

 

 

(1)領着投票過程是集羣中全部master參與,若是半數以上master節點與master節點通訊超過(cluster-node-timeout),認爲當前master節點掛掉.app

(2):何時整個集羣不可用(cluster_state:fail)? 

    a:若是集羣任意master掛掉,且當前master沒有slave.集羣進入fail狀態,也能夠理解成集羣的slot映射[0-16383]不完成時進入fail狀態. 

    b:若是集羣超過半數以上master掛掉,不管是否有slave集羣進入fail狀態.

  注意:1. 當集羣不可用時,全部對集羣的操做作都不可用,收到((error) CLUSTERDOWN The cluster is down)錯誤。

     2. redis-3.0.0.rc1加入cluster-require-full-coverage參數,默認關閉,打開改配置,容許集羣兼容部分失敗。

 

2. 安裝Redis

redis 的單機安裝以前已經講過,網絡上也有不少教程,這裏就不重複了。

文章最後提供了Redis 3.0 的源碼,Redis集羣腳本等資源。你們能夠用我提供的版原本測試。

 

3. 安裝ruby環境

redis3.0 源碼中自帶的集羣管理工具redis-trib.rb依賴ruby環境,首先須要安裝ruby環境:

1. 安裝ruby環境

yum install ruby

yum install rubygems   

 

2. 安裝ruby和redis的接口程序

拷貝redis-3.0.0.gem至/usr/local下

執行:gem install /usr/local/redis-3.0.0.gem

 

4. 建立集羣

集羣結點規劃

通常Redis集羣的實例,都安裝在各個主從服務器上,這裏爲了演示方便,只是在同一臺服務器用不一樣的端口表示不一樣的redis服務器,以下:

主節點:172.16.0.17:7001,172.16.0.17:7002,172.16.0.17:7003

從節點:172.16.0.17:7004,172.16.0.17:7005,172.16.0.17:7006

1. 在/usr/local下建立redis-cluster目錄,其下建立Redis01到Redis06等6個redis實例,端口號爲:7001-7006,具體目錄以下:

 

 

2. 將redis源碼目錄src下的redis-trib.rb拷貝到redis-cluster目錄下。

 

3. 修改每一個redis實例的redis.conf配置文件:

port 7001  //這裏要改爲各個實例對應的端口,7001-7006
#bind 172.16.0.17
cluster-enabled yes

 

啓動每一個結點redis服務

分別進入Redis0一、Redis0二、...Redis06目錄,執行:

./redis-server ./redis.conf

 

查看redis進程:ps aux|grep redis

 

以上,Redis 的6個實例,就已經啓動了。

 

執行建立集羣命令

執行redis-trib.rb,此腳本是ruby腳本,它依賴ruby環境。

./redis-trib.rb create --replicas 1 172.16.0.17:7001 172.16.0.17:7002 172.16.0.17:7003 172.16.0.17:7004 172.16.0.17:7005  172.16.0.17:7006

說明:

redis集羣至少須要3個主節點,每一個主節點有一個從節點總共6個節點

replicas指定爲1表示每一個主節點有一個從節點

 

注意:

若是執行時報以下錯誤:

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

解決方法是刪除生成的配置文件nodes.conf,若是不行則說明如今建立的結點包括了舊集羣的結點信息,須要刪除redis的持久化文件後再重啓redis,好比:appendonly.aof、dump.rdb

 

建立集羣輸出以下:

>>> Creating cluster

Connecting to node 172.16.0.17:7001: OK

Connecting to node 172.16.0.17:7002: OK

Connecting to node 172.16.0.17:7003: OK

Connecting to node 172.16.0.17:7004: OK

Connecting to node 172.16.0.17:7005: OK

Connecting to node 172.16.0.17:7006: OK

>>> Performing hash slots allocation on 6 nodes...

Using 3 masters:

172.16.0.17:7001

172.16.0.17:7002

172.16.0.17:7003

Adding replica 172.16.0.17:7004 to 172.16.0.17:7001

Adding replica 172.16.0.17:7005 to 172.16.0.17:7002

Adding replica 172.16.0.17:7006 to 172.16.0.17:7003

M: cad9f7413ec6842c971dbcc2c48b4ca959eb5db4 172.16.0.17:7001

   slots:0-5460 (5461 slots) master

M: 4e7c2b02f0c4f4cfe306d6ad13e0cfee90bf5841 172.16.0.17:7002

   slots:5461-10922 (5462 slots) master

M: 1a8420896c3ff60b70c716e8480de8e50749ee65 172.16.0.17:7003

   slots:10923-16383 (5461 slots) master

S: 69d94b4963fd94f315fba2b9f12fae1278184fe8 172.16.0.17:7004

   replicates cad9f7413ec6842c971dbcc2c48b4ca959eb5db4

S: d2421a820cc23e17a01b597866fd0f750b698ac5 172.16.0.17:7005

   replicates 4e7c2b02f0c4f4cfe306d6ad13e0cfee90bf5841

S: 444e7bedbdfa40714ee55cd3086b8f0d5511fe54 172.16.0.17:7006

   replicates 1a8420896c3ff60b70c716e8480de8e50749ee65

Can I set the above configuration? (type 'yes' to accept): yes >>> Nodes configuration updated

>>> Assign a different config epoch to each node

>>> Sending CLUSTER MEET messages to join the cluster

Waiting for the cluster to join...

>>> Performing Cluster Check (using node 172.16.0.17:7001)

M: cad9f7413ec6842c971dbcc2c48b4ca959eb5db4 172.16.0.17:7001

   slots:0-5460 (5461 slots) master

M: 4e7c2b02f0c4f4cfe306d6ad13e0cfee90bf5841 172.16.0.17:7002

   slots:5461-10922 (5462 slots) master

M: 1a8420896c3ff60b70c716e8480de8e50749ee65 172.16.0.17:7003

   slots:10923-16383 (5461 slots) master

M: 69d94b4963fd94f315fba2b9f12fae1278184fe8 172.16.0.17:7004

   slots: (0 slots) master

   replicates cad9f7413ec6842c971dbcc2c48b4ca959eb5db4

M: d2421a820cc23e17a01b597866fd0f750b698ac5 172.16.0.17:7005

   slots: (0 slots) master

   replicates 4e7c2b02f0c4f4cfe306d6ad13e0cfee90bf5841

M: 444e7bedbdfa40714ee55cd3086b8f0d5511fe54 172.16.0.17:7006

   slots: (0 slots) master

   replicates 1a8420896c3ff60b70c716e8480de8e50749ee65

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

 

5. 查詢集羣信息

集羣建立成功登錄任意redis結點查詢集羣中的節點狀況。

客戶端以集羣方式登錄:

./redis-cli -c -h 172.16.0.17 -p 7001 -c //其中-c表示以集羣方式鏈接redis,-h指定ip地址,-p指定端口號

 

查詢集羣信息

cluster nodes 查詢集羣結點信息

 

cluster info 查詢集羣狀態信息

 

 

 

6. 添加主節點

集羣建立成功後能夠向集羣中添加節點,下面是添加一個master主節點

1. 增長Redis07實例,參考集羣結點規劃章節添加一個「7007」目錄做爲新節點。

 

2. 將Redis07實例添加到集羣中,執行下邊命令:

./redis-trib.rb add-node  172.16.0.17:7007 172.16.0.17:7001

 

3. 查看集羣結點發現7007已添加到集羣中:

[root@VM_0_17_centos redis-cluster]# ./redis-trib.rb add-node  172.16.0.17:7007 172.16.0.17:7001
>>> Adding node 172.16.0.17:7007 to cluster 172.16.0.17:7001
Connecting to node 172.16.0.17:7001: OK
.
.
.
Connecting to node
172.16.0.17:7003: OK Connecting to node 172.16.0.17:7005: OK Connecting to node 172.16.0.17:7002: OK Connecting to node 172.16.0.17:7006: OK Connecting to node 172.16.0.17:7004: OK >>> Performing Cluster Check (using node 172.16.0.17:7001) M: 977962f18ec51f363747961137dc903f0078b248 172.16.0.17:7001 slots:0-5460 (5461 slots) master 1 additional replica(s) M: defe4ce0421ee6b50bdab3da58754e98cc80fca3 172.16.0.17:7003 slots:10923-16383 (5461 slots) master 1 additional replica(s) S: a64fc273c0b90700397f5bac2b393dc5587d8ba8 172.16.0.17:7005 slots: (0 slots) slave replicates f277758189eba36c5b5732e9189d8554bf4385cb M: f277758189eba36c5b5732e9189d8554bf4385cb 172.16.0.17:7002 slots:5461-10922 (5462 slots) master 1 additional replica(s) S: 4f16e5adcc141ca284d4a9ec6d04f455aee84a48 172.16.0.17:7006 slots: (0 slots) slave replicates defe4ce0421ee6b50bdab3da58754e98cc80fca3 S: 479d5a077893184cd0b05a8e1b6cb5c0625215f4 172.16.0.17:7004 slots: (0 slots) slave replicates 977962f18ec51f363747961137dc903f0078b248 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. Connecting to node 172.16.0.17:7007: OK
.
.
.
>>> Send CLUSTER MEET to node 172.16.0.17:7007 to make it join the cluster. [OK] New node added correctly.

 

哈希槽從新分配

添加完主節點後,集羣並不會自動給新添加的節點分配哈希槽,須要咱們手動對主節點進行hash槽分配從新分配,這樣該主節才能夠存儲數據。

redis集羣有16384個槽,集羣中的每一個結點分配自已槽,經過查看集羣結點能夠看到槽佔用狀況。能夠看到剛纔添加的主節點Redis07,沒有分配哈希槽(slot)。

 

 

 下面就來講說如何給剛添加的Redis01結點分配槽:

第一步:鏈接上集羣

./redis-trib.rb reshard 172.16.0.17:7001   //(鏈接集羣中任意一個可用結點都行)

 

第二步:輸入要分配的槽數量

 

 

第三步:輸入接收槽的結點id

這裏準備給Redis07分配哈希槽,經過cluster nodes查看Redis07節點id爲:e8461f9743e186ae8f67ed301d2d971186b1cc93

輸入:e8461f9743e186ae8f67ed301d2d971186b1cc93,

 

第四步:輸入源結點id

 

若是隻是想從單個主節點獲取哈希槽,那直接輸入相應的節點id便可。

若是想從全部的主節點獲取輸入:all,

 

第五步:輸入yes開始移動槽到目標結點id

 

 

第六步:分配完成以後,能夠查詢集羣節點信息,查看哈希槽是否分配成功。

 

 

 

7. 添加從節點

集羣建立成功後能夠向集羣中添加節點,下面是添加一個slave從節點的命令。

./redis-trib.rb add-node --slave --master-id 主節點id 添加節點的ip和端口 集羣中已存在節點ip和端口

 

1. 添加Redis08實例爲從結點,將Redis08做爲Redis07的從結點。

執行以下命令:

./redis-trib.rb add-node --slave --master-id e8461f9743e186ae8f67ed301d2d971186b1cc93  172.16.0.17:7008 172.16.0.17:7001

e8461f9743e186ae8f67ed301d2d971186b1cc93  是Redis07實例的節點id,可經過cluster nodes查看。

 

注意:若是原來該結點在集羣中的配置信息已經生成集羣節點的配置文件(若是集羣配置cluster-config-file默認指定則爲nodes.conf),這時可能會報錯:

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

解決方法是:刪除生成的配置文件nodes.conf,刪除後再執行./redis-trib.rb add-node指令

 

2. 查看集羣中的結點,剛添加的Redis08已經成爲Redis07的從節點:

 

 

8. 刪除結點:

集羣建立成功後能夠向集羣中刪除其中的一個節點,應該怎麼刪除呢?

執行以下命令便可:

./redis-trib.rb del-node 172.16.0.17 :7005 e8461f9743e186ae8f67ed301d2d971186b1cc93

注意:刪除已經分配了有hash槽的節點會失敗,報錯以下:

[ERR] Node 172.16.0.17:7007 is not empty! Reshard data away and try again.

解決辦法就是:將該結點佔用的hash槽分配出去,請參考前面哈希槽從新分配的操做,這裏就不重複了。

 

最後

以上就已經將如何搭建redis的集羣講完了。

redis3.0源碼和ruby腳本,點擊這裏下載

相關文章
相關標籤/搜索