Redis 集群模式笔记
注意: 因为测试,我一个节点部署多个服务,生产环境建议分开不然会报 are on same IP,导致主从切换失败
1 使用场景
哨兵模式已经能够实现高可用,实践中通常是分布式服务,某一个点的分类数据放在指定的一个哨兵主从,通常也足够,但如果某个分类数据量实在过于庞大,哨兵+主从这种模式,相当于每个节点都是一个全量的数据副本,从高可扩方面来说,它这种模式不是很方便,对资源也是很大的浪费。当哨兵+主从遇到资源瓶颈,或者对高可扩有一定要求的时候,集群模式便能解决这个问题
- 高可用原理
Redis 集群模式是没有中心节点的,它至少需要 3 个 master 节点,每个 master 节点至少一个 slave(默认读),也就是至少 6 个节点才能组建集群模式,已经内置了数据分片和故障转移。
数据分片是 16384 个虚拟槽位分散到不同的 master 节点,设置 key 的时候,服务节点通过 key 的 hashcode % 16384,转发存放到不同的节点的对应分片槽位上。当查询请求到一个节点时,服务节点根据 key 检查槽位是否在当前节点,若存在则响应数据,若不存在则 moved 重定向到对应的服务节点。
故障转移方面和哨兵类似,集群模式下各个节点之间通过 gossip 通信,相互 ping-pong,当一个节点对另外一个节点的心跳检查,超过 cluster_node_timeout 参数的值,则广播所有节点对其检查,当超过 50%的节点都认为此节点故障时则正式下线。若是从节点,断开时长超过 cluster_node_timeout * cluster-slave-validity-factor 这个组合参数值,则该从节点不再参与数据恢复。
综合来看,集群模式在 5.0 后已经非常成熟,可以不用过多考虑扩容的问题,也减少了维护哨兵的工作。
2 环境信息
因为集群模式至少 3 个 master 节点,而每个主节点至少 1 个 slave,所以至少 6 个节点才能组建集群模式,下面以 6 个节点为例。
启动 6 个实例节点后,使用 redis-cli 建立初始集群关系,便建立自动维护关系的 Cluster 集群。
3 部署 redis 集群
3.1 下载解压安装
wget http://download.redis.io/releases/redis-6.2.7.tar.gz
tar-zxvf redis-6.2.7.tar.gz
make
# make install
# 这里我不安装值编译好直接运行
3.2 修改配置文件
此配置只当参考,不要在生产环境用,环境不同配置也不一样比如 repl-diskless-syn 设置同步方式为磁盘同步或者网络同步,磁盘慢网络带宽好的时候使用网络同步更好(详细配置参考: Redis配置详解)
参数名称 | 解释 |
---|---|
daemonize yes | redis 后台运行 |
appendonly yes | aof 日志开启 有需要就开启,它会每次写操作都记录一条日志 |
bind 192.168.200.140 | 绑定 ip |
cluster-config-file nodes_6379.conf | 集群的配置 配置文件首次启动自动生成 |
cluster-enabled yes | 开启集群 把注释#去掉 |
cluster-node-timeout 5000 | 请求超时 设置 5 秒够了,防止网络波动主从误切换 |
logfile “nodes_6379.log” | 指定输出日志 |
masterauth passwd | slave 节点数据同步 master 密码 |
pidfile /var/run/redis_6379.pid | pidfile 文件对应端口号 |
port 6379 | 要开放端口 |
protected-mode no | 禁止安全模式运行,主要拦截公网 ip 访问,如果开启会一直卡在获取 |
requirepass passwd | 可选,配置 redis 密码,如果配置了一定要配置 masterauth,不然无法同步数据 |
3.3 启动 redis
src/redis-server 1114.conf
src/redis-server 1113.conf
redis4,加入集群
src/redis-cli --cluster create 192.168.1.133:6379 192.168.1.133:1110 192.168.1.133:1111 192.168.1.133:1112 192.168.1.133:1113 192.168.1.133:1114 --cluster-replicas 1 -a passwd
–replicas 1 代表一主一从, -a 是密码
关于主从节点的选择及槽的分配,其算法如下:
- 把节点按照 host 分类,这样保证 master 节点能分配到更多的主机中。
- 遍历 host 列表,从每个 host 列表中弹出一个节点,放入 interleaved 数组。直到所有的节点都弹出为止。
- 将 interleaved 数组中前 master 个数量的节点保存到 masters 数组中。
- 计算每个 master 节点负责的 slot 数量,16384 除以 master 数量取整,这里记为 N。
- 遍历 masters 数组,每个 master 分配 N 个 slot,最后一个 master,分配剩下的 slot。
- 接下来为 master 分配 slave,分配算法会尽量保证 master 和 slave 节点不在同一台主机上。对于分配完指定 slave 数量的节点,还有多余的节点,也会为这些节点寻找 master。分配算法会遍历两次 masters 数组。
- 第一次遍历 master 数组,在余下的节点列表找到 replicas 数量个 slave。每个 slave 为第一个和 master 节点 host 不一样的节点,如果没有不一样的节点,则直接取出余下列表的第一个节点。
- 第二次遍历是分配节点数除以 replicas 不为整数而多出的一部分节点。
执行指令后,提示预设的数据分片槽位信息 slots、主从关系信息等:
输入 yes
创建完成
三、检测
src/redis-cli -c -h 192.168.1.133 -p 1111
(-c 是进入集群模式)
CLUSTER nodes
(命令参考)
存储的数据(key-value)是均匀分配到不同的节点的:
以下文档新添加的,可能与上面环境不符,但是不影响观看
4 集群管理控制台
4.1 安装 redisinsight
docker run -d -v /data/redisinsight-data/:/db -p 8001:8001 redislabs/redisinsight:latest
4.2 登录添加集群
选择所有节点
4.3 查看集群状态
5 节点下线维护
所有操作都可以在上面控制台实现
5.1 查看节点状态
src/redis-cli -c -h 10.1.1.1 -p 6379 -a passwd cluster nodes
5.2 master 节点,有两种方案(二选一)
5.2.1 直接移除哈希槽,然后下线
src/redis-cli –cluster reshard 10.1.1.1:6380 -a passwd
5.2.2 改成 slave 节点
src/redis-cli -c -h 10.1.1.1(slave节点地址) -p 6380 -a passwd cluster failover
5.3 移除节点
src/redis-cli --cluster del-node 10.1.1.3:6379 8285c1fbd2297aab9f031dafc0b9240b8fa89d15 -a passwd
5.4 查看集群状态
slave 自动同步 id 以 a41 的 master 节点
5.5 查看 slave 节点数据
6 新加节点
6.1 添加节点
src/redis-cli –cluster add-node 10.1.1.3:6379(要加入的节点) 10.1.1.3:6380(当前集群已有节点) -a passwd
6.2 添加 master 节点
因为加进来默认就是 master 节点,直接分配哈希槽就行
src/redis-cli --cluster reshard 10.1.1.3:6379 -a passwd
6.2.1 写入测试
6.3 添加 slave 节点
src/redis-cli --cluster add-node --cluster-slave --cluster-master-id 8e165e491c28a35488e4c6a2fa659ec41fe8053b(主节点的ID) 10.1.1.3:6380 (新加的从节点) 10.1.1.3:6379(主节点地址) -a passwd
6.3.1 查看数据同步
7 高可用测试
7.1 停掉 slave
因为停掉 slave 不影响写入,所以不做写入测试,只测试能否自动加入集群
7.1.1 写入数据
7.1.2 启动服务查看
启动后自动加入集群
7.1.3 查看数据是否同步
8 会自动同步过来
7.2 停掉 master
7.2.1 准备写入数据脚本
1 | !/bin/bash |
7.2.2 启动脚本,停止 master
slave 会自动变成 master
7.2.3 写入数据,查看是否总共 2000 个 key
运行过程中发现脚本并不会检测这个节点能不能用. 服务不可用时间为:slave 检测 master 间隔+检测超时时间
降低不可用时间有两种方法:
- 程序或者代理层做判断
- 降低 slave 检测 master 超时时间与增加检测次数
master 切换的节点数量与别的节点相比差了将近 500
7.2.4 master 重新启动
会自动变成刚才 master 节点的 slave
7.2.5 查看数据
只有 master 节点存在的 key 都会同步过来,唯一的问题是客户端不会自动禁止访问不可用的节点,中间需要加代理判断节点可不可用
8 单节点数据迁移到集群
8.1 修改配置
如果 redis5.0 之前的版本,在移动槽点的时候,假如槽点内有值的话,导致报错:Syntax error ,try client(list|kill|getname|setname|pause|reply) ,主要就是需要修改 redis-trib.rb 文件的 move_slot 这个方法,绕过 clientCommand,直接执行 migrateCommand(去掉.client 即可)。
8.2 修改哈希槽
把所有哈希槽放到一个节点上
1 | src/redis-trib.rb reshard 192.168.1.114:6379 |
8.3 迁移数据
关闭服务,把单节点的 rdb 文件改成这个节点的配置文件里面的名字
8.4 恢复服务
启动服务
system start redis
重新分配哈希槽
1 | src/redis-trib.rb reshard 192.168.1.114:6379 |
9 备份与还原
参考: Redis备份与恢复