故障演练 Redis Cluster集群,当master宕机,主从切换,客户端报错 timed out
Posted 微观技术
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了故障演练 Redis Cluster集群,当master宕机,主从切换,客户端报错 timed out相关的知识,希望对你有一定的参考价值。
大家好,我是Tom哥
性能不够,缓存来凑
一个高并发系统肯定少不了缓存的身影,为了保证缓存服务的高可用,我们通常采用 Redis Cluster 集群模式。
描述:
集群部署采用了 3主3从
拓扑结构,数据读写
访问master节点, slave节点负责备份。
随便登录一台 redis 节点,都可以看到集群的slot的槽位分步区间,以及对应的主从节点映射关系。
Redis Cluster 的最新集群信息原因分析:
SpringBoot 2.X 版本, Redis默认的连接池采用 Lettuce
当Redis 集群节点发生变化后,Letture默认是不会刷新节点拓扑
解决方案:
将 Letture
二方包仲裁掉
相关二方包master 节点宕机,看看系统的日志初始化了 24 个连接。然后,回归业务功能,读写缓存
数据也都是操作最新的主节点。
还有一种方案:刷新节点拓扑视图
Lettuce 官方描述:
https://github.com/lettuce-io/lettuce-core/wiki/Redis-Cluster#user-content-refreshing-the-cluster-topology-view
和
移动、重定向
的自适应更新
编写代码
@Bean(destroyMethod = "destroy")
public LettuceConnectionFactory lettuceConnectionFactory()
//开启 自适应集群拓扑刷新和周期拓扑刷新
ClusterTopologyRefreshOptions clusterTopologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
// 开启自适应刷新。否则,Redis集群变更后将会导致连接异常
.enableAllAdaptiveRefreshTriggers()
// 自适应刷新超时时间(默认30秒)
.adaptiveRefreshTriggersTimeout(Duration.ofSeconds(30))
// 开周期刷新
.enablePeriodicRefresh(Duration.ofSeconds(20))
.build();
ClientOptions clientOptions = ClusterClientOptions.builder()
.topologyRefreshOptions(clusterTopologyRefreshOptions)
.build();
LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
.poolConfig(genericObjectPoolConfig(redisProperties.getJedis().getPool()))
.clientOptions(clientOptions)
.commandTimeout(redisProperties.getTimeout()) //默认RedisURI.DEFAULT_TIMEOUT 60
.build();
List<String> clusterNodes = redisProperties.getCluster().getNodes();
Set<RedisNode> nodes = new HashSet<RedisNode>();
clusterNodes.forEach(address -> nodes.add(new RedisNode(address.split(":")[0].trim(), Integer.valueOf(address.split(":")[1]))));
RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration();
clusterConfiguration.setClusterNodes(nodes);
clusterConfiguration.setPassword(RedisPassword.of(redisProperties.getPassword()));
clusterConfiguration.setMaxRedirects(redisProperties.getCluster().getMaxRedirects());
LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(clusterConfiguration, clientConfig);
// 是否允许多个线程操作同一个缓存连接,默认true,false 每个操作都将创建新的连接
// lettuceConnectionFactory.setShareNativeConnection(false);
// 重置底层共享连接, 在接下来的访问时初始化
// lettuceConnectionFactory.resetConnection();
return lettuceConnectionFactory;
关于我:Tom哥,前阿里P7技术专家,offer收割机,参加多次淘宝双11大促活动。欢迎关注,我会持续输出更多经典原创文章,为你晋级大厂助力
目前微信群已开放,想进交流群的小伙伴请添加Tom哥微信,暗号「进群」,唠嗑聊天, 技术交流,围观朋友圈,人生打怪不再寂寞
推荐阅读「故障演练」 Redis Cluster集群,当master宕机,主从切换
性能不够,缓存来凑
一个高并发系统肯定少不了缓存的身影,为了保证缓存服务的高可用,我们通常采用 Redis Cluster 集群模式。
描述:
集群部署采用了 3主3从 拓扑结构, 数据读写 访问master节点, slave节点负责备份。
随便登录一台 redis 节点,都可以看到集群的slot的槽位分步区间,以及对应的主从节点映射关系。
人为模拟,master-1 机器意外宕机
此时,Redis Cluster 集群能自动感知,并自动完成主备切换,对应的slave会被选举为新的master节点
看下 redis cluster 集群最新的主从关系
看似也没什么问题,一切正常
此时 Spring Boot 应用依然在线服务,当我们再尝试操作缓存时,会报错
问题边界还是非常清晰的。
Redis Cluster 集群已经完成了切换。
但是 Spring Boot 客户端 没有动态感知到 Redis Cluster 的最新集群信息
原因分析:
SpringBoot 2.X 版本, Redis默认的连接池采用 Lettuce
当Redis 集群节点发生变化后,Letture默认是不会刷新节点拓扑
解决方案:
将 Letture 二方包仲裁掉
然后,引入 Jedis 相关二方包
编译代码,并重新启动 SpringBoot 微服务,万事俱备,只欠再次验证
重新模拟将 127.0.0.1:8001 master 节点宕机,看看系统的日志
从打印的日志来看,客户端已经感知到了 主备切换 ,并与最新的主节点 127.0.0.1:8004 初始化了 24 个连接。
然后,回归业务功能, 读写缓存 数据也都是操作最新的主节点。
还有一种方案: 刷新节点拓扑视图
Lettuce 官方描述:
解决方案:
编写代码
以上是关于故障演练 Redis Cluster集群,当master宕机,主从切换,客户端报错 timed out的主要内容,如果未能解决你的问题,请参考以下文章
redis演练(10) redis Cluster 集群节点维护