分片集群

主从和哨兵解决了高可用/高并发读问题,但是依然有两个问题没有解决
1.海量数据存储问题
2.高并发写问题
使用分片集群可以解决以上问题,分片集群特征:
1.集群中有多个master,每个master保存不同数据
2.每个master可以有多个slave节点
3.master之间通过ping监测彼此健康状态
4.客户端请求可以访问集群任意节点,最终转发至正确节点
分片集群部署
#创建6个目录,分别用于存放主和从redis
[root@redis opt]# mkdir 700{1..3} 800{1..3}
#准备一个配置文件模板
[root@redis opt]# cat redis.conf
port 6379
#开户集群功能
cluster-enabled yes
#集群配置文件名称,不需要创建,由redis自己维护
cluster-config-file /opt/6379/nodes.conf
#节点心跳失败的超时时间(毫秒)
cluster-node-timeout 5000
#持久化文件存放目录
dir /opt/6379
#绑定地址
bind 0.0.0.0
#redis后台运行
daemonize yes
#注册实例IP
replica-announce-ip 192.168.115.129
#保护模式
protected-mode no
#数据库数量
databases 1
#日志
logfile /opt/6379/redis.log

#将模板文件复制到6个目录
[root@redis opt]# printf '%s\n' 700{1..3} 800{1..3} | xargs -I {} -n1 cp redis.conf {}
#修改目录中模板的信息
[root@redis opt]# printf '%s\n' 700{1..3} 800{1..3} | xargs -I {} -n1 sed -i 's/6379/{}/g' {}/redis.conf

#----启动集群,配置了后台启动模式,可以直接启动服务
[root@redis opt]# printf '%s\n' 700{1..3} 800{1..3} | xargs -I {} -n1 redis-server {}/redis.conf
#查看启动情况
[root@redis opt]# ps aux | grep redis
root       1405  0.2  0.1 162520  9924 ?        Ssl  08:28   0:00 redis-server 0.0.0.0:7001 [cluster]
root       1411  0.2  0.1 162520  9924 ?        Ssl  08:28   0:00 redis-server 0.0.0.0:7002 [cluster]
root       1417  0.1  0.1 162520  9928 ?        Ssl  08:28   0:00 redis-server 0.0.0.0:7003 [cluster]
root       1423  0.2  0.1 162520  9924 ?        Ssl  08:28   0:00 redis-server 0.0.0.0:8001 [cluster]
root       1429  0.1  0.1 162520  9928 ?        Ssl  08:28   0:00 redis-server 0.0.0.0:8002 [cluster]
root       1435  0.2  0.1 162520  9932 ?        Ssl  08:28   0:00 redis-server 0.0.0.0:8003 [cluster]
集群配置
[root@redis opt]# redis-cli --cluster create --cluster-replicas 1 192.168.115.129:7001 192.168.115.129:7002 192.168.115.129:7003 192.168.115.129:8001 192.168.115.129:8002 192.168.115.129:8003 
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.115.129:8002 to 192.168.115.129:7001
Adding replica 192.168.115.129:8003 to 192.168.115.129:7002
Adding replica 192.168.115.129:8001 to 192.168.115.129:7003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 7d0f11e795f29a5b292260c652cb9888315236eb 192.168.115.129:7001
   slots:[0-5460] (5461 slots) master
M: c88710da8e4f9c2d6d42b53bae00ae4f3d23e2f0 192.168.115.129:7002
   slots:[5461-10922] (5462 slots) master
M: 6be90c559096c93bbad3745238719b9d04384acc 192.168.115.129:7003
   slots:[10923-16383] (5461 slots) master
S: 1b42d9aa88fdf1adb079850a4e7b4c173108bd6a 192.168.115.129:8001
   replicates 6be90c559096c93bbad3745238719b9d04384acc
S: 89e2904481fae67e5211e15dfe56d4d585eedfc7 192.168.115.129:8002
   replicates 7d0f11e795f29a5b292260c652cb9888315236eb
S: 652895c1121e07d1068ac3a4efca9bbaf5f32776 192.168.115.129:8003
   replicates c88710da8e4f9c2d6d42b53bae00ae4f3d23e2f0
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 192.168.115.129:7001)
M: 7d0f11e795f29a5b292260c652cb9888315236eb 192.168.115.129:7001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 6be90c559096c93bbad3745238719b9d04384acc 192.168.115.129:7003
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: c88710da8e4f9c2d6d42b53bae00ae4f3d23e2f0 192.168.115.129:7002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 1b42d9aa88fdf1adb079850a4e7b4c173108bd6a 192.168.115.129:8001
   slots: (0 slots) slave
   replicates 6be90c559096c93bbad3745238719b9d04384acc
S: 652895c1121e07d1068ac3a4efca9bbaf5f32776 192.168.115.129:8003
   slots: (0 slots) slave
   replicates c88710da8e4f9c2d6d42b53bae00ae4f3d23e2f0
S: 89e2904481fae67e5211e15dfe56d4d585eedfc7 192.168.115.129:8002
   slots: (0 slots) slave
   replicates 7d0f11e795f29a5b292260c652cb9888315236eb
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

#查看集群信息
[root@redis opt]# redis-cli -p 7001 cluster nodes
6be90c559096c93bbad3745238719b9d04384acc 192.168.115.129:7003@17003 master - 0 1668087308605 3 connected 10923-16383
c88710da8e4f9c2d6d42b53bae00ae4f3d23e2f0 192.168.115.129:7002@17002 master - 0 1668087309369 2 connected 5461-10922
1b42d9aa88fdf1adb079850a4e7b4c173108bd6a 192.168.115.129:8001@18001 slave 6be90c559096c93bbad3745238719b9d04384acc 0 1668087309000 3 connected
652895c1121e07d1068ac3a4efca9bbaf5f32776 192.168.115.129:8003@18003 slave c88710da8e4f9c2d6d42b53bae00ae4f3d23e2f0 0 1668087309688 2 connected
7d0f11e795f29a5b292260c652cb9888315236eb 192.168.115.129:7001@17001 myself,master - 0 1668087307000 1 connected 0-5460
89e2904481fae67e5211e15dfe56d4d585eedfc7 192.168.115.129:8002@18002 slave 7d0f11e795f29a5b292260c652cb9888315236eb 0 1668087309000 1 connected
#
`Redis会把每个master节点映射到0-16383共16384个插槽(hash slot)上,
数据key不是与节点绑定,而是与插槽绑定,redis根据key的有效部分计算插槽值,分两种情况:
1.key中包含{},且{}中至少包含1个字符,{}中的部分是有效部分
2.key中不包含{},整个key都是有效部分
如key是name,那么就根据name计算,如果是{itcast}num,则根据itcast计算,计算方式利用CRC16算法获得1个hash值 ,然后对16384取余,得到的结果就是slot值。
`
[root@redis opt]# redis-cli -c -p 7001
127.0.0.1:7001> set num 123
OK
127.0.0.1:7001> set a 1
-> Redirected to slot [15495] located at 192.168.115.129:7003
OK
192.168.115.129:7003> get a
"1"
192.168.115.129:7003> get num
-> Redirected to slot [2765] located at 192.168.115.129:7001
"123"
集群中添加新节点
1.启动一个新的redis实例,端口7004
2.添加7004到之前的集群,作为一个master节点
3.给7004节点分配插槽,使得num这个key可以存储到7004实例
#创建目录并修改配置文件
[root@redis opt]# mkdir 7004
[root@redis opt]# cp redis.conf 7004/
[root@redis opt]# sed -i 's/6379/7004/g' 7004/redis.conf
[root@redis opt]# cat 7004/redis.conf 
port 7004
#开户集群功能
cluster-enabled yes
#集群配置文件名称,不需要创建,由redis自己维护
cluster-config-file /opt/7004/nodes.conf
#节点心跳失败的超时时间(毫秒)
cluster-node-timeout 5000
#持久化文件存放目录
dir /opt/7004
#绑定地址
bind 0.0.0.0
#redis后台运行
daemonize yes
#注册实例IP
replica-announce-ip 192.168.115.129
#保护模式
protected-mode no
#数据库数量
databases 1
#日志
logfile /opt/7004/redis.log
[root@redis opt]# redis-server 7004/redis.conf
#将7004添加至集群
[root@redis opt]# redis-cli --cluster add-node 192.168.115.129:7004 192.168.115.129:7001
>>> Adding node 192.168.115.129:7004 to cluster 192.168.115.129:7001
>>> Performing Cluster Check (using node 192.168.115.129:7001)
M: 7d0f11e795f29a5b292260c652cb9888315236eb 192.168.115.129:7001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 6be90c559096c93bbad3745238719b9d04384acc 192.168.115.129:7003
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: c88710da8e4f9c2d6d42b53bae00ae4f3d23e2f0 192.168.115.129:7002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 1b42d9aa88fdf1adb079850a4e7b4c173108bd6a 192.168.115.129:8001
   slots: (0 slots) slave
   replicates 6be90c559096c93bbad3745238719b9d04384acc
S: 652895c1121e07d1068ac3a4efca9bbaf5f32776 192.168.115.129:8003
   slots: (0 slots) slave
   replicates c88710da8e4f9c2d6d42b53bae00ae4f3d23e2f0
S: 89e2904481fae67e5211e15dfe56d4d585eedfc7 192.168.115.129:8002
   slots: (0 slots) slave
   replicates 7d0f11e795f29a5b292260c652cb9888315236eb
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 192.168.115.129:7004 to make it join the cluster.
[OK] New node added correctly.
#插槽分配
[root@redis opt]# redis-cli --cluster reshard 192.168.115.129:7001
... ...
How many slots do you want to move (from 1 to 16384)? 3000
What is the receiving node ID? fc73c2f291057bbfe2a49bc0c796ae
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the has
  Type 'done' once you entered all the source nodes IDs.
Source node #1: 7d0f11e795f29a5b292260c652cb9888315236eb
Source node #2: done
[root@redis opt]# redis-cli -c -p 7001
127.0.0.1:7001> set num 10
-> Redirected to slot [2765] located at 192.168.115.129:7004
OK
192.168.115.129:7004> get num
"10"
#删除节点(有数据的节点不能直接删除,需要将数据先移出)
#如要删除的节点中有slot,则需要先将slot移动至其它节点[redis-cli --cluster reshard ip:port]
[root@redis opt]# redis-cli --cluster del-node 192.168.115.129:7004 fc73c2f291057bbfe2a49bc0c796aeddaf707532
故障转移
#分片集群自动具有故障转移功能,当集群中有一个master宕机会发生什么?
1.首先是该实例与其它实例失去连接
2.然后是疑似宕机
3.最后确认下线,自动提升一个slave为新的master
数据迁移
利用cluster failover命令可以手动让集群中的某个master宕机,切换到执行cluster failover命令的这个slave节点,实现无感知的数据迁移。