哨兵模式的缺陷
在哨兵模式中,仍然只有一個Master節點。當並發寫請求較大時,哨兵模式並不能緩解寫壓力。
我們知道只有主節點才具有寫能力,那如果在一個集群中,能夠配置多個主節點,是不是就可以緩解寫壓力了呢?
答:是的。這個就是redis-cluster集群模式。
Redis-cluster集群概念
(1)由多個Redis服務器組成的分布式網絡服務集群;
(2)集群之中有多個Master主節點,每一個主節點都可讀可寫;
(3)節點之間會互相通信,兩兩相連;
(4)Redis集群無中心節點。
|
集群節點復制
|
在Redis-Cluster集群中,可以給每一個主節點添加從節點,主節點和從節點直接遵循主從模型的特性。
當用戶需要處理更多讀請求的時候,添加從節點可以擴展系統的讀性能。
故障轉移
Redis集群的主節點內置了類似Redis Sentinel的節點故障檢測和自動故障轉移功能,當集群中的某個主節點下線時,集群中的其他在線主節點會注意到這一點,並對已下線的主節點進行故障轉移。
|
集群進行故障轉移的方法和Redis Sentinel進行故障轉移的方法基本一樣,不同的是,在集群里面,故障轉移是由集群中其他在線的主節點負責進行的,所以集群不必另外使用Redis Sentinel。
集群分片策略
Redis-cluster分片策略,是用來解決key存儲位置的。
集群將整個數據庫分為16384個槽位slot,所有key-value數據都存儲在這些slot中的某一個上。一個slot槽位可以存放多個數據,key的槽位計算公式為:slot_number=crc16(key)%16384,其中crc16為16位的循環冗余校驗和函數。
集群中的每個主節點都可以處理0個至16383個槽,當16384個槽都有某個節點在負責處理時,集群進入上線狀態,並開始處理客戶端發送的數據命令請求。
|
集群redirect轉向
由於Redis集群無中心節點,請求會隨機發給任意主節點;
主節點只會處理自己負責槽位的命令請求,其它槽位的命令請求,該主節點會返回客戶端一個轉向錯誤;
客戶端根據錯誤中包含的地址和端口重新向正確的負責的主節點發起命令請求。
|
集群搭建
准備工作
(1)安裝ruby環境
redis集群管理工具redis-trib.rb依賴ruby環境,首先需要安裝ruby環境:
| yum -y install ruby yum -y install rubygems |
(2)安裝ruby和redis的接口程序
拷貝redis-3.0.0.gem至/usr/local下,執行安裝:
| gem install /usr/local/redis-3.0.0.gem |
集群規划
(1)Redis集群最少需要6個節點,可以分布在一台或者多台主機上。
本教案在一台主機上創建偽分布式集群,不同的端口表示不同的redis節點,如下:
主節點:192.168.56.3:7001 192.168.56.3:7002 192.168.56.3:7003
從節點:192.168.56.3:7004 192.168.56.3:7005 192.168.56.3:7006
(2)在/usr/local/redis下創建redis-cluster目錄,其下創建7001、7002。。7006目錄,如下:
|
(3)將redis解壓路徑下的配置文件redis.conf,依次拷貝到每個700X目錄內,並修改每個700X目錄下的redis.conf配置文件:
| 必選配置: port 700X bind 192.168.23.3 cluster-enabled yes 建議配置: daemonized yes logfile /usr/local/redis/redis-cluster/700X/node.log |
啟動每個結點redis服務
依次以700X下的redis.conf,啟動redis節點。(必須指定redis.conf文件)
| redis-server /usr/local/redis/redis-cluster/700X/redis.conf |
執行創建集群命令
進入到redis源碼存放目錄redis/redis-4.10.3/src下,執行redis-trib.rb,此腳本是ruby腳本,它依賴ruby環境。
| ./redis-trib.rb create --replicas 1 192.168.159.10:7001 192.168.159.10:7002 192.168.159.10:7003 192.168.159.10:7004 192.168.159.10:7005 192.168.159.10:7006 |
創建過程如下:
|
查詢集群信息
集群創建成功登陸任意redis結點查詢集群中的節點情況。
./redis-cli -c -h 192.168.56.3 -p 7001
|
說明:./redis-cli -c -h 192.168.56.3 -p 7001 ,其中:
| -c表示以集群方式連接redis, -h指定ip地址, -p指定端口號
cluster nodes 查詢集群結點信息; cluster info 查詢集群狀態信。 |
集群管理
添加主節點
節點規划
集群創建成功后可以向集群中添加節點,下面是添加一個master主節點
添加7007節點,參考集群結點規划章節添加一個“7007”目錄作為新節點。
添加節點,執行下邊命令:
./redis-trib.rb add-node 192.168.23.3:7007 192.168.23.3:7001
|
查看集群結點發現7007已添加到集群中:
|
hash槽重新分配
添加完新的主節點后,需要對主節點進行hash槽分配,這樣該主節才可以存儲數據。
redis集群有16384個槽,被所有的主節點共同分配,通過查看集群結點可以看到槽占用情況。
|
給剛添加的7007結點分配槽:
第一步:連接上集群
| ./redis-trib.rb reshard 192.168.23.3:7001(連接集群中任意一個可用節點都行) |
第二步:輸入要分配的槽數量
|
輸入 500表示要分配500個槽
第三步:輸入接收槽的結點id
|
這里准備給7007分配槽,通過cluster nodes查看7007結點id為79bbb30bba66b4997b9360dd09849c67d2d02bb9
輸入:79bbb30bba66b4997b9360dd09849c67d2d02bb9
第四步:輸入源結點id
|
這里輸入all,表示從其它主節點中分配。
第五步:輸入yes開始移動槽到目標結點id
|
添加從節點
集群創建成功后可以向集群中添加節點,下面是添加一個slave從節點。
添加7008從結點,將7008作為7007的從結點。
新增從節點命令格式:
| ./redis-trib.rb add-node --slave --master-id masterID newNodIP:port MasterIP:port
masterID 主節點id,從cluster nodes信息中查看 newNodIP:port 新增節點的ip:端口 MasterIP:port 主節點的ip:端口 |
執行如下命令:
| ./redis-trib.rb add-node --slave --master-id 909c349f5f2d4db015101fb7c4e3c227a74ad382 192.168.4.253:7008 192.168.4.253:7007 |
79bbb30bba66b4997b9360dd09849c67d2d02bb9 是7007結點的id,可通過cluster nodes查看。
|
注意:
如果原來該結點在集群中的配置信息已經生成cluster-config-file指定的配置文件中(如果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指令。
查看集群中的結點,剛添加的7008為7007的從節點:
|
刪除節點:
刪除節點命令格式:
| ./redis-trib.rb del-node nodeIP:port nodeID nodeIP:port 待刪除節點的ip:端口 nodeID 待刪除節點的id,從cluster node中查看 |
注意,刪除已經占有hash槽的結點會失敗,報錯如下:
| [ERR] Node 127.0.0.1:7005 is not empty! Reshard data away and try again. |
需要將該結點占用的hash槽分配出去(參考hash槽重新分配章節)。
