redis cluster集群是由多個主從節(jié)點群組成的分布式服務器集群煮岁,具有復制讥蔽、高可用和分片特性嗓违。不需要哨兵也能完成節(jié)點的移除和故障轉移功能巍膘。
需要將每個節(jié)點設置成集群模式,這種集群沒有中心節(jié)點恳蹲,可以線程擴展高達1000個節(jié)點步氏。
密鑰分配模型
Redis Cluster集群數(shù)據(jù)分片沒有使用一致哈希响禽,而是使用哈希槽。redis集群有16384個哈希槽,要計算哈希槽芋类,只需要給定鍵的CRC16取模16384隆嗅。
集群中的每個節(jié)點都負責哈希槽的子集,這樣可以輕松添加和刪除集群中的節(jié)點
集群總線
一個服務于客戶端的TCP端口侯繁,如6379
一個用于集群總線(客戶端端口加10000)胖喳,16379:用于故障檢測、配置更新巫击、故障轉移禀晓。
節(jié)點與節(jié)點的通信僅使用集群總線和集群總線協(xié)議進行。
如果兩個端口沒有開放坝锰,則集群不能正常工作
redis cluster集群搭建
redis cluster集群至少需要三個master節(jié)點粹懒,我們這里搭建3個master,且給每個master一個slave節(jié)點顷级。這里搭建偽分布式都在一臺上凫乖,端口8001到8006。
1弓颈、創(chuàng)建文件夾redis-cluster帽芽,在redis-cluster下面創(chuàng)建6個文件夾 8001到8006
mkdir -p /opt/redis-cluster
mkdir 8001 8002 8003 8004 8005 8006
2、把redis.conf配置文件復制到8001翔冀,并修改如下
daemonize yes
port 8001
bind 127.0.0.1
dir /opt/redis-cluster/8001/
cluster-enabled yes
cluster-config-file nodes-8001.conf
cluster-node-timeout 5000
appendonly yes
其他文件修改對應端口就行
sed 's/8001/8002/g' /opt/redis-cluster/8001redis.conf > /opt/redis-cluster/8002/redis.conf
然后啟動8001到8006端口的redis
redis-server /usr/local/redis-cluster/800*/redis.conf
3导街、設置集群
啟動完成之后需要設置集群模式,有以下方式
①原生搭建
meet
cluster meet ip port
指派槽( 0到16383)
根據(jù)crc16 算法 算出key槽位
cluster keyslot <key> 計算鍵 key 應該被放置在哪個槽上纤子。
cluster addslots slot(槽位下標)
分配主從
cluster replicate node-id
②redis提供的rb腳本
如果要使用ruby需要首先安裝
apt-get install ruby rubygems
gem install redis --version 3.0.0
然后在redis的安裝目錄下執(zhí)行 redis-trib.rb命令創(chuàng)建整個redis集群搬瑰,槽位可以按照指引完成
./redis-trib.rb create --replicas 1 127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003 127.0.0.1:8004 127.0.0.1:8005 127.0.0.1:8006
③redis-cli --cluster命令
redis5.0之后可以使用,槽位也可以按照指引完成分配
redis-cli --cluster create 192.127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003 192.168.0.104:8004 127.0.0.1:8005 127.0.0.1:8006 --cluster-replicas 1
--cluster-replicas值代表master與slave的比例控硼,如果是1則master有三臺slave有三臺8004泽论、8005、8006是slave隨機對應8001卡乾、8002翼悴、8003端口
4、驗證集群
連接任意客戶端/usr/local/redis/bin/redis-cli -c -h 127.0.0.1 -p 8002
驗證cluster info(查看集群信息)幔妨、cluster nodes(查看節(jié)點列表)鹦赎、及數(shù)據(jù)添加測試
redis 127.0.0.1:8002> set hello world
-> Redirected to slot [866] located at 127.0.0.1:8001
OK
如果需要關閉,則一個一個關閉redis-cli -c -h 127.0.0.1 -p 800* shutdown
集群伸縮
擴容集群
1误堡、準備新節(jié)點
如8007钙姊、8008端口節(jié)點。創(chuàng)建過程與其他端口相同
2埂伦、加入集群
使用redis-cli 并指定主從
add-node 新節(jié)點ip 端口 已存在節(jié)點ip 端口 --cluster-slave --cluster-master-id masterID
使用原生命令 語法:cluster meet ip port cluster replicate node-id
3、遷移槽和數(shù)據(jù)
槽遷移 redis-cli --cluster reshard 127.0.0.1:8001
遷移數(shù)據(jù):根據(jù)提示要分配多少槽思恐、接收節(jié)點ID沾谜、all/done
添加從節(jié)點
縮容集群
1膊毁、下線遷移槽
redis-cli --cluster reshard --cluster-from 遷出節(jié)點ID --cluster-to 接收槽節(jié)點ID --cluster-slots 遷出槽數(shù)量 已存在節(jié)點ip 端口
2、忘記并關閉節(jié)點
redis-cli --cluster del-node 存在節(jié)點IP:端口 要刪除的節(jié)點ID
故障轉移
與哨兵類似基跑,故障發(fā)現(xiàn)不依賴哨兵
故障恢復:
1婚温、檢查每個從節(jié)點與主節(jié)點斷開時間
2、選擇偏移量最大的并替換主節(jié)點
slaveof no one變?yōu)橹鞴?jié)點媳否,撤銷之前主節(jié)點槽位給新主節(jié)點栅螟,并向集群廣播已經(jīng)替換故障節(jié)點
重定向和重新分片
moved重定向:發(fā)送命令時,經(jīng)過crc16算法篱竭,客戶端沒有這個數(shù)字范圍力图。需要捕獲異常
asx重定向:發(fā)送命令時,正在遷移槽位
moved移動重定向
Redis客戶端可以向集群的每個節(jié)點發(fā)送查詢掺逼,如果這個hash槽由這個節(jié)點服務則查詢被簡單處理吃媒。否則,節(jié)點將會檢查其內(nèi)部哈希槽到節(jié)點的映射吕喘,并通過MOVED錯誤回復客戶端赘那。如下面示例所示,僅做參考:
GET x
-MOVED 3999 127.0.0.1:7001
錯誤包括鍵的哈希槽(3999)和可以為查詢提供服務的ip:port氯质。在收到MOVED重定向后募舟,使用cluster nodes或cluster slots命令刷新整個客戶端集群布局,遇到這種情況闻察,可能重新配置了多個插槽拱礁,而不僅僅一個,因此盡快更新比較好
ASK重定向
當遷移槽時蜓陌,可以將插槽設置:
migrating時觅彰,表示該節(jié)點將接受與該哈希槽有關的所有查詢,但是僅當所討論的鍵存在是钮热,否則該查詢將使用ask重定向轉發(fā)到遷移目標節(jié)點
importing時填抬,則該節(jié)點接受與該哈希槽有關的所有查詢,前提是請求之前帶有ASKING命令隧期。如果客戶端未提供命令飒责,則查詢會通過-MOVED重定向錯誤重定向到實際的哈希槽所有者
假如:哈希槽8 從A移動到B
moved意味著我們認為哈希槽由另一個節(jié)點永久提供。所以仆潮,ASK意味著僅將下一個查詢發(fā)送到指定節(jié)點宏蛉。這么做的原因是因為哈希槽的查詢可能在遷移前的節(jié)點B仍然存在,因此始終希望客戶端嘗試之前的節(jié)點A性置,然后需要時嘗試遷移后的節(jié)點拾并。
如果客戶端查詢之前發(fā)送asking命令,則節(jié)點B將僅接受設置為importing的插槽查詢
一旦哈希槽8遷移完成,A將發(fā)送moved消息嗅义,且客戶端永久映射新的ip和端口
總結
redis cluster集群是高可用集群屏歹,使用哈希槽分片可以輕松添加或刪除節(jié)點。
解決了哨兵模式單機存儲受限問題之碗、及寫操作的負載均衡
可以解決緩存雪崩問題