7.redis-cluster(集羣)

1.爲何須要集羣
(1)併發量:OPS
redis性能能夠達到10W/每秒,若是業務須要100W/每秒呢
(2)數據量
機器內存:16-256G,業務須要500G呢
(3)解決方法:
分佈式:簡單的認爲加機器
2.數據分佈
經常使用的兩種分佈方式
方式一:順序分佈
舉例:有三個節點,保證每一個節點均衡
node

 


特色:數據分散易傾斜,鍵值業務相關,可順序訪問,不支持批量操做
典型產品:BigTable,HBase
方式二:哈希分佈
特色:數據分散度高,鍵值分佈業務無關,沒法順序訪問,支持批量操做
典型產品:一致性哈希Memcache,redis cluster,其餘緩存產品
哈希分佈三種方式:
方式一:節點取餘分區
客戶端分片:哈希+取餘
舉例:有三個節點,對每個數字作哈希的函數,再按照節點數作一個取餘
redis

 


舉例:有四個節點,對每個數字作哈希的函數,再按照節點數作一個取餘

問題:若是當前是3個節點,加1個節點,或減1個節點,數據節點關係變化,會致使數據遷移,遷移達到80%
解決:若是想作加節點,建議作翻倍擴容,當前3個節點,加3個節點,遷移會降到50%
方式二:一致性哈希分區
客戶端分片:哈希+順時針(優化取餘)
節點伸縮:隻影響鄰近節點,可是仍是有數據遷移
翻倍伸縮:保證最小遷移數據和負載均衡
方式三:虛擬槽分區
槽(理解爲一個數字範圍是0~16383)
預設虛擬槽:每一個槽映射一個數據子集,通常比節點數大
良好的哈希函數:例如CRC16
舉例:有5個節點,對槽平均分紅5份,對於每一個keys來說作哈希,在RedisCluster裏面就是CRC16給它作一個哈希對16383去取一個餘,消息會發送給RedisCluster裏面的任意一個節點,它每個節點記錄本身是否是負責這個槽的,當某一個節點是負責這個槽就保存返回一個結果,若是發現不在這個槽,因爲RedisCluster是共享消息模式,知道哪些節點負責哪些槽,就會告訴你結果讓你去對應的節點去取

特性:主從複製,高可用,分片多個主節點能夠讀寫
3.搭建集羣
(1)基本架構
節點:RedisCluster裏有不少節點,每一個節點負責讀寫
meet:節點之間進行相互通訊的,meet過程就是完成這個過程的基礎
指派槽:給節點指派了對應的槽,它才能夠進行正常讀寫
複製:保證高可用,每個主節點都有一個從節點
(2)兩種安裝方式
方式一:原生命令安裝
第一步:配置開啓節點
配置6個節點:數據庫

#端口
port 7000
#守護進程
daemonize yes
#工做目錄
dir "/home/redis/data"
#rdb文件
dbfilename "dump-7000.rdb"
#日誌
logfile "7000.log"
#當前節點是Cluster節點
cluster-enabled yes
#故障轉移,節點超時的時間15秒
cluster-node-timeout 15000
#Cluster節點添加本身的配置文件,記錄各個節點的配置
cluster-config-file nodes-7000.conf
#是否須要集羣內全部節點都提供服務
cluster-require-full-coverage no

啓動6個節點:緩存

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

查看是否啓動成功:ruby

ps aux |grep redis
root     21474  0.0  0.0 136992  7580 ?        Ssl  12:01   0:00 ./redis-server *:7000 [cluster]
root     21478  0.0  0.0 136992  7580 ?        Ssl  12:01   0:00 ./redis-server *:7001 [cluster]
root     21482  0.0  0.0 136992  7584 ?        Ssl  12:01   0:00 ./redis-server *:7002 [cluster]
root     21486  0.0  0.0 136992  7580 ?        Ssl  12:01   0:00 ./redis-server *:7003 [cluster]
root     21490  0.0  0.0 136992  7580 ?        Ssl  12:01   0:00 ./redis-server *:7004 [cluster]
root     21494  0.0  0.0 136992  7584 ?        Ssl  12:01   0:00 ./redis-server *:7005 [cluster]

第二步:meet
命令:cluster meet ip port
6個節點相互通訊:數據結構

./redis-cli -p 7000 cluster meet 127.0.0.1 7001
./redis-cli -p 7000 cluster meet 127.0.0.1 7002
./redis-cli -p 7000 cluster meet 127.0.0.1 7003
./redis-cli -p 7000 cluster meet 127.0.0.1 7004
./redis-cli -p 7000 cluster meet 127.0.0.1 7005

查看6個節點是否通訊成功:架構

./redis-cli -p 7000 cluster nodes
2aff05faa516da21635ab6774a981e2efe7538a0 127.0.0.1:7004 master - 0 1562040532277 4 connected
1862242fd6be9f7503e4d5d43e0134660f40753f 127.0.0.1:7005 master - 0 1562040529272 5 connected
0121bd2bafa4d98833d75c2bc1f3e10841c7ac3c 127.0.0.1:7002 master - 0 1562040533281 2 connected
9c0a0dc0709b9e8bb64c2fab459ca4aeeca24142 127.0.0.1:7003 master - 0 1562040530273 3 connected
6b3f6fba363498589633b581015bbb9071f1f8ce 127.0.0.1:7001 master - 0 1562040531275 1 connected
fe3b483f2836110c67faa354b8f9328664fffb2c 127.0.0.1:7000 myself,master - 0 0 0 connected

第三步:指派槽
命令:cluster addslots slot [slot...]
一共6個節點,三主三從,將16384個節點平均分配到三個主節點上:併發

redis-cli -p 7000 cluster addslots {0...5461}
redis-cli -p 7000 cluster addslots {5462...10922}
redis-cli -p 7000 cluster addslots {10923...16383}

編寫腳本:cat addslots.sh負載均衡

start=$1
end=$2
port=$3
for slot in `seq ${start} ${end}`
    do
        echo "slot:${slot}"
        ./redis-cli -p ${port} cluster addslots ${slot}
done

執行腳本分配0-5461節點到7000運維

sh addslots.sh 0 5461 7000

執行腳本分配5462-10922節點到7001

sh addslots.sh 5462 10922 7001

執行腳本分配10923-16383節點到7002

sh addslots.sh 10923 16383 7002

查看:

./redis-cli -p 7000 cluster info
cluster_state:ok(狀態OK)
cluster_slots_assigned:16384(共16384個槽分配成功)
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6(當前認識6個節點)
cluster_size:3(分配槽的節點數3個)
cluster_current_epoch:5
cluster_my_epoch:0
cluster_stats_messages_sent:2576
cluster_stats_messages_received:2576

第四步:設置主從關係
命令:cluster replicate node-id(集羣節點的id,在集羣啓動的時候會進行分配)
讓7003複製7000的節點:

./redis-cli -p 7003 cluster replicate fe3b483f2836110c67faa354b8f9328664fffb2c

讓7004複製7001的節點:

./redis-cli -p 7004 cluster replicate 6b3f6fba363498589633b581015bbb9071f1f8ce

讓7005複製7002的節點:

./redis-cli -p 7005 cluster replicate 0121bd2bafa4d98833d75c2bc1f3e10841c7ac3c

查看是否成功:

./redis-cli -p 7000 cluster nodes
2aff05faa516da21635ab6774a981e2efe7538a0 127.0.0.1:7004 slave 6b3f6fba363498589633b581015bbb9071f1f8ce 0 1562041938444 4 connected
1862242fd6be9f7503e4d5d43e0134660f40753f 127.0.0.1:7005 slave 0121bd2bafa4d98833d75c2bc1f3e10841c7ac3c 0 1562041937441 5 connected
0121bd2bafa4d98833d75c2bc1f3e10841c7ac3c 127.0.0.1:7002 master - 0 1562041936439 2 connected 10923-16383
9c0a0dc0709b9e8bb64c2fab459ca4aeeca24142 127.0.0.1:7003 slave fe3b483f2836110c67faa354b8f9328664fffb2c 0 1562041934435 3 connected
6b3f6fba363498589633b581015bbb9071f1f8ce 127.0.0.1:7001 master - 0 1562041939447 1 connected 5462-10922
fe3b483f2836110c67faa354b8f9328664fffb2c 127.0.0.1:7000 myself,master - 0 0 0 connected 0-5461

方式二:官方工具Ruby安裝
(1)Ruby環境準備
第一步:安裝ruby-2.5.5

./configure -prefix=/home/ruby
make
make install

安裝redis-3.3.0.gem:

gem install -l redis-3.3.0.gem
gem list -- check redis gem

將redis-trib.rb拷貝到可執行文件中

cp /home/redis-3.2.1/src/redis-trib.rb /home/redis/bin/

第二步:配置開啓節點
配置6個節點(分別爲7001-7005):

#端口
port 7000
#守護進程
daemonize yes
#工做目錄
dir "/home/redis/data"
#rdb文件
dbfilename "dump-7000.rdb"
#日誌
logfile "7000.log"
#當前節點是Cluster節點
cluster-enabled yes
#故障轉移,節點超時的時間15秒
cluster-node-timeout 15000
#Cluster節點添加本身的配置文件,記錄各個節點的配置
cluster-config-file nodes-7000.conf
#是否須要集羣內全部節點都提供服務
cluster-require-full-coverage no

啓動6個節點:

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

查看是否啓動成功:

ps aux |grep redis
root     30832  0.0  0.0 136992  7580 ?        Ssl  15:55   0:00 ./redis-server *:7000 [cluster]
root     30836  0.0  0.0 136992  7584 ?        Ssl  15:55   0:00 ./redis-server *:7001 [cluster]
root     30840  0.0  0.0 136992  7584 ?        Ssl  15:55   0:00 ./redis-server *:7002 [cluster]
root     30844  0.0  0.0 136992  7580 ?        Ssl  15:55   0:00 ./redis-server *:7003 [cluster]
root     30848  0.0  0.0 136992  7584 ?        Ssl  15:55   0:00 ./redis-server *:7004 [cluster]
root     30852  0.0  0.0 136992  7580 ?        Ssl  15:55   0:00 ./redis-server *:7005 [cluster]

第三步:每一個主節點設置一個從節點

./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
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
127.0.0.1:7000
127.0.0.1:7001
127.0.0.1:7002
Adding replica 127.0.0.1:7003 to 127.0.0.1:7000
Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
M: ae394a4143dc16ba0b08d94bf78aa5872cf9180b 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
M: a75da4e3b4f89648b53a9fdc66f09fe973db756a 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
M: d7125372a04236517b4b51e996bd3e3d3575a91c 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
S: 6235626a07aa61ac2142db67a2a5b482d268fa52 127.0.0.1:7003
   replicates ae394a4143dc16ba0b08d94bf78aa5872cf9180b
S: e3fc4f3dabb9b2a2275ea4ae1ad4a27d2dbb64bc 127.0.0.1:7004
   replicates a75da4e3b4f89648b53a9fdc66f09fe973db756a
S: 25b08ac647b83eff1f1a3e0539ac302fd8fd6503 127.0.0.1:7005
   replicates d7125372a04236517b4b51e996bd3e3d3575a91c
Can I set the above configuration? (type 'yes' to accept): 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 127.0.0.1:7000)
M: ae394a4143dc16ba0b08d94bf78aa5872cf9180b 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
M: a75da4e3b4f89648b53a9fdc66f09fe973db756a 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
M: d7125372a04236517b4b51e996bd3e3d3575a91c 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
M: 6235626a07aa61ac2142db67a2a5b482d268fa52 127.0.0.1:7003
   slots: (0 slots) master
   replicates ae394a4143dc16ba0b08d94bf78aa5872cf9180b
M: e3fc4f3dabb9b2a2275ea4ae1ad4a27d2dbb64bc 127.0.0.1:7004
   slots: (0 slots) master
   replicates a75da4e3b4f89648b53a9fdc66f09fe973db756a
M: 25b08ac647b83eff1f1a3e0539ac302fd8fd6503 127.0.0.1:7005
   slots: (0 slots) master
   replicates d7125372a04236517b4b51e996bd3e3d3575a91c
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.(全部槽已經成功分配)

查看是否成功:

./redis-cli -p 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:6(6個節點)
cluster_size:3(3個主節點)
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_sent:205
cluster_stats_messages_received:205

查看是否成功:

./redis-cli -p 7000 cluster nodes
d7125372a04236517b4b51e996bd3e3d3575a91c 127.0.0.1:7002 master - 0 1562054528621 3 connected 10923-16383
25b08ac647b83eff1f1a3e0539ac302fd8fd6503 127.0.0.1:7005 slave d7125372a04236517b4b51e996bd3e3d3575a91c 0 1562054529623 6 connected
ae394a4143dc16ba0b08d94bf78aa5872cf9180b 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
a75da4e3b4f89648b53a9fdc66f09fe973db756a 127.0.0.1:7001 master - 0 1562054530624 2 connected 5461-10922
6235626a07aa61ac2142db67a2a5b482d268fa52 127.0.0.1:7003 slave ae394a4143dc16ba0b08d94bf78aa5872cf9180b 0 1562054531627 4 connected
e3fc4f3dabb9b2a2275ea4ae1ad4a27d2dbb64bc 127.0.0.1:7004 slave a75da4e3b4f89648b53a9fdc66f09fe973db756a 0 1562054526616 5 connected

4.集羣伸縮
(1)伸縮原理:槽和數據在節點之間的移動
縮(減一些節點):
伸(加一些節點):
(2)擴容集羣
<1>準備新的節點
集羣模式
配置和其餘節點統一
啓動後是孤兒節點
<2>加入集羣
做用:爲它遷移槽和數據實現擴容,做爲從節點負責故障轉移
<3>遷移槽和數據
1)槽遷移計劃:
平均槽數量:原本有三個槽,每一個槽節點是5460,添加一個槽後,4個槽每一個槽節點是4096
直接遷移:原本有三個槽,每一個槽節點是5460,三個槽每一個槽拿出一份湊成3份給第4個槽
2)遷移數據過程
第一步對目標節點發送:cluster setslot {slot(對應的槽)} importing {sourceNodeId}命令,告訴他,節點要進行導入了,讓目標節點準備導入槽的數據
第二步對源節點發送:cluster setslot {slot(對應的槽)} migrating {targetNodeId}命令,讓源節點準備遷出槽的數據
第三步源節點循環執行:cluster getkeysinslot {slot} {count}命令,每次獲取count個屬於槽的鍵
第四步在源節點上執行migrate {targetIp} {targetPort} key 0 {timeout} 命令把指定key遷移
第五步重複執行步驟3~4直到槽下全部的鍵數據遷移到目標節點
第六步向集羣內全部主節點發送cluster setslot {slot} node {targetNodeId}命令,通知槽分配給目標節點

3)添加從節點操做
第一步:查看當前三主三從結構:

./redis-cli -p 7000 cluster nodes
d7125372a04236517b4b51e996bd3e3d3575a91c 127.0.0.1:7002 master - 0 1562054528621 3 connected 10923-16383
25b08ac647b83eff1f1a3e0539ac302fd8fd6503 127.0.0.1:7005 slave d7125372a04236517b4b51e996bd3e3d3575a91c 0 1562054529623 6 connected
ae394a4143dc16ba0b08d94bf78aa5872cf9180b 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
a75da4e3b4f89648b53a9fdc66f09fe973db756a 127.0.0.1:7001 master - 0 1562054530624 2 connected 5461-10922
6235626a07aa61ac2142db67a2a5b482d268fa52 127.0.0.1:7003 slave ae394a4143dc16ba0b08d94bf78aa5872cf9180b 0 1562054531627 4 connected
e3fc4f3dabb9b2a2275ea4ae1ad4a27d2dbb64bc 127.0.0.1:7004 slave a75da4e3b4f89648b53a9fdc66f09fe973db756a 0 1562054526616 5 connected

第二步:再添加一主一從,添加啓動7006和7007

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

第三步:把7006和7007加入到集羣

./redis-cli -p 7000 cluster meet 127.0.0.1 7006
./redis-cli -p 7000 cluster meet 127.0.0.1 7007

查看當前集羣狀態:

./redis-cli -p 7000 cluster nodes
d7125372a04236517b4b51e996bd3e3d3575a91c 127.0.0.1:7002 master - 0 1562126756992 3 connected 10923-16383
25b08ac647b83eff1f1a3e0539ac302fd8fd6503 127.0.0.1:7005 slave d7125372a04236517b4b51e996bd3e3d3575a91c 0 1562126752986 6 connected
ae394a4143dc16ba0b08d94bf78aa5872cf9180b 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
a75da4e3b4f89648b53a9fdc66f09fe973db756a 127.0.0.1:7001 master - 0 1562126756992 2 connected 5461-10922
0c10d5bc1ad6e17f338c0cdf4370fddb81daea55 127.0.0.1:7006 master - 0 1562126753987 7 connected
6235626a07aa61ac2142db67a2a5b482d268fa52 127.0.0.1:7003 slave ae394a4143dc16ba0b08d94bf78aa5872cf9180b 0 1562126755991 4 connected
43c1f9023e609c0af1228d87a65e4009076cd28a 127.0.0.1:7007 master - 0 1562126754989 0 connected
e3fc4f3dabb9b2a2275ea4ae1ad4a27d2dbb64bc 127.0.0.1:7004 slave a75da4e3b4f89648b53a9fdc66f09fe973db756a 0 1562126751483 5 connected

第四步:把7007和7006作主從複製

./redis-cli -p 7007 cluster replicate 0c10d5bc1ad6e17f338c0cdf4370fddb81daea55

當前集羣狀態:

./redis-cli -p 7000 cluster nodes
d7125372a04236517b4b51e996bd3e3d3575a91c 127.0.0.1:7002 master - 0 1562126831660 3 connected 10923-16383
25b08ac647b83eff1f1a3e0539ac302fd8fd6503 127.0.0.1:7005 slave d7125372a04236517b4b51e996bd3e3d3575a91c 0 1562126837171 6 connected
ae394a4143dc16ba0b08d94bf78aa5872cf9180b 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
a75da4e3b4f89648b53a9fdc66f09fe973db756a 127.0.0.1:7001 master - 0 1562126835167 2 connected 5461-10922
0c10d5bc1ad6e17f338c0cdf4370fddb81daea55 127.0.0.1:7006 master - 0 1562126838172 7 connected
6235626a07aa61ac2142db67a2a5b482d268fa52 127.0.0.1:7003 slave ae394a4143dc16ba0b08d94bf78aa5872cf9180b 0 1562126836169 4 connected
43c1f9023e609c0af1228d87a65e4009076cd28a 127.0.0.1:7007 slave 0c10d5bc1ad6e17f338c0cdf4370fddb81daea55 0 1562126833164 7 connected
e3fc4f3dabb9b2a2275ea4ae1ad4a27d2dbb64bc 127.0.0.1:7004 slave a75da4e3b4f89648b53a9fdc66f09fe973db756a 0 1562126832662 5 connected

第五步:遷移槽:

執行./redis-trib.rb reshard 127.0.0.1:7000
#遷移多少個槽?
How many slots do you want to move (from 1 to 16384)?4096
#但願給哪一個ID加槽
What is the receiving node ID?0c10d5bc1ad6e17f338c0cdf4370fddb81daea55
#填入all就是拿其餘的節點分配給這個節點
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
#是否要執行?
Do you want to proceed with the proposed reshard plan (yes/no)?yes

查看遷移結果

./redis-cli -p 7000 cluster nodes | grep master
d7125372a04236517b4b51e996bd3e3d3575a91c 127.0.0.1:7002 master - 0 1562127237014 3 connected 12288-16383
ae394a4143dc16ba0b08d94bf78aa5872cf9180b 127.0.0.1:7000 myself,master - 0 0 1 connected 1365-5460
a75da4e3b4f89648b53a9fdc66f09fe973db756a 127.0.0.1:7001 master - 0 1562127238017 2 connected 6827-10922
0c10d5bc1ad6e17f338c0cdf4370fddb81daea55 127.0.0.1:7006 master - 0 1562127236012 7 connected 0-1364 5461-6826 10923-12287

(3)縮容集羣:下線節點,首先判斷是否有槽,有槽遷移槽到其餘節點,沒有槽通知其它節點忘記下線節點,關閉節點
<1>下線遷移槽
原本有四個槽,每一個槽節點是6379,下線一個槽後,把下線的槽節點平均分配給其它三個節點
<2>忘記節點
cluster forget {downNodeId}
<3>關閉節點
(4)縮容從節點操做
第一步:查看當前節點狀態4主4從

./redis-cli -p 7000 cluster nodes
d7125372a04236517b4b51e996bd3e3d3575a91c 127.0.0.1:7002 master - 0 1562128014673 3 connected 12288-16383
25b08ac647b83eff1f1a3e0539ac302fd8fd6503 127.0.0.1:7005 slave d7125372a04236517b4b51e996bd3e3d3575a91c 0 1562128013170 6 connected
ae394a4143dc16ba0b08d94bf78aa5872cf9180b 127.0.0.1:7000 myself,master - 0 0 1 connected 1365-5460
a75da4e3b4f89648b53a9fdc66f09fe973db756a 127.0.0.1:7001 master - 0 1562128013671 2 connected 6827-10922
0c10d5bc1ad6e17f338c0cdf4370fddb81daea55 127.0.0.1:7006 master - 0 1562128016177 7 connected 0-1364 5461-6826 10923-12287
6235626a07aa61ac2142db67a2a5b482d268fa52 127.0.0.1:7003 slave ae394a4143dc16ba0b08d94bf78aa5872cf9180b 0 1562128019683 4 connected
43c1f9023e609c0af1228d87a65e4009076cd28a 127.0.0.1:7007 slave 0c10d5bc1ad6e17f338c0cdf4370fddb81daea55 0 1562128018680 7 connected
e3fc4f3dabb9b2a2275ea4ae1ad4a27d2dbb64bc 127.0.0.1:7004 slave a75da4e3b4f89648b53a9fdc66f09fe973db756a 0 1562128017679 5 connected

第二步:把7006的槽第一段0-1364數據遷移到7000

./redis-trib.rb reshard --from 0c10d5bc1ad6e17f338c0cdf4370fddb81daea55 --to ae394a4143dc16ba0b08d94bf78aa5872cf9180b --slots 1366 127.0.0.1:7006

第三步:把7006的槽第二段5461-6826數據遷移到7001

./redis-trib.rb reshard --from 0c10d5bc1ad6e17f338c0cdf4370fddb81daea55 --to a75da4e3b4f89648b53a9fdc66f09fe973db756a --slots 1365 127.0.0.1:7006

第四步:把7006的槽第三段10923-12287數據遷移到7002

./redis-trib.rb reshard --from 0c10d5bc1ad6e17f338c0cdf4370fddb81daea55 --to d7125372a04236517b4b51e996bd3e3d3575a91c --slots 1364 127.0.0.1:7006

查看當前節點

./redis-cli -p 7000 cluster nodes
d7125372a04236517b4b51e996bd3e3d3575a91c 127.0.0.1:7002 master - 0 1562128677014 10 connected 10923-12286 12288-16383
25b08ac647b83eff1f1a3e0539ac302fd8fd6503 127.0.0.1:7005 slave d7125372a04236517b4b51e996bd3e3d3575a91c 0 1562128681022 10 connected
ae394a4143dc16ba0b08d94bf78aa5872cf9180b 127.0.0.1:7000 myself,master - 0 0 8 connected 0-5461
a75da4e3b4f89648b53a9fdc66f09fe973db756a 127.0.0.1:7001 master - 0 1562128683026 9 connected 5462-10922
0c10d5bc1ad6e17f338c0cdf4370fddb81daea55 127.0.0.1:7006 master - 0 1562128933545 7 connected
6235626a07aa61ac2142db67a2a5b482d268fa52 127.0.0.1:7003 slave ae394a4143dc16ba0b08d94bf78aa5872cf9180b 0 1562128680018 8 connected
43c1f9023e609c0af1228d87a65e4009076cd28a 127.0.0.1:7007 slave 0c10d5bc1ad6e17f338c0cdf4370fddb81daea55 0 1562128682525 7 connected
e3fc4f3dabb9b2a2275ea4ae1ad4a27d2dbb64bc 127.0.0.1:7004 slave a75da4e3b4f89648b53a9fdc66f09fe973db756a 0 1562128679017 9 connected
讓集羣中的節點忘記7006和7007

第五步:先下從節點7007

./redis-trib.rb del-node 127.0.0.1:7000 43c1f9023e609c0af1228d87a65e4009076cd28a
>>> Removing node 43c1f9023e609c0af1228d87a65e4009076cd28a from cluster 127.0.0.1:7000
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

第六步:在下主節點7006

./redis-trib.rb del-node 127.0.0.1:7000 0c10d5bc1ad6e17f338c0cdf4370fddb81daea55
>>> Removing node 0c10d5bc1ad6e17f338c0cdf4370fddb81daea55 from cluster 127.0.0.1:7000
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

查看縮容結果:

./redis-cli -p 7000 cluster nodes
d7125372a04236517b4b51e996bd3e3d3575a91c 127.0.0.1:7002 master - 0 1562129022228 10 connected 10923-16383
25b08ac647b83eff1f1a3e0539ac302fd8fd6503 127.0.0.1:7005 slave d7125372a04236517b4b51e996bd3e3d3575a91c 0 1562129024734 10 connected
ae394a4143dc16ba0b08d94bf78aa5872cf9180b 127.0.0.1:7000 myself,master - 0 0 8 connected 0-5461
a75da4e3b4f89648b53a9fdc66f09fe973db756a 127.0.0.1:7001 master - 0 1562129022730 9 connected 5462-10922
6235626a07aa61ac2142db67a2a5b482d268fa52 127.0.0.1:7003 slave ae394a4143dc16ba0b08d94bf78aa5872cf9180b 0 1562129023733 8 connected
e3fc4f3dabb9b2a2275ea4ae1ad4a27d2dbb64bc 127.0.0.1:7004 slave a75da4e3b4f89648b53a9fdc66f09fe973db756a 0 1562129021729 9 connected

5.客戶端路由
(1)moved重定向
(2)ask重定向
(3)smart客戶端
6.集羣原理

7.開發運維常見問題
(1)集羣完整性
是否須要集羣內全部節點都提供服務
cluster-require-full-coverage默認爲yes
問題1:集羣中16384個槽所有可用:保證集羣完整性
問題2:節點故障或者正在作故障轉移
總結:大多數業務沒法容忍,建議爲no
(2)帶寬消耗
官方建議:1000個節點
問題:PING/PONG消息:
問題:不容忽視的帶寬消耗:
三個方面:
消息發送頻率:slots槽數(2KB空間)和整個集羣1/10的狀態數據(10個節點狀態數據約1KB)
消息數據量:節點發現與其它節點最後通訊時間超過cluster-node-timeout/2時會直接發送ping消息
節點部署的機器規模:集羣分佈的機器越多且每臺機器劃分節點數越均勻,則集羣內總體的可用帶寬越高
優化:
避免「大」集羣:避免多業務使用一個集羣,大業務能夠多集羣
cluster-node-timeout:帶寬和故障轉移速度的均衡
儘可能均勻分配到多機器上:保證高可用和帶寬
(3)Pub/Sub廣播
問題:publish在集羣每一個節點廣播:加劇帶寬
解決:單獨「走」一套Redis Sentinel
(4)數據傾斜
<1>數據傾斜:內存不均
可能一:節點和槽分配不均
命令查看節點,槽,鍵值分佈:redis-trib.rb info ip:port
使用打印主節點信息:
./redis-trib.rb info 127.0.0.1:7000
127.0.0.1:7000 (ae394a41...) -> 0 keys | 5462 slots | 1 slaves.
127.0.0.1:7002 (d7125372...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7001 (a75da4e3...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
可能二:不一樣槽對應鍵值數量差別較大
CRC16正常狀況下比較均勻
可能存在hash_tag
命令獲取槽對應鍵值個數:cluster countkeysinslot {slot}
可能三:包含bigkey
例如大字符串,幾百萬的元素的hash,set等
從節點:redis-cli --bigkeys
優化:優化數據結構
可能四:內存相關配置不一致
hash-max-ziplist-value,set-max-intset-entries等
優化:按期「檢查」配置一致性
<2>請求傾斜:熱點
熱點key:重要的key或者bigkey
優化:
第一:避免bigkey
第二:熱鍵不要用hash_tag
第三:當一致性不高時,可用本地緩存+MQ
(5)集羣讀寫分離
<1>只讀鏈接:集羣模式的從節點不接受任何讀寫請求
-重定向到負責槽的主節點
-readonly命令能夠讀:鏈接級別命令
實現:
在7000主寫入一條hello world
./redis-cli -c -p 7000
127.0.0.1:7000> set hello world
OK
在從7003執行讀取,跳轉到主7000讀取
./redis-cli -c -p 7003
127.0.0.1:7003> get hello
-> Redirected to slot [866] located at 127.0.0.1:7000
"world"
重新進入從7003使用readonly命令後能夠直接從7003讀取
./redis-cli -c -p 7003
127.0.0.1:7003> readonly
OK
127.0.0.1:7003> get hello
"world"
<2>讀寫分離:更加複雜
-一樣的問題:複製延遲,讀取過時數據,從節點故障
-修改客戶端:cluster slaves {nodeId}
(6)數據遷移-離線/在線遷移
<1>官方遷移工具:redis-trib.rb import
-只能從單機遷移到集羣
-不支持在線遷移:source須要停寫
-不支持斷電續傳
-單線程遷移:影響速度
<2>在線遷移:
-惟品會redis-migrate-tool
-豌豆莢:redis-port
(7)集羣vs單機
<1>集羣限制:
-key批量操做支持有限:例如mget,mset必須在一個slot(槽)
-key事務和Lua支持有限:操做的key必須在一個節點上
-key是數據分區的最小粒度:不支持bigkey分區
-不支持多個數據庫:集羣模式下只有一個db 0
-複製只支持一層:不支持樹形複製結構
<2>分佈式redis不必定好
第一:Redis Cluster:知足容量和性能的擴展性,不少業務「不須要」
-大多數時客戶端性能會「下降」
-命令沒法跨節點使用:mget,keys,scan,flush,sinter等
-Lua和事務沒法跨節點使用
-客戶端維護更復雜:SDK和應用自己消耗(例如更多的鏈接池)
第二:不少場景Redis Sentinel已經足夠好了
8.集羣總結:(1)Redis cluster數據分區規則採用虛擬槽方式(16384個槽),每一個節點負責一部分槽和相關數據,實現數據和請求的負載均衡(2)搭建集羣劃分四個步驟:準備節點,節點握手,分配槽,複製。redis-trib.rb工具用於快速搭建集羣。(3)集羣伸縮經過在節點之間移動槽和相關數據實現-擴容時根據槽遷移計劃把槽從源節點遷移到新節點-收縮時若是下線的節點有負責的槽須要遷移到其它節點,再經過cluster forget命令讓集羣內全部的節點忘記被下線節點。(4)使用smart客戶端操做集羣達到通訊效率最大化,客戶端內部負責計算維護鍵->槽->節點的映射,用於快速定位到目標節點。(5)集羣自動故障轉移過程分爲故障發現和節點恢復。節點下線分爲主觀下線和客觀下線,當超過半數主節點認爲故障節點爲主觀下線時標記它爲客觀下線狀態。從節點負責對客觀下線的主節點觸發故障恢復流程,保證集羣的可用性(6)開發運維常見問題包括:超大規模集羣帶寬消耗,pub/sub廣播問題,集羣傾斜問題,單機和集羣對比等

相關文章
相關標籤/搜索