RedisCluster集群模式下master宕机主从切换期间Lettuce连接Redis无法使用报错Redis command timed out的问题

记录redis集群连接超时问题及解决方案 下午同事反馈,某业务场景性能测试过程中,出现异常,提供日志报:Redis command timed out 1. 先看下日志 org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutExcep... 阅读详情
AI摘要

本文深入探讨Redis集群中Lettuce客户端在主从切换后服务恢复缓慢的原因,提供通过调整拓扑刷新策略来优化服务可用性的解决方案。

最新一次线上生产环境下Redis集群服务器某一个主节点发生故障,Cluster节点下的从节点快速进行迁移升级为主节点,节点迁移时间大概为15秒,这15秒期间Redis服务不可用,程序无法读写Redis数据,报错java.lang.RuntimeException: org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s),但是15秒过后服务依旧无法使用,大概持续了6分钟,而在业务高峰期间这6分钟也会造成很大的用户感知,为何要持续这么久Redis才能恢复,成为了未知的谜团!

联合运维和云厂商做了很多测试,发现凡是使用jedis客户端的服务都可以在15秒主从切换后恢复,而使用lettuce作为redis客户端的服务则无法恢复使用,一直抛超时的异常,做了实验发现,使用lettuce作为客户端的服务,在15秒主从切换后一直要等待redis服务的宕机节点拉起成功后才可以恢复,而这时间大概持续了2分钟,从网上搜了很多答案发现也有一些遇到了同样问题的情况发生。Lettuce的节点切换15秒是来源于 cluster-node-timeout这个配置的默认时间,这个是时间节点宕机发现时间,也就是Redis群集节点不可用的最长时间,因为RedisCluster是无中心设计,节点探测的时间设置太小会因为网络抖动造成的节点下线,时间太长又无法快速处理节点切换,这个可以具体了解Cluster集群主从切换的原理。相关阅读https://www.cnblogs.com/kaleidoscope/p/9636264.html

因为所有微服务使用SpringBoot2.1.7版本SpringBoot2.X版本开始Redis默认的连接池都是采用的Lettuce,之前的文章也有介绍过Lettuce连接池的使用,为了避免后续出现硬件故障,导致服务连接Redis一段时间不可用的情况,所以也就急需要解决节点宕机的恢复时间问题。

经过大量的调研和实验最后发现有关,官方的描述是https://github.com/lettuce-io/lettuce-core/wiki/Redis-Cluster#user-content-refreshing-the-cluster-topology-view, Lettuce需要刷新节点拓扑视图,

大致意思是,Redis集群配置在运行期间可能会改变,可以添加新的节点,为特定插槽的主节点可以发生改变,Lettuce处理Moved和Ask永久重定向,但是由于命令重定向,你必须刷新节点拓扑视图,拓扑是绑定到RedisClusterClient的示例,所有由一个RedisClusterClient实例创建的节点连接共享相同的节点拓扑视图,视图可以采用以下三种方式更新

1、Either by calling RedisClusterClient.reloadPartitions

通过调用RedisClusterClient.reloadPartitions

2、Periodic updates in the background based on an interval

后台基于时间间隔的周期刷新

3、Adaptive updates in the background based on persistent disconnects and MOVED/ASKredirections

后台基于持续的断开和移动/重定向的自适应更新

By default, commands follow -ASK and -MOVED redirects up to 5 times until the command execution is considered to be failed. Background topology updating starts with the first connection obtained through RedisClusterClient.

默认的 命令跟随ASK 和移MOVED 命令执行重定向到5次,直到被认为是失败了,后台拓扑更新始于第一次RedisClusterClient链接

相关阅读 https://github.com/lettuce-io/lettuce-core/wiki/Client-options#periodic-cluster-topology-refresh

所以说在RedisCluster集群模式下可以通过 3种方式去刷新节点拓扑视图去解决节点重新识别的问题,

第一种方式是通过RedisClusterClient,SpringBoot通过Sprint Redis Data构建Redis时,没有显式构建RedisClusterClient,所以只能通过其他两种方式

https://github.com/lettuce-io/lettuce-core/wiki/Client-Options

这里描述了很多特殊场景下设置的客户端选项,可以视自身情况去设置调整

 

    @Autowired
	private RedisProperties redisProperties;

	@Bean
	public GenericObjectPoolConfig<?> genericObjectPoolConfig(Pool properties) {
		GenericObjectPoolConfig<?> config = new GenericObjectPoolConfig<>();
		config.setMaxTotal(properties.getMaxActive());
		config.setMaxIdle(properties.getMaxIdle());
		config.setMinIdle(properties.getMinIdle());
		if (properties.getTimeBetweenEvictionRuns() != null) {
			config.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRuns().toMillis());
		}
		if (properties.getMaxWait() != null) {
			config.setMaxWaitMillis(properties.getMaxWait().toMillis());
		}
		return config;
	}
	
	@Bean(destroyMethod = "destroy")
	public LettuceConnectionFactory lettuceConnectionFactory() {
		
	    //开启 自适应集群拓扑刷新和周期拓扑刷新
	    ClusterTopologyRefreshOptions clusterTopologyRefreshOptions =  ClusterTopologyRefreshOptions.builder()
	    		// 开启全部自适应刷新
	            .enableAllAdaptiveRefreshTriggers() // 开启自适应刷新,自适应刷新不开启,Redis集群变更时将会导致连接异常
	            // 自适应刷新超时时间(默认30秒)
	            .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(30)) //默认关闭开启后时间为30秒
	    		// 开周期刷新 
	    		.enablePeriodicRefresh(Duration.ofSeconds(20))  // 默认关闭开启后时间为60秒 ClusterTopologyRefreshOptions.DEFAULT_REFRESH_PERIOD 60  .enablePeriodicRefresh(Duration.ofSeconds(2)) = .enablePeriodicRefresh().refreshPeriod(Duration.ofSeconds(2))
	            .build();
		
	    // https://github.com/lettuce-io/lettuce-core/wiki/Client-Options
	    ClientOptions clientOptions = ClusterClientOptions.builder()
	            .topologyRefreshOptions(clusterTopologyRefreshOptions)
	            .build();

	    LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
				.poolConfig(genericObjectPoolConfig(redisProperties.getLettuce().getPool()))
				//.readFrom(ReadFrom.MASTER_PREFERRED)
				.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);
		// lettuceConnectionFactory.setShareNativeConnection(false); //是否允许多个线程操作共用同一个缓存连接,默认true,false时每个操作都将开辟新的连接
		// lettuceConnectionFactory.resetConnection(); // 重置底层共享连接, 在接下来的访问时初始化
		return lettuceConnectionFactory;
	}

开启自适应刷新并设定刷新频率

可以看到设定前,周期刷新和拓扑刷新都是false

调整后周期刷新和拓扑刷新都是true

 

enablePeriodicRefresh意思就是开启并设定周期刷新时间

开关的开启后的控制实际是RedisClusterClient.activateTopologyRefreshIfNeeded在这个方法内完成的,如果开关开启则会创建一个ScheduledFuture 根据你设置的节点刷新事件定期的去调用,当RedisClusterClient初始化后,定时器会周期性的执行,

如果 定时器执行通过,则RedisClusterClient.doLoadPartitions会返回loadedPartitions,如果半截Return掉,则不再返回新的节点信息。

 

相关阅读https://github.com/lettuce-io/lettuce-core/issues/240

相关阅读https://blog.youkuaiyun.com/weixin_42182797/article/details/95210437#_1

 

 

当然,如果你想就此放弃lettuce转用jedis也是可以的 Spring Boot2.X版本,只要在pom.xml里,调整一下依赖包的引用

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
			<exclusions>
				<exclusion>
					<groupId>io.lettuce</groupId>
					<artifactId>lettuce-core</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
		</dependency>

配置上lettuce换成jedis的,既可以完成底层对jedis的替换

spring:
  redis:
    jedis:
      pool:
        max-active: ${redis.config.maxTotal:1024}
        max-idle: ${redis.config.maxIdle:50}
        min-idle: ${redis.config.minIdle:1}
        max-wait: ${redis.config.maxWaitMillis:5000}
    #lettuce:
      #pool:
        #max-active: ${redis.config.maxTotal:1024}
        #max-idle: ${redis.config.maxIdle:50}
        #min-idle: ${redis.config.minIdle:1}
        #max-wait: ${redis.config.maxWaitMillis:5000}

因为jedis的节点信息,没有搞的那么复杂

 

后续SpringBoot2.3.0以后开始Lettuce支持集群拓扑动态感应刷新的新特性,可以移步这里 https://blog.youkuaiyun.com/ankeway/article/details/108192487

[springboot, lettuce] io.lettuce.core.RedisCommandTimeoutException: Command timed out after 环境上用的springboot2.3.1, 项目上线已经两年,今天第一次遇到这个lettuce的Redis “Command timed out”,于是网上查了查资料,找一下原因和解决方法。 列举一下处理方式 1、修改spring.redis.timeout和cluster.refresh 当然这个是第一步,可以进行观察是否有作用 #Spring Boot 从 2.0版本开始,将默认的Redis客户端Jedis替换为Lettuce spring.redis.lettuc... 阅读详情

相关推荐

填坑之路-记录Redis操作的异常QueryTimeoutException & RedisCommandTimeoutException: Command timed out after 1 min

原始异常信息如下 org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s) at org.springframework.data.redis.connection.lettuce.LettuceExcep

汉风唐尚的博客 1万+

【问题解决】org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io

解决Redis连接异常超时或存储超时问题

喵喵喵喵~我是一个程序员而已 7993

微信小程序-如何根据缩放屏幕大小自适应icon图标更改marker

微信小程序如何根据用户的缩放屏幕来改变marker图标icon的大小,实现icon自适应屏幕缩放的效果

Bartender_VA11的博客 3980

Redis command timed out 两种异常情况

Redis command timed out

心若有向往,何惧道阻且长! 2万+

已解决-Parallels Desktop 16 网络初始化失败:您的虚拟机将继续正常运作,但将无法连接网络

我是月球挖掘机,相信不少打工人为了尝鲜已经更新了MacOS 11 Big Sur,当然,苹果每次的系统大更新,都会给我们软件的功能无法使用惊喜,这次的也不例外。 这个问题是我在更新macOS Big Sur之后,Parallels Desktop打开虚拟机后,提示: 报错信息 网络初始化失败:您的虚拟机将继续正常运作,但将无法连接网络 这是我的软件版本: 起初我以为是我的虚拟机坏了,结果重装了一遍虚拟机,没有任何用处。我开始在网上找方法,只能找到那个使用命令行打开软件的命令,除此之外没有了

月球挖掘机 5万+

xilinx zynq-7000 linux下rs422串口通信测试步骤

这几天使用xilinx的zynq-7000系列调试rs422串口,期间遇到不少问题,好在最终调试完成,在这里记录一下调试步骤。 我用的soc型号是xc7z100,板载了2个rs422外设,PS端有2个uart控制器,uart0用于连接rs232并作为console控制台输出,uart1连接rs422。 rs422和主板连线原理图如下: 其中422_TXD1_3V3 和422_RXD1_3V3 为数据发送和接收引脚,422_TXD_DE1_3V3为发送使能引脚,422_RXD_REn1_...

dongyunke的博客 5907

redis死链 org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception

org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s) at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.con

wangjun5159的专栏 8772

运算放大器测试方法-输入失调电压

由于运放输入回路的不对称性,在输入端将产生一定的误差信号,从而限制运放信号灵敏度。通常用输入失调电压(VOS)、输入失调电流(Ios)和输入偏置电流(IB)表示。运放有四个主要特征:输入失调特征、开环特征、共模特征及输出特征。其放大倍数较大,由于外界的影响,即使运放的输入端产生较小的输入信号,经过放大,在输出端也会产生较大的误差。为能精确测量其性能,一般采用辅助运放进行测试。下面着重讲了运放的主要参数及如何精确测量这些参数。文中DUT代表被测运放,A代表辅助运放。

weixin_46135931的博客 1万+

lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s) timeout 60000超时问题

java程序不定期会出现Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s) 错误,导致应用出现 timeout 60000 错误,重启应用后,问题修复,但还是会不定期出现该问题。查看应用日志,发现有如下错误:

黄煜的博客 6058

HDMI接口协议

接口HDMI(High-Definition Multimedia Interface),新一代多媒体接口标准。即高清多媒体接口。它能够同时传输视频和音频,简化了设备的接口和连线;同时提供了更高的数据传输带宽,可以传输无压缩的数字音频及高分辨率视频信号。HDMI 1.0 版本于 2002 年发布,最高数据传输速度为 5Gbps;而2017 年发布的 HDMI 2.1 标准的理论带宽可达 48Gbps。1、能够同时传输视频和音频,简化了设备接口与连线。2、提供了更高的数据传输带宽,

weixin_42581439的博客 2595

影刀RPA验证码识别避坑指南:官方指令、Python ddddocr与第三方图鉴怎么选?

本文深度对比了影刀RPA验证码识别的三种方案:官方AI指令、Python ddddocr开源库和第三方图鉴服务。从识别率、成本、维护性等维度分析各方案优劣,提供实战选型建议和优化技巧,帮助技术决策者在自动化流程中高效解决验证码识别难题。

weixin_30790841的博客 471

Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException 错误

错误,主要需从网络连接、Redis服务器性能、命令执行效率、阻塞性命令以及客户端配置等多个角度进行排查。通过监控、日志分析和代码审查,定位并优化问题根源,同时合理调整客户端超时设置以适应实际场景。错误时,这表明客户端(通常是使用Lettuce作为Redis客户端库的应用程序)在执行Redis命令时超出了预设的响应时间限制。

易之阴阳,量子纠缠,道之一体,缘起性空 1万+

AI视频生成成本优化实战:混合架构与硬件选型

AI视频生成技术正面临效果与成本的二元博弈,其核心挑战在于高昂的推理算力消耗与黑箱服务的不确定性。从技术原理看,视频生成依赖扩散模型等深度学习架构,通过多轮迭代实现像素级合成,这导致GPU显存占用和电力消耗呈指数级增长。在工程实践中,采用混合推理架构能有效平衡成本与质量,例如云端处理关键帧配合本地渲染过渡帧,实测可降低58%支出。硬件选型方面,消费级显卡魔改与边缘计算设备为中小企业提供了可行方案,如RTX 3090显存扩容或Jetson AGX边缘部署。当前AI视频应用已渗透电商直播、新闻制作等领域,但需警

weixin_29531177的博客 295

Redis command timed out 原因

错误通常表示客户端在向 Redis 服务器发送命令后,在指定的超时时间内未能收到服务器的响应。通过综合分析和排查,定位具体原因后采取相应的优化措施,可以有效减少或消除。

易之阴阳,量子纠缠,道之一体,缘起性空 4174

linux操作系统使用以太网连接ubuntu,设置固定ipv4

首先,您需要确定要配置的网络接口。可以使用ifconfig -a或ip addr命令来列出当前系统上的所有网络接口及其相关信息。找到您要配置的网络接口名称,例如eth0、ens33或enp0s3;保存并关闭文件后,您需要重启网络服务以使更改生效。在linux操作系统中,要使用交换机连接以太网可以直接使用交互界面;如果你的操作系统没有交互界面,你可以使用命令方式配置;点击ipv4,方式为手动,可以设置ip和子网了;开头,后接网络接口名称。第三步:点击有线最右边圆形控件;第二步:点击有线设置;

2301_79311842的博客 2404

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Redis command timed out 处理(InsCode AI 创作助手)

1. 命令本身耗时过长:某些Redis命令可能需要较长的时间来执行,特别是在大型数据集上执行时。如果超时值设置得太短,就会导致命令超时异常。 2. Redis执行大命令:Redis服务器端通过单线程处理命令,一旦有大命令被执行,Redis将无法及时响应来自客户端的任何命令。

LSW1737554365的博客 3734

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

redis连接报错:io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s)

这是lettuce的bug spring-boot-starter-data-redis引用的是lettuce做为redis的连接方式,所以我们需要用别的代替,比如jedis 在pom依赖中排除lettuce,再引入jedis <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifa

nirvana99的博客 7011

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【解决方法】 SpringBoot 整合 Redis 报错:Cannot resolve symbol ‘RedisTemplate‘

现象 原因 导入的 Redisjar 包不对,所以找不到 StringRedisTemplate 和 RedisTemplate 类。 解决方法 将 pom.xml 修改为: <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis --> <dependency&g...

ageovb的专栏 9971

生产一次RedisCommandTimeoutException问题分析

1、在某个时间段,生产日志大量出现RedisCommandTimeoutException,一共98次: grep "RedisCommandTimeoutException" *_2021-09-10.5.log |wc -l 2、查看第一次出现的位置: grep -C 100 "RedisCommandTimeoutException" *_2021-09-10.5.log |head -201 完整异常信息如下: 2021-09-10 14:50:33.423 INFO [h...

小哥骑单车 1万+

解决io.lettuce.core.RedisCommandTimeoutException: Command timed out, mysql 访问15分钟阻塞等待

写这篇文章前我也是谷歌百度过,可以无非都是千篇一律配置 timeout 或者lettuce的连接池,可是更改完这些配置,问题依旧,于是开始了自我探索之路,请出Wireshark大杀器,每当动用Wireshark时,我都知道我摊上大事了,文章是两个问题一个redis,一个mysql,但是都是一个原因造成的,所以写在了一起 一:redis超时 1.出现问题的现象是每隔5,6分钟(这个时间是反复...

淡泊明志,宁静致远 4万+

SpringBoot连接Redis服务出现Command timed out

问题描述:SpringBoot整合Redis,连接Redis服务时出现Command timed out 解决方法: 查看配置文件是否是设置的连接超时时间过小,一般将其设置为5000毫秒

北辰 2万+

redis 连接超时 Redis command timed out

最近在项目中遇到这个问题,启动项目没有问题,但是用着用着就出现redis连接超时,而且这个问题在使用了Kubernetes后,显得尤为突出。估计很多人也遇到了,排查思路如下: 1.检查配置文件链接配置,修改配置 2.redis服务问题 3.网络问题 后来还是会有这个问题: 在检查redis服务没问题后,最后发现是驱动的问题,我们引入了spring-boot-starter-data-redis包,这个包会默认使用 lettuce ,这个问题就lettuce引起的,我们只需要把io.

xiaomins_zhm的博客 1万+

如何解决Command timed out after 1 minute(s) 问题

今天上班刚打开项目 发现项目突然报这个错 检查自己的代码 也没有问题。

yzs2022的博客 6502
上一篇: Nepxion/Discovery灰度发布组件的使用教程(二)、基于REST请求调用灰度路由策略的使用
下一篇: STS启动Spring Boot服务的时候无法启动,报错,错误: 找不到或无法加载主类的解决办法
幕紫
博客等级 码龄16年 56粉丝 32原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值