ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Spring Session与Redis集群集成问题解决方案

Spring Session与Redis集群集成问题解决方案 1. 问题现象与背景分析最近在afcenter项目中使用Spring Session配置Redis集群存储时遇到了一个典型的启动报错。当我们在application.properties中设置spring.session.store-typeredis后应用启动时抛出异常Caused by: io.lettuce.core.RedisCommandExecutionException: ERR no such key at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:54) ... at org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:247)这个错误表面看起来是Redis操作时找不到对应的key但实际涉及Spring Session与Redis集成的多个技术环节。我在排查过程中发现这实际上是Spring Session在初始化时尝试操作一个不存在的Redis key导致的连锁反应。2. 错误根源深度解析2.1 Spring Session的Redis存储机制Spring Session使用Redis存储会话数据时会在Redis中创建特定的数据结构。默认情况下它会使用spring:session作为key的前缀并创建以下几种数据结构会话主记录spring:session:sessions:sessionId过期时间索引spring:session:sessions:expires:sessionId全局索引spring:session:expirations:timestamp当应用启动时Spring Session会尝试与Redis建立连接并初始化这些数据结构。如果Redis连接配置正确但权限不足或者Redis集群某些节点不可达就会出现这种看似key不存在的错误。2.2 Lettuce客户端的行为特点从堆栈信息可以看到我们使用的是Lettuce作为Redis客户端io.lettuce.core包。Lettuce与Redis集群交互时有几个特点连接延迟建立Lettuce默认采用懒加载方式建立连接集群拓扑刷新定期刷新集群节点信息命令重定向当操作key不在当前节点时会收到MOVED重定向在集群环境下如果客户端没有正确处理MOVED/ASK重定向或者集群节点间数据同步延迟就可能出现no such key的错误。3. 完整解决方案3.1 基础配置检查首先确保Redis连接配置正确在application.properties中# 基本Redis配置 spring.redis.cluster.nodes192.168.1.101:6379,192.168.1.102:6379,192.168.1.103:6379 spring.redis.passwordyourpassword spring.redis.timeout3000 # Session配置 spring.session.store-typeredis spring.session.redis.flush-modeon_save spring.session.redis.namespacespring:session关键检查点所有集群节点地址和端口是否正确密码是否正确如果有网络连通性是否正常3.2 集群特定配置对于Redis集群需要添加以下额外配置# Lettuce集群配置 spring.redis.lettuce.cluster.refresh.adaptivetrue spring.redis.lettuce.cluster.refresh.period2000 spring.redis.lettuce.pool.max-active8 spring.redis.lettuce.pool.max-wait-1这些配置的作用refresh.adaptive启用自适应拓扑刷新refresh.period拓扑刷新间隔(毫秒)连接池配置避免连接泄漏3.3 代码级解决方案如果仍然出现问题可以自定义RedisConnectionFactoryConfiguration public class RedisConfig { Bean public RedisConnectionFactory redisConnectionFactory() { RedisClusterConfiguration clusterConfig new RedisClusterConfiguration(); clusterConfig.addClusterNode(new RedisNode(192.168.1.101, 6379)); // 添加所有节点... clusterConfig.setPassword(RedisPassword.of(yourpassword)); LettuceClientConfiguration clientConfig LettuceClientConfiguration.builder() .commandTimeout(Duration.ofSeconds(3)) .clientOptions(ClientOptions.builder() .autoReconnect(true) .pingBeforeActivateConnection(true) .build()) .build(); return new LettuceConnectionFactory(clusterConfig, clientConfig); } }4. 高级排查技巧4.1 诊断Redis集群状态使用Redis CLI检查集群健康状态redis-cli -c -h 192.168.1.101 -p 6379 -a yourpassword cluster nodes输出示例e1d1a3cf... 192.168.1.101:637916379 myself,master - 0 1650000000000 1 connected 0-5460 a2b3c4d5... 192.168.1.102:637916379 master - 0 1650000000500 2 connected 5461-10922 f5e6d7c8... 192.168.1.103:637916379 master - 0 1650000001000 3 connected 10923-16383检查要点所有节点状态是否为connected槽位(slot)分配是否完整(0-16383)是否有fail状态的节点4.2 监控Spring Session初始化过程启用调试日志查看详细过程logging.level.org.springframework.sessionDEBUG logging.level.org.springframework.data.redisDEBUG logging.level.io.lettuce.coreINFO典型正常日志DEBUG o.s.session.data.redis.RedisOperationsSessionRepository - Creating new session DEBUG o.s.data.redis.core.RedisTemplate - Executing command [RENAME]... DEBUG o.s.data.redis.core.RedisTemplate - Redis command execution completed4.3 使用Redis Desktop Manager验证通过可视化工具检查连接是否成功建立spring:session命名空间下是否有数据Key的TTL设置是否合理5. 生产环境最佳实践5.1 高可用配置建议# 集群故障转移配置 spring.redis.lettuce.cluster.refresh.adaptivetrue spring.redis.lettuce.cluster.max-redirects5 spring.redis.lettuce.cluster.validatetrue # 连接池优化 spring.redis.lettuce.pool.max-active16 spring.redis.lettuce.pool.max-idle8 spring.redis.lettuce.pool.min-idle4 spring.redis.lettuce.pool.time-between-eviction-runs30s5.2 会话存储优化Bean public RedisSerializerObject springSessionDefaultRedisSerializer() { return new GenericJackson2JsonRedisSerializer(objectMapper()); } private ObjectMapper objectMapper() { ObjectMapper mapper new ObjectMapper(); mapper.registerModules(new JavaTimeModule()); mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); return mapper; }5.3 监控与告警建议监控以下指标Redis集群各节点内存使用率连接数波动命令延迟百分位Key过期事件异常6. 同类问题扩展6.1 其他常见Redis集群错误MOVED重定向错误原因客户端未跟随集群重定向解决检查spring.redis.lettuce.cluster.refresh配置ASK重定向错误原因集群正在迁移槽位解决等待迁移完成或临时重试CLUSTERDOWN错误原因集群不可用解决检查集群节点状态和网络6.2 Spring Session与Redis版本兼容性常见组合验证Spring Session 2.x Redis 5.x/6.xSpring Boot 2.4.x Lettuce 6.x避免混用Jedis和Lettuce客户端6.3 多应用共享Redis集群时的隔离建议方案使用不同database需集群支持设置不同的namespacespring.session.redis.namespaceapp1:session通过不同密码分区需Redis ACL支持
返回列表