centos6下redis cluster集羣部署過程

 

通常來講,redis主從和mysql主從目的差很少,但redis主從配置很簡單,主要在從節點配置文件指定主節點ip和端口,好比:slaveof 192.168.10.10 6379,而後啓動主從,主從就搭建好了。redis主從中若是主節點發生故障,不會自動切換,須要藉助redis的Sentinel(哨兵模式)或者keepalive來實現主的故障轉移。node

今天介紹下redis cluster集羣模式:
redis集羣是一個無中心的分佈式redis存儲架構,能夠在多個節點之間進行數據共享,解決了redis高可用、可擴展等問題,redis集羣提供瞭如下兩個好處:
1)將數據自動切分(split)到多個節點
2)當集羣中的某一個節點故障時,redis還能夠繼續處理客戶端的請求。mysql

一個 Redis 集羣包含 16384 個哈希槽(hash slot),數據庫中的每一個數據都屬於這16384個哈希槽中的一個。集羣使用公式 CRC16(key) % 16384 來計算鍵 key 屬於哪一個槽。集羣中的每個節點負責處理一部分哈希槽。
集羣中的主從複製
集羣中的每一個節點都有1個至N個複製品,其中一個爲主節點,其他的爲從節點,若是主節點下線了,集羣就會把這個主節點的一個從節點設置爲新的主節點,繼續工做。這樣集羣就不會由於一個主節點的下線而沒法正常工做。linux

==========從Redis3.x開始已經支持Load Balance功能了===========c++

Redis Cluster集羣功能推出已經有一段時間了。在單機版的Redis中,每一個Master之間是沒有任何通訊的,因此通常在Jedis客戶端或者Codis這樣的代理中作Pre-sharding。按照CAP理論來講,單機版的Redis屬於保證CP(Consistency & Partition-Tolerancy)而犧牲A(Availability),也就說Redis可以保證全部用戶看到相同的數據(一致性,由於Redis不自動冗餘數據)和網絡通訊出問題時,暫時隔離開的子系統能繼續運行(分區容忍性,由於Master之間沒有直接關係,不須要通訊),可是不保證某些結點故障時,全部請求都能被響應(可用性,某個Master結點掛了的話,那麼它上面分片的數據就沒法訪問了)。git

有了Cluster功能後,Redis從一個單純的NoSQL內存數據庫變成了分佈式NoSQL數據庫,CAP模型也從CP變成了AP。也就是說,經過自動分片和冗餘數據,Redis具備了真正的分佈式能力,某個結點掛了的話,由於數據在其餘結點上有備份,因此其餘結點頂上來就能夠繼續提供服務,保證了Availability。然而,也正由於這一點,Redis沒法保證曾經的強一致性了。這也是CAP理論要求的,三者只能取其二。redis

Redis Cluster 是Redis的集羣實現,內置數據自動分片機制,集羣內部將全部的key映射到16384個Slot中,集羣中的每一個Redis Instance負責其中的一部分的Slot的讀寫。集羣客戶端鏈接集羣中任一Redis Instance便可發送命令,當Redis Instance收到本身不負責的Slot的請求時,會將負責請求Key所在Slot的Redis Instance地址返回給客戶端,客戶端收到後自動將原請求從新發往這個地址,對外部透明。一個Key到底屬於哪一個Slot由crc16(key) % 16384 決定。在Redis Cluster裏對於負載均衡和HA相關都已經支持的至關完善了。算法

負載均衡(Load Balance):集羣的Redis Instance之間能夠遷移數據,以Slot爲單位,但不是自動的,須要外部命令觸發。
集羣成員管理:集羣的節點(Redis Instance)和節點之間兩兩按期交換集羣內節點信息而且更新,從發送節點的角度看,這些信息包括:集羣內有哪些節點,IP和PORT是什麼,節點名字是什麼,節點的狀態(好比OK,PFAIL,FAIL,後面詳述)是什麼,包括節點角色(master 或者 slave)等。
關於可用性,集羣由N組主從Redis Instance組成。spring

主能夠沒有從,可是沒有從 意味着主宕機後主負責的Slot讀寫服務不可用。sql

一個主能夠有多個從,主宕機時,某個從會被提高爲主,具體哪一個從被提高爲主,協議相似於Raft,參見這裏。如何檢測主宕機?Redis Cluster採用quorum+心跳的機制。從節點的角度看,節點會按期給其餘全部的節點發送Ping,cluster-node-timeout(可配置,秒級)時間內沒有收到對方的回覆,則單方面認爲對端節點宕機,將該節點標爲PFAIL狀態。經過節點之間交換信息收集到quorum個節點都認爲這個節點爲PFAIL,則將該節點標記爲FAIL,而且將其發送給其餘全部節點,其餘全部節點收到後當即認爲該節點宕機。從這裏能夠看出,主宕機後,至少cluster-node-timeout時間內該主所負責的Slot的讀寫服務不可用。mongodb

Redis Cluster的特色以下:

  • 節點自動發現
  • slave->master選舉,集羣容錯
  • Hot resharding:在線分片
  • 集羣管理:clusterxxx
  • 基於配置(nodes-port.conf)的集羣管理
  • ASK 轉向/MOVED轉向機制
  • 佈署無需指定master
  • 能夠支持超過1,000臺節點的集羣

======Redis-Cluster採用無中心結構,每一個節點保存數據和整個集羣狀態,每一個節點都和其餘全部節點鏈接======
redis-cluster架構圖以下:

 

其結構特色:

  • 全部的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬。
  • 節點的fail是經過集羣中超過半數的節點檢測失效時才生效。
  • 客戶端與redis節點直連,不須要中間proxy層.客戶端不須要鏈接集羣全部節點,鏈接集羣中任何一個可用節點便可。
  • redis-cluster把全部的物理節點映射到[0-16383]slot上(不必定是平均分配),cluster 負責維護node<->slot<->value。
  • Redis集羣預分好16384個桶,當須要在 Redis 集羣中放置一個 key-value 時,根據 CRC16(key) mod 16384的值,決定將一個key放到哪一個桶中。

redis cluster集羣是爲了下降單節點或單純主從redis的壓力,主主節點之間是不存在同步關係的,各主從之間的數據存在同步關係。有多少主節點,就會把16384個哈希槽(hash slot)平均分配到這些主節點上當往redis裏寫入數據時,會根據哈希算法算出這個數的哈希槽,決定它放到哪個主節點上,而後這個主節點的從節點去自動同步。在客戶端隨便鏈接一個主節點便可,主節點之間會進行內部跳轉!當取對應數據時,各節點之間會自動跳轉到所取數據所在的主節點上!

1)redis cluster節點分配
假設現有有三個主節點分別是:A、 B、C ,它們能夠是一臺機器上的三個端口,也能夠是三臺不一樣的服務器。那麼,採用哈希槽 (hash slot)的方式
來分配16384個slot 的話,它們三個節點分別承擔的slot 區間是:
節點A         覆蓋0-5460;
節點B         覆蓋5461-10922;
節點C        覆蓋10923-16383.

獲取數據:
若是存入一個值,按照redis cluster哈希槽的算法: CRC16('key')%16384 = 6782。 那麼就會把這個key 的存儲分配到 B 上了。一樣,當我鏈接
(A,B,C)任何一個節點想獲取'key'這個key時,也會這樣的算法,而後內部跳轉到B節點上獲取數據

新增一個主節點:
新增一個節點D,redis cluster的這種作法是從各個節點的前面各拿取一部分slot到D上,我會在接下來的實踐中實驗。大體就會變成這樣:
節點A         覆蓋1365-5460
節點B        覆蓋6827-10922
節點C       覆蓋12288-16383
節點D       覆蓋0-1364,5461-6826,10923-12287

一樣刪除一個節點也是相似,移動完成後就能夠刪除這個節點了。

2)Redis Cluster主從模式
redis cluster 爲了保證數據的高可用性,加入了主從模式,一個主節點對應一個或多個從節點,主節點提供數據存取,從節點則是從主節點拉取數據
備份,當這個主節點掛掉後,就會有這個從節點選取一個來充當主節點,從而保證集羣不會掛掉。

上面那個例子裏, 集羣有A、B、C三個主節點, 若是這3個節點都沒有加入從節點,若是B掛掉了,咱們就沒法訪問整個集羣了。A和C的slot也沒法訪問。
因此在集羣創建的時候,必定要爲每一個主節點都添加了從節點, 好比像這樣, 集羣包含主節點A、B、C, 以及從節點A一、B一、C1, 那麼即便B掛掉系統也
能夠繼續正確工做。B1節點替代了B節點,因此Redis集羣將會選擇B1節點做爲新的主節點,集羣將會繼續正確地提供服務。 當B從新開啓後,它就會變成B1的從節點。

不過須要注意,若是節點B和B1同時掛了,Redis集羣就沒法繼續正確地提供服務了。

===========廢話很少說,下面記錄下搭建redis cluster集羣==========
因爲最小的redis集羣須要3個主節點(即Redis Cluster集羣至少須要3個master節點,也就是說至少須要6個節點才能構建Redis cluster集羣),一臺機器可運行多個redis實例(通常使用兩臺機器,每臺啓動3個redis實例,即三個主節點,三個從節點)。不少案例使用單臺服務器開6個端口,操做差很少,只是配置基本相對簡單點,多臺服務器更接近生產環境。【當集羣最開始建立好後,要記住各節點的主從關係(或是建立的時候指定主從關係);如果其中一臺機器重啓,重啓後,需從新將其加入到redis cluster集羣中;這就須要將這臺機器上的各節點以前的從節點變爲主節點(客戶端執行slaveof no one),而後再根據新的主節點添加這臺機器的各節點到集羣中,添加後變爲從節點】
本案例redis cluster節點信息:
redis01
172.16.51.175:7000
172.16.51.175:7001
172.16.51.175:7002
redis02
172.16.51.176:7003
172.16.51.176:7004
172.16.51.176:7005
redis03
172.16.51.178:7006
172.16.51.178:7007
172.16.51.178:7008

先說下redis01節點的部署過程(其餘兩臺節點部署過程一致)

我的運維習慣,會專門建立一個app帳號,用戶部署應用程序。本案例應用程序都部署在/data目錄下,將/data權限設置成app
[root@bl-redis01 ~]# useradd app
[root@bl-redis01 ~]# passwd app
[root@bl-redis01 ~]# chown -R app.app /data
 
前提準備
1)安裝 GCC 編譯工具 否則會有編譯不過的問題
[root@bl-redis01 ~]# yum install -y gcc g++ make gcc-c++ kernel-devel automake autoconf libtool make wget tcl vim ruby rubygems unzip git
 
2)升級全部的包,防止出現版本太久不兼容問題
[root@bl-redis01 ~]# yum -y update
 
3)關閉防火牆 節點以前須要開放指定端口,爲了方便,生產不要禁用
[root@bl-redis01 ~]# /etc/init.d/iptables stop
[root@bl-redis01 ~]# setenforce 0
[root@bl-redis01 ~]# vim /etc/sysconfig/selinux
......
SELINUX=disabled
......
 
redis cluster集羣部署
4)下載並編譯安裝redis
[root@bl-redis01 ~]# su - app
[app@bl-redis01 ~]$ mkdir /data/software/
[app@bl-redis01 software]$ wget http://download.redis.io/releases/redis-4.0.1.tar.gz
[app@bl-redis01 software]$ tar -zvxf redis-4.0.1.tar.gz
[app@bl-redis01 software]$ mv redis-4.0.1 /data/
[app@bl-redis01 software]$ cd /data/redis-4.0.1/
[app@bl-redis01 redis-4.0.1]$ make
--------------------------------------------------------------------------------------
若是由於上次編譯失敗,有殘留的文件,作法以下:
[app@bl-redis01 redis-4.0.1]$ make distclean
--------------------------------------------------------------------------------------
 
5)建立節點
首先在172.16.51.175機器(redis01)上/data/redis-4.0.1目錄下建立redis-cluster目錄
[app@bl-redis01 redis-4.0.1]$ mkdir /data/redis-4.0.1/redis-cluster
 
接着在redis-cluster目錄下,建立名爲7000、700一、7002的目錄
[app@bl-redis01 redis-cluster]$ mkdir 7000
[app@bl-redis01 redis-cluster]$ mkdir 7001
[app@bl-redis01 redis-cluster]$ mkdir 7002
 
分別修改這三個配置文件redis.conf
[app@bl-redis01 redis-4.0.1]$ cd redis-cluster/
[app@bl-redis01 redis-cluster]$ ll
total 12
drwxrwxr-x 2 app app 4096 Nov 16 17:38 7000
drwxrwxr-x 2 app app 4096 Nov 16 17:39 7001
drwxrwxr-x 2 app app 4096 Nov 16 17:39 7002
[app@bl-redis01 redis-cluster]$ cat 7000/redis.conf
port 7000
bind 172.16.51.175
daemonize yes
pidfile /var/run/redis_7000.pid
cluster-enabled yes
cluster-config-file nodes_7000.conf
cluster-node-timeout 10100
appendonly yes
[app@bl-redis01 redis-cluster]$ cat 7001/redis.conf
port 7001
bind 172.16.51.175
daemonize yes
pidfile /var/run/redis_7001.pid
cluster-enabled yes
cluster-config-file nodes_7001.conf
cluster-node-timeout 10100
appendonly yes
[app@bl-redis01 redis-cluster]$ cat 7002/redis.conf
port 7002
bind 172.16.51.175
daemonize yes
pidfile /var/run/redis_7002.pid
cluster-enabled yes
cluster-config-file nodes_7002.conf
cluster-node-timeout 10100
appendonly yes
 
----------------------------------------------------------------------------------------------------
redis.conf的配置說明:
#端口7000,7001,7002
port 7000
 
#默認ip爲127.0.0.1,須要改成其餘節點機器可訪問的ip,不然建立集羣時沒法訪問對應的端口,沒法建立集羣
bind 172.16.51.175
 
#redis後臺運行
daemonize yes
 
#pidfile文件對應7000,7001,7002
pidfile /var/run/redis_7000.pid
 
#開啓集羣,把註釋#去掉
cluster-enabled yes
 
#集羣的配置,配置文件首次啓動自動生成 7000,7001,7002         
cluster-config-file nodes_7000.conf
 
#請求超時,默認15秒,可自行設置
cluster-node-timeout 10100   
         
#aof日誌開啓,有須要就開啓,它會每次寫操做都記錄一條日誌
appendonly yes
----------------------------------------------------------------------------------------------------
 
接着在另外兩臺機器上(172.16.51.176,172.16.51.178)重複以上三步,只是把目錄改成700三、700四、7005和700六、700七、7008,對應的配置文件也按照這個規則修改便可(即修改redis.conf文件中的端口就好了)
 
6)啓動集羣(依次啓動7000-7008端口)
#第一個節點機器上執行 3個節點
[app@bl-redis01 redis-cluster]$ for((i=0;i<=2;i++)); do /data/redis-4.0.1/src/redis-server /data/redis-4.0.1/redis-cluster/700$i/redis.conf; done
 
#第二個節點機器上執行 3個節點
[app@bl-redis01 redis-cluster]$ for((i=3;i<=5;i++)); do /data/redis-4.0.1/src/redis-server /data/redis-4.0.1/redis-cluster/700$i/redis.conf; done
 
#第三個節點機器上執行 3個節點
[app@bl-redis01 redis-cluster]$ for((i=6;i<=8;i++)); do /data/redis-4.0.1/src/redis-server /data/redis-4.0.1/redis-cluster/700$i/redis.conf; done
 
7)檢查服務
檢查各 Redis 各個節點啓動狀況
[app@bl-redis01 redis-cluster]$ ps -ef | grep redis 
app       2564  2405  0 20:13 pts/0    00:00:00 grep redis
app      15197     1  0 17:57 ?        00:00:05 /data/redis-4.0.1/src/redis-server 172.16.51.175:7000 [cluster]                  
app      15199     1  0 17:57 ?        00:00:05 /data/redis-4.0.1/src/redis-server 172.16.51.175:7001 [cluster]                  
app      15201     1  0 17:57 ?        00:00:05 /data/redis-4.0.1/src/redis-server 172.16.51.175:7002 [cluster]                  
[app@bl-redis01 redis-cluster]$ ps -ef | grep redis 
app       2566  2405  0 20:13 pts/0    00:00:00 grep redis
app      15197     1  0 17:57 ?        00:00:05 /data/redis-4.0.1/src/redis-server 172.16.51.175:7000 [cluster]                  
app      15199     1  0 17:57 ?        00:00:05 /data/redis-4.0.1/src/redis-server 172.16.51.175:7001 [cluster]                  
app      15201     1  0 17:57 ?        00:00:05 /data/redis-4.0.1/src/redis-server 172.16.51.175:7002 [cluster]
 
8)安裝 Ruby(須要切換到root帳號下進行安裝,app帳號下權限不夠)
[root@bl-redis01 ~]# yum -y install ruby ruby-devel rubygems rpm-build
[root@bl-redis01 ~]# gem install redis
-----------------------------------------------------------------------------------------------------
注意:在centos6.x下執行上面的"gem install redis"操做可能會報錯,坑不少!
默認yum安裝的ruby版本是1.8.7,版本過低,須要升級到ruby2.2以上,不然執行上面安裝會報錯!
 
首先安裝rvm(或者直接下載證書:https://pan.baidu.com/s/1slTyJ7n  密鑰:7uan   下載並解壓後直接執行"curl -L get.rvm.io | bash -s stable"便可)
[root@bl-redis01 ~]# curl -L get.rvm.io | bash -s stable          //可能會報錯,須要安裝提示進行下面一步操做
[root@bl-redis01 ~]# curl -sSL https://rvm.io/mpapis.asc | gpg2 --import -      //而後再接着執行:curl -L get.rvm.io | bash -s stable
[root@bl-redis01 ~]# find / -name rvm.sh
/etc/profile.d/rvm.sh
[root@bl-redis01 ~]# source /etc/profile.d/rvm.sh
[root@bl-redis01 ~]# rvm requirements
 
而後升級ruby到2.3
[root@bl-redis01 ~]# rvm install ruby 2.3.1
[root@bl-redis01 ~]# ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
 
列出全部ruby版本
[root@bl-redis01 ~]# rvm list
 
設置默認的版本
[root@bl-redis01 ~]# rvm --default use 2.3.1
 
更新下載源
[root@bl-redis01 ~]# gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org
https://gems.ruby-china.org/ added to sources
source https://rubygems.org not present in cache
 
[root@bl-redis01 ~]# gem sources
*** CURRENT SOURCES ***
 
https://rubygems.org/
https://gems.ruby-china.org/
 
最後就能順利安裝了
[root@bl-redis01 src]# gem install redis
Successfully installed redis-4.0.1
Parsing documentation for redis-4.0.1
Done installing documentation for redis after 1 seconds
1 gem installed
-----------------------------------------------------------------------------------------------------
 
9)建立集羣
千萬注意:在任意一臺上運行便可,不要在每臺機器上都運行,一臺就夠了!!!!
Redis 官方提供了 redis-trib.rb 這個工具,就在解壓目錄的 src 目錄中
[root@bl-redis01 ~]# su - app
[app@bl-redis01 ~]$ /data/redis-4.0.1/src/redis-trib.rb create --replicas 1 172.16.51.175:7000 172.16.51.175:7001 172.16.51.175:7002 172.16.51.176:7003 172.16.51.176:7004 172.16.51.176:7005 172.16.51.178:7006 172.16.51.178:7007 172.16.51.178:7008
 
出現下面信息,從下面信息能夠看出,本案例三臺服務器啓動9個實例,配置成4主5從,其中有一個是一主兩從,其餘3個都是一主一從。
>>> Creating cluster
>>> Performing hash slots allocation on 9 nodes...
Using 4 masters:
172.16.51.175:7000
172.16.51.176:7003
172.16.51.178:7006
172.16.51.175:7001
Adding replica 172.16.51.176:7004 to 172.16.51.175:7000
Adding replica 172.16.51.178:7007 to 172.16.51.176:7003
Adding replica 172.16.51.175:7002 to 172.16.51.178:7006
Adding replica 172.16.51.176:7005 to 172.16.51.175:7001
Adding replica 172.16.51.178:7008 to 172.16.51.175:7000
M: 7c622ac191edd40dd61d9b79b27f6f69d02a5bbf 172.16.51.175:7000
   slots:0-4095 (4096 slots) master
M: 44c81c15b01d992cb9ede4ad35477ec853d70723 172.16.51.175:7001
   slots:12288-16383 (4096 slots) master
S: 38f03c27af39723e1828eb62d1775c4b6e2c3638 172.16.51.175:7002
   replicates f1abb62a8c9b448ea14db421bdfe3f1d8075189c
M: 987965baf505a9aa43e50e46c76189c51a8f17ec 172.16.51.176:7003
   slots:4096-8191 (4096 slots) master
S: 6555292fed9c5d52fcf5b983c441aff6f96923d5 172.16.51.176:7004
   replicates 7c622ac191edd40dd61d9b79b27f6f69d02a5bbf
S: 2b5ba254a0405d4efde4c459867b15176f79244a 172.16.51.176:7005
   replicates 44c81c15b01d992cb9ede4ad35477ec853d70723
M: f1abb62a8c9b448ea14db421bdfe3f1d8075189c 172.16.51.178:7006
   slots:8192-12287 (4096 slots) master
S: eb4067373d36d8a8df07951f92794e67a6aac022 172.16.51.178:7007
   replicates 987965baf505a9aa43e50e46c76189c51a8f17ec
S: 2919e041dd3d1daf176d6800dcd262f4e727f366 172.16.51.178:7008
   replicates 7c622ac191edd40dd61d9b79b27f6f69d02a5bbf
Can I set the above configuration? (type 'yes' to accept): yes
 
輸入 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.51.175:7000)
M: 7c622ac191edd40dd61d9b79b27f6f69d02a5bbf 172.16.51.175:7000
   slots:0-4095 (4096 slots) master
   2 additional replica(s)
S: 6555292fed9c5d52fcf5b983c441aff6f96923d5 172.16.51.176:7004
   slots: (0 slots) slave
   replicates 7c622ac191edd40dd61d9b79b27f6f69d02a5bbf
M: 44c81c15b01d992cb9ede4ad35477ec853d70723 172.16.51.175:7001
   slots:12288-16383 (4096 slots) master
   1 additional replica(s)
S: 2919e041dd3d1daf176d6800dcd262f4e727f366 172.16.51.178:7008
   slots: (0 slots) slave
   replicates 7c622ac191edd40dd61d9b79b27f6f69d02a5bbf
M: f1abb62a8c9b448ea14db421bdfe3f1d8075189c 172.16.51.178:7006
   slots:8192-12287 (4096 slots) master
   1 additional replica(s)
S: eb4067373d36d8a8df07951f92794e67a6aac022 172.16.51.178:7007
   slots: (0 slots) slave
   replicates 987965baf505a9aa43e50e46c76189c51a8f17ec
S: 38f03c27af39723e1828eb62d1775c4b6e2c3638 172.16.51.175:7002
   slots: (0 slots) slave
   replicates f1abb62a8c9b448ea14db421bdfe3f1d8075189c
S: 2b5ba254a0405d4efde4c459867b15176f79244a 172.16.51.176:7005
   slots: (0 slots) slave
   replicates 44c81c15b01d992cb9ede4ad35477ec853d70723
M: 987965baf505a9aa43e50e46c76189c51a8f17ec 172.16.51.176:7003
   slots:4096-8191 (4096 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.
 
10)關閉集羣
推薦作法:
[app@bl-redis01 ~]$ pkill redis
[app@bl-redis02 ~]$ pkill redis
[app@bl-redis03 ~]$ pkill redis
 
或者循環節點逐個關閉
[app@bl-redis01 ~]$ for((i=0;i<=2;i++)); do /opt/redis-4.0.1/src/redis-cli -c -h 172.16.51.175 -p 700$i shutdown; done
[app@bl-redis02 ~]$ for((i=3;i<=5;i++)); do /opt/redis-4.0.1/src/redis-cli -c -h 172.16.51.176 -p 700$i shutdown; done
[app@bl-redis03 ~]$ for((i=6;i<=8;i++)); do /opt/redis-4.0.1/src/redis-cli -c -h 172.16.51.178 -p 700$i shutdown; done
 
11)集羣驗證
鏈接集羣測試
參數-C可鏈接到集羣,由於redis.conf將bind改成了ip地址,因此-h參數不能夠省略,-p參數爲端口號
 
能夠先在172.16.51.175機器redis 7000 的節點set一個key
[app@bl-redis01 ~]$ /data/redis-4.0.1/src/redis-cli -h 172.16.51.175 -c -p 7000
172.16.51.175:7000> set name www.ymq.io
-> Redirected to slot [5798] located at 172.16.51.176:7003
OK
172.16.51.176:7003> get name
"www.ymq.io"
172.16.51.176:7003>
 
由上面信息可發現redis set name 以後重定向到172.16.51.176機器 redis 7003 這個節點
 
而後在172.16.51.178機器redis 7008 的節點get一個key
[app@bl-redis03 ~]$ /data/redis-4.0.1/src/redis-cli -h 172.16.51.178 -c -p 7008
172.16.51.178:7008> get name
-> Redirected to slot [5798] located at 172.16.51.176:7003
"www.ymq.io"
172.16.51.176:7003>
 
發現redis get name 重定向到172.16.51.176機器 redis 7003 這個節點.
 
若是看到這樣的現象,說明redis cluster集羣已是可用的了!!!!!!
 
12)檢查集羣狀態(經過下面的命令,能夠看到本案例實現的是4主5從,4個主節點會默認分配到三個機器上,每一個機器上都要有master;另:建立集羣的時候能夠指定master和slave。這裏我是默認建立的)
[app@bl-redis01 ~]$ /data/redis-4.0.1/src/redis-cli -h 172.16.51.175 -c -p 7000
172.16.51.175:7000>
[app@bl-redis01 ~]$ /data/redis-4.0.1/src/redis-trib.rb check 172.16.51.175:7000
>>> Performing Cluster Check (using node 172.16.51.175:7000)
M: 5a43e668f53ff64da68be31afe6dc6ea1f3c14c5 172.16.51.175:7000
   slots:0-4095 (4096 slots) master
   2 additional replica(s)
M: c64b0839e0199f73c5c192cc8c90f12c999f79b2 172.16.51.175:7001
   slots:12288-16383 (4096 slots) master
   1 additional replica(s)
S: 81347f01cf38d8f0faef1ad02676ebb4cffbec9e 172.16.51.176:7005
   slots: (0 slots) slave
   replicates c64b0839e0199f73c5c192cc8c90f12c999f79b2
M: da5dde3f2f02c232784bf3163f5f584b8cf046f2 172.16.51.178:7006
   slots:8192-12287 (4096 slots) master
   1 additional replica(s)
M: b217ab2a6c05497af3b2a859c1bb6b3fae5e0d92 172.16.51.176:7003
   slots:4096-8191 (4096 slots) master
   1 additional replica(s)
S: 0420c49fbc9f1fe16066d189265cca2f5e71c86e 172.16.51.178:7007
   slots: (0 slots) slave
   replicates b217ab2a6c05497af3b2a859c1bb6b3fae5e0d92
S: 5ad89453fb36e50ecc4560de6b4acce1dbbb78b3 172.16.51.176:7004
   slots: (0 slots) slave
   replicates 5a43e668f53ff64da68be31afe6dc6ea1f3c14c5
S: bbd1f279b99b95cf00ecbfab22b6b8dd5eb05989 172.16.51.178:7008
   slots: (0 slots) slave
   replicates 5a43e668f53ff64da68be31afe6dc6ea1f3c14c5
S: e95407b83bfeb30e3cc537161eadc372d6aa1fa2 172.16.51.175:7002
   slots: (0 slots) slave
   replicates da5dde3f2f02c232784bf3163f5f584b8cf046f2
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
 
13)列出集羣節點
列出集羣當前已知的全部節點(node),以及這些節點的相關信息
[app@bl-redis01 ~]$ /data/redis-4.0.1/src/redis-cli -h 172.16.51.175 -c -p 7000
172.16.51.175:7000> cluster nodes
5a43e668f53ff64da68be31afe6dc6ea1f3c14c5 172.16.51.175:7000@17000 myself,master - 0 1510836027000 1 connected 0-4095
c64b0839e0199f73c5c192cc8c90f12c999f79b2 172.16.51.175:7001@17001 master - 0 1510836030068 2 connected 12288-16383
81347f01cf38d8f0faef1ad02676ebb4cffbec9e 172.16.51.176:7005@17005 slave c64b0839e0199f73c5c192cc8c90f12c999f79b2 0 1510836031000 6 connected
da5dde3f2f02c232784bf3163f5f584b8cf046f2 172.16.51.178:7006@17006 master - 0 1510836031000 7 connected 8192-12287
b217ab2a6c05497af3b2a859c1bb6b3fae5e0d92 172.16.51.176:7003@17003 master - 0 1510836030000 4 connected 4096-8191
0420c49fbc9f1fe16066d189265cca2f5e71c86e 172.16.51.178:7007@17007 slave b217ab2a6c05497af3b2a859c1bb6b3fae5e0d92 0 1510836029067 8 connected
5ad89453fb36e50ecc4560de6b4acce1dbbb78b3 172.16.51.176:7004@17004 slave 5a43e668f53ff64da68be31afe6dc6ea1f3c14c5 0 1510836032672 5 connected
bbd1f279b99b95cf00ecbfab22b6b8dd5eb05989 172.16.51.178:7008@17008 slave 5a43e668f53ff64da68be31afe6dc6ea1f3c14c5 0 1510836031000 9 connected
e95407b83bfeb30e3cc537161eadc372d6aa1fa2 172.16.51.175:7002@17002 slave da5dde3f2f02c232784bf3163f5f584b8cf046f2 0 1510836031672 7 connected
 
14)打印集羣信息
[app@bl-redis01 ~]$ /data/redis-4.0.1/src/redis-cli -h 172.16.51.175 -c -p 7000
172.16.51.175:7000> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:9
cluster_size:4
cluster_current_epoch:9
cluster_my_epoch:1
cluster_stats_messages_ping_sent:8627
cluster_stats_messages_pong_sent:8581
cluster_stats_messages_sent:17208
cluster_stats_messages_ping_received:8573
cluster_stats_messages_pong_received:8626
cluster_stats_messages_meet_received:8
cluster_stats_messages_received:17207

------------------------------------------------------------------------------------------------
[root@bl-redis01 src]# pwd
/data/redis-4.0.1/src
[root@bl-redis01 src]# ./redis-trib.rb help
Usage: redis-trib <command> <options> <arguments ...>

  create          host1:port1 ... hostN:portN
                  --replicas <arg>
  check           host:port
  info            host:port
  fix             host:port
                  --timeout <arg>
  reshard         host:port
                  --from <arg>
                  --to <arg>
                  --slots <arg>
                  --yes
                  --timeout <arg>
                  --pipeline <arg>
  rebalance       host:port
                  --weight <arg>
                  --auto-weights
                  --use-empty-masters
                  --timeout <arg>
                  --simulate
                  --pipeline <arg>
                  --threshold <arg>
  add-node        new_host:new_port existing_host:existing_port
                  --slave
                  --master-id <arg>
  del-node        host:port node_id
  set-timeout     host:port milliseconds
  call            host:port command arg arg .. arg
  import          host:port
                  --from <arg>
                  --copy
                  --replace
  help            (show this help)

For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.

上面已經屢次出現了slot這個詞,略爲解釋一下:
redis-cluster把整個集羣的存儲空間劃分爲16384個slot(譯爲:插槽?),當9個實例分爲3主6從時,至關於整個cluster中有3組HA的節點,
3個master會平均分攤全部slot,每次向cluster中的key作操做時(好比:讀取/寫入緩存),redis會對key值作CRC32算法處理,獲得一個數值,
而後再對16384取模,經過餘數判斷該緩存項應該落在哪一個slot上,肯定了slot,也就肯定了保存在哪一個master節點上,當cluster擴容或刪除
節點時,只須要將slot從新分配便可(即:把部分slot從一些節點移動到其它節點)。

---------------------------------------------------------------------------------------------------------
在代碼裏鏈接以上redis cluster集羣節點配置以下:
spring.redis.cluster.nodes = 172.16.51.175:7000,172.16.51.175:7001,172.16.51.175:7002,172.16.51.176:7003,172.16.51.176:7004,172.16.51.176:7005,172.16.51.178:7006,172.16.51.178:7007,172.16.51.178:7008

==========================集羣模式配置======================

如下這種方式貌似不能按照本身的思路添加主從
redis-trib.rb create --replicas 1 192.168.1.101:6381 192.168.1.102:6382  192.168.1.103:6383 192.168.1.102:6381 192.168.1.103:6382   192.168.1.101:6383
 
思路改成先加主庫 再加從庫
添加主庫
redis-trib.rb create  192.168.1.101:6381 192.168.1.102:6382  192.168.1.103:6383
 
添加從庫
把 102的6381 做爲從庫加入 101的6381
redis-trib.rb add-node --slave 192.168.1.102:6381   192.168.1.101:6381
 
redis-trib.rb add-node --slave 192.168.1.103:6382   192.168.1.102:6382
redis-trib.rb add-node --slave 192.168.1.101:6383   192.168.1.103:6383
 
檢測
redis-trib.rb check 192.168.1.101:6381
redis-trib.rb check 192.168.1.102:6382
redis-trib.rb check 192.168.1.103:6383

==========================redis cluster常見的幾個問題======================

1)問題一
因爲redis clster集羣節點宕機(或節點的redis服務重啓),致使了部分slot數據分片丟失;在用check檢查集羣運行狀態時,遇到錯誤;
[root@slave2 redis]# redis-trib.rb check 192.168.1.100:7000
........
[ERR] Not all 16384 slots are covered by nodes.
    
緣由分析:
這個每每是因爲主node移除了,可是並無移除node上面的slot,從而致使了slot總數沒有達到16384,其實也就是slots分佈不正確。
因此在刪除節點的時候必定要注意刪除的是不是Master主節點。
    
解決辦法:
官方是推薦使用redis-trib.rb fix 來修復集羣。經過cluster nodes看到7001這個節點被幹掉了。能夠按照下面操做進行修復
[root@slave2 redis]# redis-trib.rb fix 192.168.1.100:7000
    
修復完成後再用check命令檢查下是否正確(查看別的節點)
[root@slave2 redis]# redis-trib.rb check 192.168.1.101:7002
    
只要輸入任意集羣中節點便可,會自動檢查全部相關節點。
能夠查看相應的輸出看下是不是每一個Master都有了slots。
    
若是分佈不均勻那可使用下面的方式從新分配slot:
[root@slave2 redis]# redis-trib.rb reshard 192.168.1.100:7000
 
特別注意:
在部分節點重啓後從新回到集羣中的過程期間,在check集羣狀態的時候會出現"[ERR] Not all 16384 slots are covered by nodes."這個報錯,
須要稍微等待一會,等重啓節點徹底回到集羣中後,這個報錯就會消失!
======================================================
問題二:
在往redis cluster集羣環境中添加節點時遇到一個問題,提示新增的Node不爲空:
[root@slave2 redis]# redis-trib.rb add-node --slave 192.168.1.103:7004  192.168.1.102:7002
.......
[ERR] Node 192.168.1.103:7004 is not empty. Either the nodealready knows other nodes (check with CLUSTER NODES) or
contains some key in database 0.
    
解決辦法:(若是redis cluster全部節點同時斷電同時宕機, 則節點重啓後, 只能從新建立集羣, 以前的集羣數據所有丟失! 從新建立集羣前,各節點要以下操做)
1)將192.168.1.103節點機redis下的aof、rdb等本地備份文件所有刪除
2)同時將新Node的集羣配置文件刪除,也便是刪除redis.conf裏面cluster-config-file指定所在的文件;
3)"redis-cli -c -h 192.168.1.103 -p 7004"登錄後,執行 "flushdb"命令進行清除操做
4)重啓reds服務
5)最後再次執行節點添加操做
    
=============================================================================================
舒適提示:
-  集羣中只要有一組master-slave節點同時掛點,則集羣服務也會掛掉;待該組master和slave節點的redis恢復後,這部分slot槽的數據也會丟失。
-  集羣中1/2或master節點掛掉,則集羣服務也會掛掉;待這些master節點服務重啓後,會自動加入到集羣中,需等待一段時間,集羣恢復正常,數據不會丟失。
  
- 集羣中master節點關閉,須要等待一小段時間,它對應的slave節點就會變成master節點,集羣服務正常,數據會隨之到新的maser節點的slot。
- master節點掛掉後,重啓redis服務(必定要在原來的aof和nodes*.conf文件路徑下啓動),則會自動加入到cluster集羣中,並會變成slave節點。
  
-  新添加的master節點的slot默認爲0,master主節點若是沒有slots,存取數據就都不會被選中! 故要爲新增長的master節點進行reshard從新分配slot。
-  slave從節點的slot爲0,數據不會存儲在slave節點!只會存儲在master主節點中,master節點纔有slot數值。

======================================================
注意:每一組的master-slave節點不能同時掛掉或短期內前後掛掉,不然這部分slot內的數據就會丟失。
好比說一主一從,當master節點掛掉後,數據都保存到slave節點內,稍過一會,slave節點就會被選舉爲新的master節點。
老的master節點重啓後從新回到集羣中,並自動變爲它原來的slave(如今是新的master)的slave節點,並自動同步數據。
這個時候新的master節點若是掛掉,則數據一樣會保存到新的slave節點中,新的slave節點過一段時間一樣會被再次選舉爲新的master,如此類推....
若是master節點和它的slave節點同時掛掉,或者在其中一個掛掉後尚未來得及恢復到集羣中,另外一個就掛掉,這種狀況下,這部分slot槽的數據確定就沒有了。
因此說,通常會重啓一個節點,待該節點恢復到集羣中後,再能夠重啓它對應的slave或master節點。
 
redis做爲純緩存服務時,數據丟失,通常對業務是無感的,不影響業務,丟失後會再次寫入。但若是做爲存儲服務(即做爲存儲數據庫),數據丟失則對業務影響很大。
不過通常業務場景,存儲數據庫會用mysql、oracle或mongodb。

======================================================
redis cluster集羣節點重啓後,要想恢復集羣狀態,正確的作法是:
1)要在各個節點原來的appendonly.aof ,dump.rdb,nodes_*.conf 文件所在路徑下重啓redis服務。這樣就能確保redis啓動後用到以前的數據文件。
(可使用find命令查找這些文件所在路徑,而後在這個路徑下啓動redis服務)
2)各個節點的redis服務正常啓動後,就能夠直接查看redis cluster狀態了,檢查集羣狀態是否恢復。
      
注意:
必定要在原來的數據文件的路徑下啓動redis,若是啓動的路徑錯誤,則讀取的數據文件就不是以前的了,這樣集羣就很難恢復了。這個時候就須要刪除以前的數據文件,
從新建立集羣了。(或者直接在/data/redis-4.0.6/redis-cluster/700*目錄下的redis.conf文件裏的cluster-config-file指定文件的絕對路徑)
   
集羣節點的redis服務重啓後,check集羣狀態,若有下面告警信息,處理以下:
[root@redis-node01 redis-cluster]# /data/redis-4.0.6/src/redis-trib.rb check 192.168.1.100:7000
...........
...........
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
[WARNING] Node 192.168.1.100:7000 has slots in importing state (5798,11479).
[WARNING] Node 192.168.1.100:7001 has slots in importing state (1734,5798).
[WARNING] Node 192.168.1.101:7002 has slots in importing state (11479).
[WARNING] The following slots are open: 5798,11479,1734
>>> Check slots coverage...
[OK] All 16384 slots covered.
   
解決辦法:
必定要登陸到告警信息中的節點和對應的端口上進行操做。
執行"cluster setslot <slot> stable"命令,表示取消對槽slot 的導入( import)或者遷移( migrate)。
執行後,這部分slot槽的數據就沒了。
[root@redis-node01 redis-cluster]# /data/redis-4.0.6/src/redis-cli -h 192.168.1.100 -c -p 7000
192.168.1.100:7000> cluster setslot 5798 stable
OK
192.168.1.100:7000> cluster setslot 11479 stable
OK
   
[root@redis-node01 redis-cluster]# /data/redis-4.0.6/src/redis-cli -h 192.168.1.100 -c -p 7001
192.168.1.100:7001> cluster setslot 1734 stable
OK
192.168.1.100:7001> cluster setslot 5798 stable
OK
   
[root@redis-node01 redis-cluster]# /data/redis-4.0.6/src/redis-cli -h 192.168.1.101 -c -p 7002
192.168.1.101:7002> cluster setslot 11479 stable
OK
   
再次檢查redis cluster集羣狀態,就會發現一切正常了!
[root@redis-node01 redis-cluster]# /data/redis-4.0.6/src/redis-trib.rb check 192.168.1.100:7000
>>> Performing Cluster Check (using node 192.168.1.100:7000)
M: 39737de1c48fdbaec304f0d11294286593553365 192.168.1.100:7000
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: 61a0cc84069ced156b6e1459bb71cab225182385 192.168.1.101:7003
   slots: (0 slots) slave
   replicates 39737de1c48fdbaec304f0d11294286593553365
S: 75de8c46eda03aee1afdd39de3ffd39cc42a5eec 172.16.60.209:7005
   slots: (0 slots) slave
   replicates 70a24c750995e2f316ee15320acb73441254a7aa
M: 70a24c750995e2f316ee15320acb73441254a7aa 192.168.1.101:7002
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 5272bd14768e3e32e165284c272525a7da47b47e 192.168.1.100:7001
   slots: (0 slots) slave
   replicates c1b71d52b0d804f499c9166c0c1f4e3c35077ee9
M: c1b71d52b0d804f499c9166c0c1f4e3c35077ee9 172.16.60.209:7004
   slots:10923-16383 (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.
相關文章
相關標籤/搜索