之前總結Redis 的一些基本的安裝和使用,你們能夠這這裏查看Redis 系列文章:https://www.cnblogs.com/zhangweizhong/category/771056.html。html
今天補一下redis集羣功能吧。須要注意,Redis 3.0 之後纔有集羣的功能,下載Redis的時候注意下版本。
node
先看看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 會根據節點數量大體均等的將哈希槽映射到不一樣的節點。架構
(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參數,默認關閉,打開改配置,容許集羣兼容部分失敗。
redis 的單機安裝以前已經講過,網絡上也有不少教程,這裏就不重複了。
文章最後提供了Redis 3.0 的源碼,Redis集羣腳本等資源。你們能夠用我提供的版原本測試。
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
通常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
分別進入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.
集羣建立成功登錄任意redis結點查詢集羣中的節點狀況。
客戶端以集羣方式登錄:
./redis-cli -c -h 172.16.0.17 -p 7001 -c //其中-c表示以集羣方式鏈接redis,-h指定ip地址,-p指定端口號
查詢集羣信息
cluster nodes 查詢集羣結點信息
cluster info 查詢集羣狀態信息
集羣建立成功後能夠向集羣中添加節點,下面是添加一個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
第六步:分配完成以後,能夠查詢集羣節點信息,查看哈希槽是否分配成功。
集羣建立成功後能夠向集羣中添加節點,下面是添加一個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的從節點:
集羣建立成功後能夠向集羣中刪除其中的一個節點,應該怎麼刪除呢?
執行以下命令便可:
./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腳本,點擊這裏下載。