Redis Cluster 搭建高可用Redis伺服器叢集
redis-cluster提供的功能:
- 節點自動發現
- 主從選舉,切換,叢集容錯
- 叢集管理
- 線上分片
- ASK轉向/MOVED轉向機制
架構細節說明:
(1)所有的redis節點彼此互聯(PING-PONG機制),內部使用二進位制協議優化傳輸速度和頻寬.
(2)節點的fail是通過叢集中超過半數的master節點檢測失效時才生效.
(3)客戶端與redis節點直連,不需要中間proxy層.客戶端不需要連線叢集所有節點,連線叢集中任何一個可用節點即可
(4)redis-cluster把所有的物理節點對映到[0-16383]slot上,cluster 負責維護node<->slot<->key
選舉容錯
(1)領導選舉過程是叢集中所有master參與,如果半數以上master節點與故障節點通訊超過(cluster-node-timeout),認為該節點故障,自動觸發故障轉移操作.
(2):什麼時候整個叢集不可用(cluster_state:fail)?
a:如果叢集任意master掛掉,且當前master沒有slave.叢集進入fail狀態,也可以理解成叢集的slot對映[0-16383]不完成時進入fail態. redis-3.0.0.rc1加入cluster-require-full-coverage引數,預設關閉,開啟叢集相容部分失敗.
b:如果叢集超過半數以上master掛掉,無論是否有slave叢集進入fail狀態.
ps:當叢集不可用時,所有對叢集的操作做都不可用,收到((error) CLUSTERDOWN The cluster is down)錯誤
搭建叢集說明:本人用的是4臺伺服器來搭建,同時要讓叢集正常工作至少需要3個主節點,所以這裡每臺主機都會開啟3個redis例項,就一共12個例項,(6個master和6個slave)
例如:
主機1:192.168.25.65
主機2:192.168.25.66
主機3:192.168.25.67
主機4:192.168.25.68
搭建的步驟:
1.先安裝好redis,安裝步驟請自行百度
2.在各個主機建立叢集目錄
mkdir -p /usr/local/RedisCluster cd /usr/local/RedisCluster mkdir 7000 7001 7002 (依次在餘下主機建立7003-7011)
3.修改redis.conf配置檔案,並放進叢集目錄
cp /etc/redis/redis.conf /usr/local/RedisCluster/7000
按照如下修改:(每個例項都得修改,根據相應埠修改)
port 7000
daemonize yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
4.分別啟動7000-7011共12個redis例項
redis-server redis.conf
可以檢視服務啟動情況:ps aux|grep redis5.進入redis的目錄將redis-trib.rb複製到/usr/local/bin目錄下
cp redis-trib.rb /usr/local/bin/
6.安裝ruby
yum -y install ruby ruby-devel rubygems rpm-build
gem install redis
7.建立叢集(只需在其中一臺主機上操作即可)
redis-trib.rb create --replicas 1 192.168.25.65:7000 192.168.25.65:7001 192.168.25.65:7002 192.168.25.66:7003 192.168.25.66:7004 192.168.25.66:7005 192.168.25.67:7006 192.168.25.67:7007 192.168.25.67:7008 192.168.25.68:7009 192.168.25.68:7010 192.168.25.68:7011
8.叢集建立成功,連線方式為:redis-cli -h 192.168.25.65 -c -p 7000 (-c代表可連線到叢集) ,進入redis,設定一個值,然後在其他節點上檢視。同時當kill掉一個master節點,cluster會重新選舉另一個節點當master
可能遇到的錯誤:
1.配置完所有主節點後,報" ERR Invalid node address specified"
由於Redis-trib.rb 對域名或主機名支援不好,故在建立叢集的時候要使用ip:port的方式
redis-trib.rb create ip1:port1 ip2:port2 ip3:port3
2.出現err slot 0 is already busy (redis::commanderror)
這時需要刪除nodes-*.conf檔案dump.rdb檔案(每個伺服器上都會生成,記得全部清空),然後重啟每個redis例項