什么是redis-cluster:
Redis Cluster 是一种分布式去中心化的运行模式,是在 Redis 3.0 版本中推出的 Redis 集群方案,它将数据分布在不同的服务器上,以此来降低系统对单主节点的依赖,从而提高 Redis 服务的读写性能。
Redis Cluster是如何将数据分片的?
Redis cluster 采用虚拟槽分区,所有的键根据哈希函数映射到0~16383整数槽内,计算公式:Slot=CRC16(key)&16384。每个节点负责维护一部分槽以及槽所映射的键值数据。
redis群集中的每个节点都负责哈希槽的子集,例如,您可能拥有一个包含3个节点的群集,其中:
节点A包含从0到5500的散列槽。
节点B包含从5501到11000的散列槽。
节点C包含从11001到16383的散列槽。
集群选举原理分析(ping-pong机制)
选举流程:
当slave发现自己的master变为FAIL状态时,便尝试发起选举,以期成为新的master。由于挂掉的master可能会有多个slave,从而存在多个slave竞争成为master节点的过程, 其过程如下:
1.slave发现自己的master变为FAIL(失败)
2.将自己记录的集群currentEpoch(选举轮次标记)加1,并广播信息给集群中其他节点
3.其他节点收到该信息,只有master响应,判断请求者的合法性,并发送结果
4.尝试选举的slave收集master返回的结果,收到超过半数master的同意后变成新Master
5.广播Pong消息通知其他集群节点。
如果这次选举不成功,比如三个小的主从A,B,C组成的集群,A的master挂了,A的两个小弟发起选举,结果B的master投给A的小弟A1,C的master投给了A的小弟A2,这样就会发起第二次选举,选举轮次标记+1继续上面的流程。
redis-cluster集群搭建
集群环境
主机 | IP | 角色 |
centos1 | 192.168.100.1 | Master1 |
centos1 | 192.168.100.11 | Slave1 |
centos2 | 192.168.100.2 | Master2 |
centos2 | 192.168.100.22 | Slave2 |
centos3 | 192.168.100.3 | Master3 |
centos3 | 192.168.100.33 | Slave3 |
分别修改六台节点的主机名
[root@locathost ~]# hostnamectl set-hostname master1
[root@locathost ~]# hostnamectl set-hostname slave1
[root@locathost ~]# hostnamectl set-hostname master2
[root@locathost ~]# hostnamectl set-hostname slave2
[root@locathost ~]# hostnamectl set-hostname master3
[root@locathost ~]# hostnamectl set-hostname slave3
分别在六台节点添加IP与主机名映射
[root@master1 ~]# vim /etc/hosts
192.168.100.1 master1
192.168.100.11 slave1
192.168.100.2 master2
192.168.100.22 slave2
192.168.100.3 master3
192.168.100.33 slave3
修改配置文件
[root@master1 ~]# vim /usr/local/redis/bin/redis.conf
daemonize yes ##redis后台运行
bind 0.0.0.0 ##监听所有地址
pidfile /var/run/redis_6379.pid ##pid文件对应端口
logfile "/var/log/redis/redis_6379.log" ##日志存放目录
dir "/usr/local/redis/var" ##数据存放目录
requirepass 123123 ##设置redis登录密码
protected-mode no ##关闭保护模式
cluster-enabled yes ##开启集群,把注释去掉
cluster-config-file nodes-6379.conf ##集群的配置,配置文件首次启动自动生成
cluster-node-timeout 15000 ##请求超时时间
appendonly yes ##开启AOF
将配置文件发给其他节点
[root@master1 ~]# scp /usr/local/redis/bin/redis.conf root@192.168.100.2:/usr/local/redis/bin/
[root@master1 ~]# scp /usr/local/redis/bin/redis.conf root@192.168.100.3:/usr/local/redis/bin/
[root@master1 ~]# scp /usr/local/redis/bin/redis.conf root@192.168.100.11:/usr/local/redis/bin/
[root@master1 ~]# scp /usr/local/redis/bin/redis.conf root@192.168.100.22:/usr/local/redis/bin/
[root@master1 ~]# scp /usr/local/redis/bin/redis.conf root@192.168.100.33:/usr/local/redis/bin/
创建数据存放目录
[root@master1 ~]# mkdir /usr/local/redis/var
设置开启自启
[root@master1 ~]# systemctl enable redis --now
查看端口号
[root@master1 ~]# netstat -anptu | grep 63
tcp 0 0 0.0.0.0:16379 0.0.0.0:* LISTEN 2614/redis-server 0
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 2614/redis-server 0
创建cluster集群
[root@master1 ~]# redis-cli --cluster create --cluster-replicas 1 -a 123123 192.168.100.1:6379 192.168.100.2:6379 192.168.100.3:6379 192.168.100.11:6379 192.168.100.22:6379 192.168.100.33:6379 ##-a表示redis集群登录密码
测试:
[root@master1 ~]# redis-cli -h 192.168.100.1 -p 6379 -a 123123 -c #-c表示激活集群模式
192.168.100.1:6379> set name zhangsan
-> Redirected to slot [5798] located at 192.168.100.2:6379
OK
192.168.100.2:6379> keys *
1) "name"
在192.168.100.1上创建一个key通过哈希算法得到一个值载除16384根据这个数的值取决于存放在那个节点上
节点A:0-5460
节点B:5461-10922
节点C:10923-16383
[root@master1 ~]# redis-cli -h 192.168.100.1 -p 6379 -a 123123 -c
192.168.100.1:6379> keys *
(empty array)
虽然在192.168.100.1上看不见这个key但可以通过get方式获取到这个值
192.168.100.1:6379> get name
-> Redirected to slot [5798] located at 192.168.100.2:6379
"zhangsan"
查看集群状态
[root@master1 ~]# redis-cli --cluster check 192.168.100.1:6379 -a 123123
redis-cluster扩容
修改主机名
[root@localhost ~]# hostnamectl set-hostname master4
[root@localhost ~]# hostnamectl set-hostname slave4
修改hosts文件(在其他节点也加入其主机名ip)
[root@slave4 ~]# vim /etc/hosts
192.168.100.1 master1
192.168.100.11 slave1
192.168.100.2 master2
192.168.100.22 slave2
192.168.100.3 master3
192.168.100.33 slave3
192.168.100.4 master4
192.168.100.44 slave4
将节点master4:192.168.100.4:6379加入集群
[root@master1 ~]# redis-cli --cluster add-node 192.168.100.4:6379 192.168.100.1:6379 -a 123123
查看集群状态192.168.100.4:6379和192.168.100.44:6379添加成功,但是没有卡槽
为192.168.100.4:6379添加卡槽
[root@master1 ~]# redis-cli --cluster reshard 192.168.100.4:6379 -a 123123
##选择位置输入槽位
##选择位置输入master4 节点id
为192.168.100.4:6379添加从节点
[root@master1 ~]# redis-cli --cluster add-node 192.168.100.44:6379 192.168.100.1:6379 --cluster-slave --cluster-master-id 9a07430415ff9e747d62bc15b2e4c9f0242181ac -a 123123
格式:
redis-cli --cluster add-npde 从节点ip和端口号 集群master节点ip和端口号 --cluster-slave --cluster-master-id 集群master节点id号 -a 123123
查看集群状态
[root@master1 ~]# redis-cli --cluster check 192.168.100.1:6379 -a 123123
缩容
[root@master1 ~]# redis-cli --cluster reshard 192.168.100.1:6379 --cluster-from 4520dbbb01288acaacd3a4fdea4e880f544c1335 --cluster-to 9a07430415ff9e747d62bc15b2e4c9f0242181ac --cluster-slots 4096 -a 123123
格式:redis-cli --cluster reshard 集群masterip:端口号 --cluster-from 扩容的master id号
--cluster-to 集群master id号 --cluster-slots 槽位 -a 密码
查看缩容后节点信息
[root@master1 ~]# redis-cli --cluster check 192.168.100.1:6379 -a 123123
可以看到192.168.100.1:6379 的槽位变成了3个
删除节点
[root@master1 ~]# redis-cli --cluster del-node 192.168.100.4:6379 4520dbbb01288acaacd3a4fdea4e880f544c1335 -a 123123
[root@master1 ~]# redis-cli --cluster del-node 192.168.100.44:6379 f630821463053c2a4cd54c408fc30c8323b03217 -a 123123
槽位不均衡,可以使用以下方法解决
[root@master1 ~]# redis-cli --cluster rebalance --cluster-use-empty-masters 192.168.100.1:6379 -a 123123
再次查看发现槽位恢复