上一篇:https://blog.csdn.net/fengxianaa/article/details/124409445
1. 介绍
redis 主从和哨兵机制是为了解决 高可用、高并发读 的问题,但是不能解决:
- 高并发写
- 海量数据存储
使用 redis cluster 可以解决上面的问题,特征
- 有多个 master ,每个都保存一部分的数据,所以只要 master 足够多,可以存无限数据
- 每个 master 都有多个 slave 节点,master 宕机,slave顶上
- 各个master之间通过ping,检测彼此的健康状态
- 客户端随意访问任何一个 master,最后请求都会被路由到正确的master上
2. 搭建
我们搭建有 3 个 master 的集群,每个 master 只有一个 slave
7001、7002、7003 是 master
8001、8002、8003 是 salve
首先,清除之前的配置,再 /root/soft/redis 目录只保留下面的文件
创建目录
新建redis.conf,以 7001 为例:
# 端口号
port 7001
# 开启集群模式
cluster-enabled yes
# 集群内部的配置文件,不需要创建,由redis自己维护
cluster-config-file /root/soft/redis/7001/nodes.conf
# 节点心跳失败的超时时间,单位:毫秒,master宕机的话就会触发主备切换,slave宕机就不会提供服务
cluster-node-timeout 5000
# 持久化目录
dir /root/soft/redis/7001
# 绑定ip
bind 192.168.56.103 127.0.0.1
# 后台运行
daemonize yes
# 注册实例ip
replica-announce-ip 192.168.56.103
# 关闭保护模式
protected-mode no
# 数据库数量
databases 1
# 日志文件
logfile /root/soft/redis/7001/redis.log
把这个文件放到 /root/soft/redis 目录
将上面的文件复制到每个文件夹中:echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf
修改每个目录下的redis.conf,将其中的 7001 修改为跟目录一致
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/7001/{}/g' {}/redis.conf
启动服务:printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf
关闭所有进程:ps -ef | grep redis | awk '{print $2}' | xargs kill
或者:printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-cli -p {} shutdown
3. 集群
执行命令:
redis-cli --cluster create --cluster-replicas 1 192.168.56.103:7001 192.168.56.103:7002 192.168.56.103:7003 192.168.56.103:8001 192.168.56.103:8002 192.168.56.103:8003
上面这个命令,只需要在第一次启动集群的时候使用,如果集群关闭后再次重启,只要执行:
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf
命令解释:
- redis-cli --cluster create :开始创建集群
- --cluster-replicas 1:指定每个 master 的 salve 数量为 1,
- 这时 节点总数 ➗ (replicas + 1)就得到master的数量,其他都是 slave 节点,随机分给某个master
结果:
可以看到 8001 挂到了7002 上,8002 挂到了7003 上,8003 挂到了7001 上,
在这里上图红框出输入 yes,回车:
集群创建成功
查看集群状态:redis-cli -p 7001 cluster nodes
4. hash slot
1. 介绍
在搭建集群的时候会发现有些 slots 信息,这就是 hash slot,也叫:散列插槽,一共有 16384 个
作用:在 redis cluster 模式下,会给每一个 master 分配一些 hash slot,在 set 的时候,
先对key计算,得出一个插槽值,最终确定把数据放到哪个 master上
在计算插槽值时,redis 会根据 key的有效部分计算:
- key中没有"{}",那么整个key都是有效部分
- key中有"{}",那么"{}"中的才是有效部分
例如:key 是 test,那么根据 test 计算,如果key是 {feng}test,就根据 feng 计算,
计算方式:利用CRC16算法得到一个 hash 值,然后对 16384 取余
2. 演示
使用 redis-cli 连接集群,注意:需要加上 -c
设置几个值
上图红框出,执行 set test hahaha 命令,对 test 计算,得出的 slot 是 6918,所以把它放到 7002 上,而且,命令行也切换到了 7002 节点
再次执行 get fengxiansheng 命令
对 fengxiansheng 计算,得出的 slot 是 1605,所以切换到 7001 节点,记住这个值,后面要用到
3. 将同一类数据放到一个 master 上
让这类数据的 key 都加上一个统一的前缀,比如:{fengxiansheng}
5. 集群伸缩
1. 添加 master
向集群中添加 master ,需要使用 add-node 命令
解释:
- new_host:new_port: 需要加入集群的ip和端口
- existing_host:existing_port: 已经在集群中存在的ip和端口
- --cluster-slave: 作为一个从节点加入集群
- --cluster-master-id <arg>:指定作为哪一个 master 的 salve
- 注意:没有后两个参数,新加的节点默认是 master
再 /root/soft/redis 目录中,新建 7004,并设置redis.conf(此处省略)
启动 7004
但,7004 还没有加入集群,执行下面命令,加进来
可以看到,已经添加成功,再查看一下集群状态
但是,7004 目前没有分配插槽,下面分配一下
2. 分配 slot
使用 reshard 命令
提示要移动多少个 slot,我们移动 2000个
又问,移动到哪个节点?我们移动到 7004 节点,从上图的红框出可以找到 7004 的node ID
- all: 从所有主节点(7001,7002,3003)中分别抽取相应的槽数指定到新节点中,总槽数为2000
- done: 需要先指定的 node ID,就会从这个 node 迁移 2000个slot 到 7004
又问,是否执行这个计划,yes
最终移动 0-1999 到 7004
再查看一下集群状态
之前 fengxiansheng 这个key 计算的 slot 是 1605,存放在 7001上,现在应该在 7004 上
3. 删除节点
使用 del-node 命令
- host:port: ip和端口
- node_id: 通过redis-cli -p 7001 cluster nodes 可以查看 node ID
-
- 为了防止误删,node_id 必须 ip:port保持一致,如果不一致会报错;
删除 7004,在删除一个 master 前,必须把它的slot移动到其他 master上,否则
转移 slot
然后删除
再查看集群信息,已经没有 7004
6. 故障转移
集群中,如果某个 master 宕机,那么它的 slave 会自动升级为 master
1. 演示
执行命令,监控集群的状态:watch redis-cli -p 7001 cluster nodes
结果:
新建一个窗口,关闭 7002 :redis-cli -p 7002 shutdown,然后查看集群状态:
在执行命令后,可以看到 7002 disconnected
等待一下就发现,7002 fail,它的 slave ,8001 成为 master
重新启动 7002 ,发现成为 slave
2. 手动宕机
可以利用 cluster failover 命令,手动让某个 master 宕机,执行命令的 slave 节点升级为 master
好处:可以实现数据的无感知迁移
流程:
failover 命令还有几个参数
- 缺省:就是上面的流程
- force :忽略数据同步,直接故障转移,需要大多数 master 节点有效,以便对这次切换进行验证
- 使用场景是 master 节点 down 的情况下的人工故障转移
- takeover:直接执行第5步,忽略主备同步,忽略集群其他master的投票
- 使用场景:集群中主节点和从节点在不同的数据中心,当所有主节点 down 掉或被网络分区隔离
在 7002 上执行 cluster failover 命令,恢复 master 地位
这时集群状态
7. RedisTemplate
RedisTemplate 底层基于 lettuce 实现了对 redis cluster 的支持,实现步骤跟哨兵一致
只需要删除哨兵的配置,配置下面地址
# 集群地址
spring.redis.cluster.nodes[0]=192.168.56.103:7001
spring.redis.cluster.nodes[1]=192.168.56.103:7002
spring.redis.cluster.nodes[2]=192.168.56.103:7003
spring.redis.cluster.nodes[3]=192.168.56.103:8001
spring.redis.cluster.nodes[4]=192.168.56.103:8002
spring.redis.cluster.nodes[5]=192.168.56.103:8003