redis cluster集羣詳解

前面博客咱們已經學習到sentinel問題?爲何還要講cluster呢?
使用Redis Sentinel 模式架構的緩存體系,在使用的過程當中,隨着業務的增長不可避免的要對Redis進行擴容,熟知的擴容方式有兩種,一種是垂直擴容,一種是水平擴容。垂直擴容表示經過加內存方式來增長整個緩存體系的容量好比將緩存大小由2G調整到4G,這種擴容不須要應用程序支持;水平擴容表示表示經過增長節點的方式來增長整個緩存體系的容量好比原本有1個節點變成2個節點,這種擴容方式須要應用程序支持。垂直擴容看似最便捷的擴容,可是受到機器的限制,一個機器的內存是有限的,因此垂直擴容到必定階段不可避免的要進行水平擴容,若是預留出不少節點感受又是對資源的一種浪費由於對業務的發展趨勢很快預測。Redis Sentinel 水平擴容一直都是程序猿心中的痛點,由於水平擴容牽涉到數據的遷移。遷移過程一方面要保證本身的業務是可用的,一方面要保證儘可能不丟失數據因此數據能不遷移就儘可能不遷移。針對這個問題,Redis Cluster就應運而生了,下面簡單介紹一下RedisCluster。
Redis Cluster是Redis的分佈式解決方案,在Redis 3.0版本正式推出的,有效解決了Redis分佈式方面的需求。當遇到單機內存、併發、流量等瓶頸時,能夠採用Cluster架構達到負載均衡的目的。分佈式集羣首要解決把整個數據集按照分區規則映射到多個節點的問題,即把數據集劃分到多個節點上,每一個節點負責整個數據的一個子集。Redis Cluster採用哈希分區規則中的虛擬槽分區。虛擬槽分區巧妙地使用了哈希空間,使用分散度良好的哈希函數把全部的數據映射到一個固定範圍內的整數集合,整數定義爲槽(slot)。Redis Cluster槽的範圍是0 ~ 16383。槽是集羣內數據管理和遷移的基本單位。採用大範圍的槽的主要目的是爲了方便數據的拆分和集羣的擴展,每一個節點負責必定數量的槽。Redis Cluster採用虛擬槽分區,全部的鍵根據哈希函數映射到0 ~ 16383,計算公式:slot = CRC16(key)&16383。每個實節點負責維護一部分槽以及槽所映射的鍵值數據。
 

Redis集羣

 
 
高性能:
 
基於KEY進行數據拆分
 
一、在多分片節點中,將16384個槽位,均勻分佈到多個分片節點中
二、存數據時,將key作crc16(key),而後和16384進行取模,得出槽位值(0-16383之間)
三、根據計算得出的槽位值,找到相對應的分片節點的主節點,存儲到相應槽位上
四、若是客戶端當時鏈接的節點不是未來要存儲的分片節點,分片集羣會將客戶端鏈接切換至真正存儲節點進行數據存儲
 
高可用:
在搭建集羣時,會爲每個分片的主節點,對應一個從節點,實現slaveof的功能,同時當主節點down,實現相似於sentinel的自動failover的功能。
 
Redis 集羣是一個能夠在多個 Redis 節點之間進行數據共享的設施(installation)。
Redis 集羣不支持那些須要同時處理多個鍵的 Redis 命令, 由於執行這些命令須要在多個 Redis 節點之間移動數據, 而且在高負載的狀況下, 這些命令將下降 Redis 集羣的性能, 並致使不可預測的行爲。
Redis 集羣經過分區(partition)來提供必定程度的可用性(availability): 即便集羣中有一部分節點失效或者沒法進行通信, 集羣也能夠繼續處理命令請求。
將數據自動切分(split)到多個節點的能力。
當集羣中的一部分節點失效或者沒法進行通信時, 仍然能夠繼續處理命令請求的能力。
 

Redis集羣數據共享

Redis 集羣使用數據分片(sharding)而非一致性哈希(consistency hashing)來實現: 一個 Redis 集羣包含 16384 個哈希槽(hash slot), 數據庫中的每一個鍵都屬於這 16384 個哈希槽的其中一個, 集羣使用公式 CRC16(key) % 16384 來計算鍵 key 屬於哪一個槽, 其中 CRC16(key) 語句用於計算鍵 key 的 CRC16 校驗和 。
節點 A 負責處理 0 號至 5500 號哈希槽。
節點 B 負責處理 5501 號至 11000 號哈希槽。
節點 C 負責處理 11001 號至 16384 號哈希槽。
 

槽的計算公式

集羣使用公式 CRC16(key) & 16383 計算鍵 key屬於哪一個槽。

 

 

運行機制

全部的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬.
節點的fail是經過集羣中超過半數的master節點檢測失效時才生效.
客戶端與redis節點直連,不須要中間proxy層.客戶端不須要鏈接集羣全部節點,鏈接集羣中任何一個可用節點便可
把全部的物理節點映射到[0-16383]slot上,cluster 負責維護node<->slot<->key
 

集羣複製

 
爲了使得集羣在一部分節點下線或者沒法與集羣的大多數(majority)節點進行通信的狀況下, 仍然能夠正常運做, Redis 集羣對節點使用了主從複製功能: 集羣中的每一個節點都有 1 個至 N 個複製品(replica), 其中一個複製品爲主節點(master), 而其他的 N-1 個複製品爲從節點(slave)。
  在以前列舉的節點 A 、B 、C 的例子中, 若是節點 B 下線了, 那麼集羣將沒法正常運行, 由於集羣找不到節點來處理 5501 號至 11000 號的哈希槽。
  假如在建立集羣的時候(或者至少在節點 B 下線以前), 咱們爲主節點 B 添加了從節點 B1 , 那麼當主節點 B 下線的時候, 集羣就會將 B1 設置爲新的主節點, 並讓它代替下線的主節點 B , 繼續處理 5501 號至 11000 號的哈希槽, 這樣集羣就不會由於主節點 B 的下線而沒法正常運做了。
  不過若是節點 B 和 B1 都下線的話, Redis 集羣仍是會中止運做。
  集羣的複製特性重用了 SLAVEOF 命令的代碼,因此集羣節點的複製行爲和 SLAVEOF 命令的複製行爲徹底相同。
 
 

集羣的故障轉移

 
•在集羣裏面,節點會對其餘節點進行下線檢測。
•當一個主節點下線時,集羣裏面的其餘主節點負責對下線主節點進行故障移。
•換句話說,集羣的節點集成了下線檢測和故障轉移等相似 Sentinel 的功能。
•由於 Sentinel 是一個獨立運行的監控程序,而集羣的下線檢測和故障轉移等功能是集成在節點裏面的,它們的運行模式很是地不一樣,因此儘管這二者的功能很類似,但集羣的實現沒有重用 Sentinel 的代碼。
 
 

在集羣裏面執行命令的兩種狀況

 
•命令發送到了正確的節點:命令要處理的鍵所在的槽正好是由接收命令的節點負責,那麼該節點執行命令,就像單機 Redis 服務器同樣。
•命令發送到了錯誤的節點:接收到命令的節點並不是處理鍵所在槽的節點,那麼節點將向客戶端返回一個轉向(redirection)錯誤,告知客戶端應該到哪一個節點去執行這個命令,客戶端會根據錯誤提示的信息,從新向正確的節點發送命令。
 

命令發送給正確的節點

鍵 date 位於 2022 槽,該槽由節點 7000 負責,命令會直接執行。

 

命令發送給了錯誤的節點

鍵 date 位於 2022 槽,該槽由節點 7000 負責,但錯誤發送到了7001節點

 

轉向錯誤的實現(1)

集羣中的節點會互相告知對方,本身負責處理哪些槽。
 

轉向錯誤的實現(2)

集羣中的每一個節點都會記錄 16384 個槽分別由哪一個節點負責,從而造成一個「槽表」(slot table)。
節點在接收到命令請求時,會經過槽表檢查鍵所在的槽是否由本節點處理:
- 若是是的話,那麼節點直接執行命令;
- 若是不是的話,那麼節點就從槽表裏面提取出正確節點的地址信息,而後返回轉向錯誤。
 

redis cluster集羣的搭建

規劃、搭建過程:
 
6個redis實例,通常會放到3臺硬件服務器
注:在企業規劃中,一個分片的兩個節點,分到不一樣的物理機,防止硬件主機宕機形成的整個分片數據丟失。

主機名
ip
操做系統
redis版本
實例規劃
docker-01
10.0.0.130
centos7.4
5.05穩定版
/data/7000 master
/data/7001 slave
docker-02
10.0.0.131
centos7.4
5.05穩定版
/data/7002 master
/data/7003 slave
docker-03
10.0.0.132
centos7.4
5.05穩定版
/data/7004 master
/data/7005 slave
注意: 每臺服務器上的兩個實例不能互爲主從,不然若是服務器掛掉就會致使集羣中一個節點數據的丟失,應該讓每臺服務器他們彼此互爲主從,這裏咱們規劃以下
docker-01 7000 master ---> docker-02 7003 slave
docker-02 7002 master ---> docker-03 7005 slave
docker-03 7004 master ---> docker-01 7001 slave

 

1. 安裝集羣插件(redis5不用安裝插件)

EPEL源安裝ruby支持
yum install ruby rubygems -y
使用國內源
gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/
gem install redis -v 3.3.3
gem sources -l
若是沒法使用,可使用aliyun
gem sources -a http://mirrors.aliyun.com/rubygems/
gem sources  --remove http://rubygems.org/
 
注意對於新版redis5 (已經出穩定版了)中已經把這個插件嵌入到了redis-cli中了,無需咱們安裝這個插件。下面爲官方的說明:
若是您使用的是Redis 5,這很容易實現,由於嵌入到中的Redis Cluster命令行實用程序redis-cli將爲咱們提供幫助,該實用程序可用於建立新集羣,檢查或從新分片現有集羣等。

 

2. 集羣節點的準備

 
在每個服務器節點安裝規劃建立好目錄
mkdir /data/700{0..5}
 
vim /data/7000/redis.conf
port 7000
daemonize yes
pidfile /data/7000/redis.pid
loglevel notice
logfile "/data/7000/redis.log"
dbfilename dump.rdb
dir /data/7000
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

  

vim /data/7001/redis.conf
port 7001
daemonize yes
pidfile /data/7001/redis.pid
loglevel notice
logfile "/data/7001/redis.log"
dbfilename dump.rdb
dir /data/7001
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

 

vim /data/7002/redis.conf
port 7002
daemonize yes
pidfile /data/7002/redis.pid
loglevel notice
logfile "/data/7002/redis.log"
dbfilename dump.rdb
dir /data/7002
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

  

vim /data/7003/redis.conf
port 7003
daemonize yes
pidfile /data/7003/redis.pid
loglevel notice
logfile "/data/7003/redis.log"
dbfilename dump.rdb
dir /data/7003
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

  

vim /data/7004/redis.conf
port 7004
daemonize yes
pidfile /data/7004/redis.pid
loglevel notice
logfile "/data/7004/redis.log"
dbfilename dump.rdb
dir /data/7004
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

  

vim /data/7005/redis.conf
port 7005
daemonize yes
pidfile /data/7005/redis.pid
loglevel notice
logfile "/data/7005/redis.log"
dbfilename dump.rdb
dir /data/7005
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
 
Redis 集羣由多個運行在集羣模式(cluster mode)下的 Redis 實例組成, 實例的集羣模式須要經過配置來開啓, 開啓集羣模式的實例將可使用集羣特有的功能和命令。
如下是一個包含了最少選項的集羣配置文件示例:
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

  

3. 啓動節點並驗證

redis-server /data/7000/redis.conf 
redis-server /data/7001/redis.conf 
redis-server /data/7002/redis.conf 
redis-server /data/7003/redis.conf 
redis-server /data/7004/redis.conf 
redis-server /data/7005/redis.conf 

[root@docker-01 ~]# ps -ef|grep -v grep |grep redis
root      74891      1  0 07:15 ?        00:00:01 redis-server *:7000 [cluster]
root      75699      1  0 07:16 ?        00:00:00 redis-server *:7001 [cluster]

[root@docker-02 ~]# ps -ef|grep -v grep |grep redis
root       6411      1  0 07:17 ?        00:00:00 redis-server *:7002 [cluster]
root       6416      1  0 07:17 ?        00:00:00 redis-server *:7003 [cluster]

[root@docker-03 ~]# ps -ef|grep -v grep |grep redis
root      17074      1  0 07:17 ?        00:00:00 redis-server *:7004 [cluster]
root      17079      1  0 07:18 ?        00:00:00 redis-server *:7005 [cluster]

  

4. 建立集羣(將節點加入集羣)

redis-cli --cluster create --cluster-replicas 1 10.0.0.130:7000 10.0.0.131:7002 10.0.0.132:7004 10.0.0.131:7003 10.0.0.132:7005 10.0.0.130:7001
給定 redis-cli 程序的命令是 create , 這表示咱們但願建立一個新的集羣。
選項 --replicas 1 表示咱們但願爲集羣中的每一個主節點建立一個從節點。
建立時會自動把前面三個節點做爲主節點,後面三個做爲從節點, 主節點和從節點一一對應
 
redis3建集羣的命令(reidis5已經把這個插件集成到了redis-cli中了)
{redis_src_home}/src/redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
 
 
主從對應恰好跟咱們預想的同樣,後面問是否要設置成上面的配置? 這裏輸入yes
集羣建立成功了
 

5. 集羣節點狀態查看

 
集羣主節點狀態
redis-cli -p 7000 cluster nodes | grep master
集羣從節點狀態
redis-cli -p 7000 cluster nodes | grep slave
 
 
總共有三對:master和slave一一對應,符合預期.
 
也能夠這樣查看
[root@docker-01 ~]# redis-cli -p 7000 info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.131,port=7003,state=online,offset=1540,lag=1
....
 
 

集羣客戶端

redis-cli -c -p 7000
set foo bar
get foo
 
#注意: 客戶端進行操做的時候最好要加-c, 確保是集羣模式,不然有時沒法進行操做.由於就是由於-c參數能夠保證在操做的客戶端若是沒有要找的node的話,會自動轉發過去,從而獲取到想要的結果,
 
從新分片
./redis-trib.rb reshard 127.0.0.1:7000
 
 

集羣管理

 

集羣主節點狀態
redis-cli -p 7000 cluster nodes | grep master
集羣從節點狀態
redis-cli -p 7000 cluster nodes | grep slave
 
增長新的節點
./redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000
 
刪除一個節點
redis-trib  del-node  ip:port  '<node-id>' 
刪除master節點以前首先要使用reshard移除master的所有slot,而後再刪除當前節點
 
添加一個從節點
./redis-trib.rb add-node  --slave  --master-id  $[nodeid] 127.0.0.1:7008 127.0.0.1:7000  
 
 

增長節點

一個新的節點須要至少一個從節點,這裏咱們在docker-01上添加
 

1. 準備工做

mkdir /data/7006
mkdir /data/7007
 
 
vim /data/7006/redis.conf
port 7006
daemonize yes
pidfile /data/7006/redis.pid
loglevel notice
logfile "/data/7006/redis.log"
dbfilename dump.rdb
dir /data/7006
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf # 添加好集羣以後會保存集羣的信息
cluster-node-timeout 5000
appendonly yes

  

vim /data/7007/redis.conf
port 7007
daemonize yes
pidfile /data/7007/redis.pid
loglevel notice
logfile "/data/7007/redis.log"
dbfilename dump.rdb
dir /data/7007
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

  

redis-server /data/7006/redis.conf
redis-server /data/7007/redis.conf
 

2.  添加主節點

 
redis-cli --cluster add-node 10.0.0.130:7006 10.0.0.130:7000
add-node命令將新節點的地址指定爲第一個參數,並將集羣中隨機存在的節點(已經存在主從節點均可以)的地址指定爲第二個參數
 
驗證新節點是否已經加入集羣
[root@docker-01 7006]# redis-cli -c -p 7000 cluster nodes | egrep 7006
623aaa030690211b641c08f6623f5b4468bf03b0 10.0.0.130:7006@17006 master - 0 1569460664357 0 connected
 
已經成功添加到新的集羣當中了.
 
請注意,因爲此節點已經鏈接到集羣,所以它已經可以正確重定向客戶端查詢,而且一般來講是集羣的一部分。可是,與其餘master相比,它有兩個特色:
  • 因爲沒有分配的哈希槽,所以不保存任何數據。
  • 由於它是沒有分配插槽的主機,因此當從機要成爲主機時,它不會參與選舉過程。
因此咱們須要爲新添加的節點分配槽位(從新分片), 新節點才能被使用.
 
redis5 以前的版本添加方式
redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000
 

3. 轉移slot(從新分片)

redis-cli --cluster reshard 10.0.0.130:7006 # 會進行交互式

>>> Performing Cluster Check (using node 10.0.0.130:7006)
M: 623aaa030690211b641c08f6623f5b4468bf03b0 10.0.0.130:7006
   slots: (0 slots) master
S: 8afb9a41f361e087cea56d3912b180db043fa6f7 10.0.0.132:7005
   slots: (0 slots) slave
   replicates b537e21aa9db60d2935f47bbd88a9ebd62168b16
S: c7f34873785eeddda818a4d1adce775cc3d01b1c 10.0.0.131:7003
   slots: (0 slots) slave
   replicates a59225315c983972554cd34e63336adad78001d6
M: b537e21aa9db60d2935f47bbd88a9ebd62168b16 10.0.0.131:7002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: b5ed868eebf22825fd06888c7ebb426caab2a368 10.0.0.130:7001
   slots: (0 slots) slave
   replicates a9b353fe6e31b6cea4005215648f2c4ab6731f10
M: a9b353fe6e31b6cea4005215648f2c4ab6731f10 10.0.0.132:7004
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: a59225315c983972554cd34e63336adad78001d6 10.0.0.130:7000
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 4096

問你要爲新節點分配多少個槽位?有如今有一個有4個節點了16384/4=4096, 因此這裏咱們填4096javascript

What is the receiving node ID? 623aaa030690211b641c08f6623f5b4468bf03b0
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

問要接受分片的node的id, 新加節點7006: 623aaa030690211b641c08f6623f5b4468bf03b0java

問從哪一個節點做爲源分配槽位ID,這裏選擇: all, 即從已經存在全部的節點進行分配.
Do you want to proceed with the proposed reshard plan (yes/no)?

問是否從這些節點進行分配, 輸入 yesnode

 

4. 驗證主節點是否添加成功redis

可見新的redis 7006 已經從原有的三個節點平均分配了槽位累計恰好4096個docker

 

redis5 以前的版本從新分片

redis-trib.rb reshard 127.0.0.1:7000 數據庫

 

5. 添加從節點vim

redis-cli --cluster add-node --cluster-slave --cluster-master-id 623aaa030690211b641c08f6623f5b4468bf03b0 10.0.0.130:7007 10.0.0.130:7006
參數說明:
--cluster-master-Id 指定要把從節點添加給哪一個redis主節點的id
10.0.0.130:7007 要添加的從節點
10.0.0.130:7006 已經存在主節點7006

驗證:centos

[root@docker-01 ~]# redis-cli -c -p 7000 cluster nodes |egrep '700[67]'
623aaa030690211b641c08f6623f5b4468bf03b0 10.0.0.130:7006@17006 master - 0 1569462389467 7 connected 0-1364 5461-6826 10923-12287
4ca37b1856b63ace09632a79b6788cccc47963ab 10.0.0.130:7007@17007 slave 623aaa030690211b641c08f6623f5b4468bf03b0 0 1569462387951 7 connected

  

已經成功把7007從節點,添加到集羣中7006的主節點上了

注意:若是在生產環境,建議新添加的主從節點必定不要放在同一臺服務器上面. 防止該服務器掛掉, 整個節點數據丟失的問題.
 
 
redis5以前版本添加從節點寫法:
redis-trib.rb add-node --slave --master-id bff7d6e603578033f53865de3e55fb2b8c526b60 127.0.0.1:7007 127.0.0.1:7000

 

刪除節點

redis-cli --cluster reshard 10.0.0.130:7006
 
redis5以前的版本寫法:
redis-trib.rb reshard 127.0.0.1:7000
 
 
刪除一個節點
 
主節點刪除:
刪除master節點以前首先要使用reshard移除master的所有slot,而後再刪除當前節點
 
(1) 從新分片
 
這裏咱們要把源redis 7006節點上面的4096個槽位,分配到redis 7000上面
因此接受slot的node ID寫上redis 7000的ID
下面會讓你輸入你要從把那個節點的slot從新分? 這裏固然是redis 7006的ID
done表明已經輸入完
 
下一行是讓你確認是否要分片,輸入yes
 
驗證分片:
[root@docker-01 ~]# redis-cli -c -p 7000 cluster nodes
623aaa030690211b641c08f6623f5b4468bf03b0 10.0.0.130:7006@17006 master - 0 1569465429000 7 connected
c7f34873785eeddda818a4d1adce775cc3d01b1c 10.0.0.131:7003@17003 slave a59225315c983972554cd34e63336adad78001d6 0 1569465429000 8 connected
a9b353fe6e31b6cea4005215648f2c4ab6731f10 10.0.0.132:7004@17004 master - 0 1569465428000 3 connected 12288-16383
8afb9a41f361e087cea56d3912b180db043fa6f7 10.0.0.132:7005@17005 slave b537e21aa9db60d2935f47bbd88a9ebd62168b16 0 1569465429548 5 connected
a59225315c983972554cd34e63336adad78001d6 10.0.0.130:7000@17000 myself,master - 0 1569465429000 8 connected 0-6826 10923-12287
b537e21aa9db60d2935f47bbd88a9ebd62168b16 10.0.0.131:7002@17002 master - 0 1569465428000 2 connected 6827-10922
b5ed868eebf22825fd06888c7ebb426caab2a368 10.0.0.130:7001@17001 slave a9b353fe6e31b6cea4005215648f2c4ab6731f10 0 1569465429953 6 connected
4ca37b1856b63ace09632a79b6788cccc47963ab 10.0.0.130:7007@17007 slave a59225315c983972554cd34e63336adad78001d6 0 1569465428000 8 connected
[root@docker-01 ~]# 
[root@docker-01 ~]# 
[root@docker-01 ~]# 
[root@docker-01 ~]# redis-cli -c -p 7007 info replication
# Replication
role:slave
master_host:10.0.0.130
master_port:7000
master_link_status:up
....

我經過集羣狀態能夠看出redis 7006已經沒有slot了. 以前的集羣從節點 redis 7007已經指定到 集羣節點redis 7000上面了,由於咱們把原來redis 7006全部的slot所有遷移到了redis 7000上面了.緩存

 

(2). 開始刪除主節點
redis-cli --cluster del-node 10.0.0.130:7006 623aaa030690211b641c08f6623f5b4468bf03b0
 
redis5 以前版本的寫法
redis-trib.rb del-node 127.0.0.1:7006 bff7d6e603578033f53865de3e55fb2b8c526b6
 
驗證: redis-cli -c -p 7000 cluster nodes
 
 

從節點刪除:
redis-cli --cluster del-node 10.0.0.130:7007 4ca37b1856b63ace09632a79b6788cccc47963ab
 
redis5 以前版本的寫法
redis-trib.rb del-node 127.0.0.1:7007 2af3da4252ad1a7334d476e1b56498b85a1b488c
 
驗證: redis-cli -c -p 7000 cluster nodes

 

redis集羣故障切換測試

接着上面

[root@docker-01 ~]# redis-cli -c -p 7000 cluster nodes
c7f34873785eeddda818a4d1adce775cc3d01b1c 10.0.0.131:7003@17003 slave a59225315c983972554cd34e63336adad78001d6 0 1569466576000 8 connected
a9b353fe6e31b6cea4005215648f2c4ab6731f10 10.0.0.132:7004@17004 master - 0 1569466577000 3 connected 12288-16383
8afb9a41f361e087cea56d3912b180db043fa6f7 10.0.0.132:7005@17005 slave b537e21aa9db60d2935f47bbd88a9ebd62168b16 0 1569466577000 5 connected
a59225315c983972554cd34e63336adad78001d6 10.0.0.130:7000@17000 myself,master - 0 1569466576000 8 connected 0-6826 10923-12287
b537e21aa9db60d2935f47bbd88a9ebd62168b16 10.0.0.131:7002@17002 master - 0 1569466577730 2 connected 6827-10922
b5ed868eebf22825fd06888c7ebb426caab2a368 10.0.0.130:7001@17001 slave a9b353fe6e31b6cea4005215648f2c4ab6731f10 0 1569466577529 6 connected

  

關閉主庫測試

 
我把reids 7000 殺死
[root@docker-01 ~]# ps -ef|grep redis
root      74891      1  0 07:15 ?        00:01:32 redis-server *:7000 [cluster]
root      75699      1  0 07:16 ?        00:01:27 redis-server *:7001 [cluster]
root      82424  46420  0 10:56 pts/0    00:00:00 grep --color=auto redis
[root@docker-01 ~]# kill 74891
[root@docker-01 ~]# ps -ef|grep redis
root      75699      1  0 07:16 ?        00:01:27 redis-server *:7001 [cluster]
root      82842  46420  0 10:57 pts/0    00:00:00 grep --color=auto redis

  

我在docker03上(也能夠在docker02)查看下日誌
[root@docker-03 ~]# tail -f /data/700*/redis.log
==> /data/7004/redis.log <==
17074:M 26 Sep 2019 07:48:50.222 * Background saving started by pid 17098
17098:C 26 Sep 2019 07:48:50.264 * DB saved on disk
17098:C 26 Sep 2019 07:48:50.265 * RDB: 2 MB of memory used by copy-on-write
17074:M 26 Sep 2019 07:48:50.272 * Background saving terminated with success
17074:M 26 Sep 2019 07:48:50.272 # Cluster state changed: ok
17074:M 26 Sep 2019 07:48:50.272 * Synchronization with replica 10.0.0.130:7001 succeeded
17074:M 26 Sep 2019 10:57:23.966 * Marking node a59225315c983972554cd34e63336adad78001d6 as failing (quorum reached).
17074:M 26 Sep 2019 10:57:23.966 # Cluster state changed: fail
17074:M 26 Sep 2019 10:57:24.205 # Failover auth granted to c7f34873785eeddda818a4d1adce775cc3d01b1c for epoch 9
17074:M 26 Sep 2019 10:57:24.213 # Cluster state changed: ok

==> /data/7005/redis.log <==
17099:C 26 Sep 2019 07:48:50.437 * Parent agreed to stop sending diffs. Finalizing AOF...
17099:C 26 Sep 2019 07:48:50.437 * Concatenating 0.00 MB of AOF diff received from parent.
17099:C 26 Sep 2019 07:48:50.437 * SYNC append only file rewrite performed
17099:C 26 Sep 2019 07:48:50.437 * AOF rewrite: 4 MB of memory used by copy-on-write
17079:S 26 Sep 2019 07:48:50.524 * Background AOF rewrite terminated with success
17079:S 26 Sep 2019 07:48:50.524 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB)
17079:S 26 Sep 2019 07:48:50.524 * Background AOF rewrite finished successfully
17079:S 26 Sep 2019 10:57:23.966 * FAIL message received from b537e21aa9db60d2935f47bbd88a9ebd62168b16 about a59225315c983972554cd34e63336adad78001d6
17079:S 26 Sep 2019 10:57:23.966 # Cluster state changed: fail
17079:S 26 Sep 2019 10:57:24.213 # Cluster state changed: ok

  

經過日誌能夠看出, redis cluster已經把這個節點的主的權限交給了c7f34873785eeddda818a4d1adce775cc3d01b1c, 而這個ID是10.0.0.131 redis 7003, 恰好爲 redis 7000的從庫的ID
 
查看集羣狀態
[root@docker-02 ~]# redis-cli -c -p 7002 cluster nodes
b5ed868eebf22825fd06888c7ebb426caab2a368 10.0.0.130:7001@17001 slave a9b353fe6e31b6cea4005215648f2c4ab6731f10 0 1569467232651 6 connected
8afb9a41f361e087cea56d3912b180db043fa6f7 10.0.0.132:7005@17005 slave b537e21aa9db60d2935f47bbd88a9ebd62168b16 0 1569467232551 5 connected
a59225315c983972554cd34e63336adad78001d6 10.0.0.130:7000@17000 master,fail - 1569466638301 1569466637597 8 disconnected
b537e21aa9db60d2935f47bbd88a9ebd62168b16 10.0.0.131:7002@17002 myself,master - 0 1569467231000 2 connected 6827-10922
a9b353fe6e31b6cea4005215648f2c4ab6731f10 10.0.0.132:7004@17004 master - 0 1569467233663 3 connected 12288-16383
c7f34873785eeddda818a4d1adce775cc3d01b1c 10.0.0.131:7003@17003 master - 0 1569467232000 9 connected 0-6826 10923-12287

此時源docker01的redis 7000的從庫 docker-02 redis 7003已經提高爲了主庫ruby

 

從新啓動主庫測試

redis-server /data/7000/redis.conf
 
查看集羣狀態
[root@docker-02 ~]# redis-cli -c -p 7002 cluster nodes
b5ed868eebf22825fd06888c7ebb426caab2a368 10.0.0.130:7001@17001 slave a9b353fe6e31b6cea4005215648f2c4ab6731f10 0 1569467495195 6 connected
8afb9a41f361e087cea56d3912b180db043fa6f7 10.0.0.132:7005@17005 slave b537e21aa9db60d2935f47bbd88a9ebd62168b16 0 1569467496503 5 connected
a59225315c983972554cd34e63336adad78001d6 10.0.0.130:7000@17000 slave c7f34873785eeddda818a4d1adce775cc3d01b1c 0 1569467495000 9 connected
b537e21aa9db60d2935f47bbd88a9ebd62168b16 10.0.0.131:7002@17002 myself,master - 0 1569467494000 2 connected 6827-10922
a9b353fe6e31b6cea4005215648f2c4ab6731f10 10.0.0.132:7004@17004 master - 0 1569467496201 3 connected 12288-16383
c7f34873785eeddda818a4d1adce775cc3d01b1c 10.0.0.131:7003@17003 master - 0 1569467495000 9 connected 0-6826 10923-12287

  

經過集羣狀態能夠看出從新啓動的原redis主庫, 已經變爲從庫.
 
也就是說當在redis cluster中,若是一個主庫redis實例宕掉的話, 那麼的它的從庫將被提高爲主庫. 當主庫再次上線時,它將成爲原來從庫(如今是主庫)的從庫.

 

 

相關文章
相關標籤/搜索