1. Redis集群模式简介
Redis集群是Redis的一种高可用解决方案,它通过在多个节点上分片存储数据,实现数据的高可用和扩展。Redis集群最初是在Redis 3.0版本中引入的。
Redis集群的节点由多个主节点和从节点组成,每个主节点都有多个从节点。集群中的每个节点都维护了整个集群的状态信息,节点之间通过Gossip协议进行通信,通过相互交换状态信息来保持集群中节点的一致性。Redis集群使用的哈希槽(hash slot)将键映射到不同的节点,实现了数据的分布式存储。
Redis集群的优点包括:
- 高可用:当集群中的某个节点故障时,集群仍然可以正常运行。
- 扩展性:Redis集群可以支持更多的数据和客户端请求,可以通过增加节点来实现横向扩展。
- 分布式:Redis集群可以将数据分散在不同的节点上,使得数据的读写负载得到了平衡,提高了Redis的性能。
但是Redis集群也存在一些限制和注意事项,例如:
- Redis集群只能支持单个数据库空间,不能在不同节点之间存储不同的数据库。
- Redis集群不支持事务嵌套和 Lua 脚本中的事务操作。
- Redis集群使用的是哈希槽分片,因此在集群运行过程中,不能动态添加或删除哈希槽,否则会导致数据的迁移,对集群性能产生影响。
在实际应用中,如果需要使用Redis集群,需要对集群中的节点进行适当的配置和调优,以确保集群的高可用性、性能和可靠性。
本节内容来自ChatGPT。
2. Redis集群容错机制
Redis集群的节点由多个主节点和从节点组成,每个主节点都有多个从节点,从节点和主节点的数据一致。
从节点挂掉,不会影响redis集群数据的写入和读取,只会降低读取的性能和容错能力。从节点启动后会自动从主节点同步数据。
主节点挂掉,Redis集群会将该主节点的从节点切换为新的主节点(理论上会几秒内完成,实测三分钟没有等到切换,可能是配置问题),以保证数据可用性和一致性,在新的主节点选出来之前,集群写能力不可用。
参考文档:
- docker搭建3主3从redis集群(主从容错切换、主从扩容、主从缩容)
- K8S部署Redis Cluster集群(三主三从模式)
- redis集群节点宕机
- 深入理解redis cluster的failover机制
- CLUSTER FAILOVER
- Scaling with Redis Cluster
- 腾讯云开发者社区 - cluster failover
3. Redis集群操作命令
cluster
命令查看和操作redis集群。
通过给定可选的参数 section ,可以让命令只返回某一部分的信息:
cluster info
:打印redis集群的信息cluster slots
:列出集群的槽信息cluster nodes
:列出集群当前已知的所有节点(node),以及这些节点的相关信息cluster meet <ip> <port>
:将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子cluster forget <node_id>
:从集群中移除 node_id 指定的节点cluster failover
:该命令只能在群集slave节点执行,让slave节点进行一次人工故障切换,成为master。切换过程中redis会阻塞请求(10s),切换完成再处理请求。
4. Redis集群重启
需求描述:
192.168.56.101-103 三台机器,使用7001和7002端口,搭建了redis集群。
现在想降低内存碎片率,因此计划对redis集群进行重启。
根据Redis集群容错机制,为了对上游调用的服务影响最小,重启流程如下:
1、查看主节点和从节点
1 | redis-cli -c -h 192.168.56.101 -p 7001 -a 'xxx' cluster nodes |
其中-c
参数的作用是启用集群模式,这样可以自动重定向到正确的节点。
查看到主节点和从节点,以及它们的对应关系。
2、挨个重启从节点(一个节点重启成功再进行下一个)
1 | # 登录192.168.56.101执行 |
3、手动故障转移,从节点升级为主节点
1 | redis-cli -c -h 192.168.56.101 -p 7002 -a 'xxx' cluster failover TAKEOVER |
其中TAKEOVER
可选,详情参考腾讯云开发者社区 - cluster failover
4、挨个重启从节点(原本的主节点)
1 | # 登录192.168.56.101执行 |
5、手动故障转移,从节点升级为主节点
1 | redis-cli -c -h 192.168.56.101 -p 7001 -a 'xxx' cluster failover TAKEOVER |
5. 节点不可用问题
Redis集群模式,Java访问Redis集群报错:
1 | io.lettuce.core.RedisCommandExecutionException: CLUSTERDOWN The cluster is down |
排查方法:
1 | redis-cli -c -h 192.168.56.101 -p 7001 -a 'xxx' cluster nodes |
发现报错:
1 | [ERR] Nodes don't agree about configuration! |
这个报错实际上有两个问题:1)有一个节点报错ERR,处于不可用状态,经查是192.168.56.103:7001
;2)192.168.56.101:7002
节点有一些槽位处于导入状态还未完成。
对于192.168.56.101:7002
,解决办法是重启redis节点。
1 | redis-cli -c -h 192.168.56.101 -p 7002 -a 'xxx' shutdown |
重启成功。
对于192.168.56.103:7001
,也是首先尝试重启redis节点。
重启失败,查看日志发现报错:
1 | 15914:C 12 Aug 2023 19:07:36.383 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo |
解决办法:删除数据目录中的文件,然后重新启动。
重新启动成功,但是该节点启动后独立了,不在原本的集群中,这时需要重新握手加入到集群。
1 | redis-cli --cluster check 192.168.56.103:7002 -a 'xxx' |