ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Spring Boot整合Redis四种模式详解与故障排查指南

Spring Boot整合Redis四种模式详解与故障排查指南 做后端开发的人几乎都绕不开Redis尤其在Spring Boot框架下缓存、分布式锁、会话共享、限流、排行榜、消息队列很多功能都会优先考虑用Redis来承接。于是网络上到处能看到“Spring Boot整合Redis”的教程但大部分教程只演示默认单机模式下的配置后面说到主从、哨兵、集群就含糊带过或者直接不写了。先说个我经常看到的场景项目初期Redis单机跑得好好的上线后流量一上来就频繁报警或者某次服务器重启后缓存全部丢失因为Redis进程挂了没人恢复。这时候才想起来要搭主从复制、用哨兵做自动切换或者在多个节点之间做集群分片。但问题在于单机、主从、哨兵、集群这四种模式不只是部署层面的差异Spring Boot里的配置方式、连接参数、故障处理机制也完全不同比如Spring Boot 3.x用了新的spring.data.redis前缀和旧版的spring.redis前缀不一样直接照搬网上老教程就会踩坑。这篇文章把四种模式一次性讲清楚。我会先从它们各自的原理说起再逐个给出Spring Boot下的配置文件和连接工厂配置最后整理一份高频故障排查清单。文中所有配置都基于实际可运行的做法我踩过的坑也都会点出来希望看完你能在自己项目里直接照着改。1. Redis四种模式先分清楚它们本质差别在哪很多人把主从、哨兵、集群混为一谈其实它们是不同维度上的方案。主从解决的是数据冗余和读写能力问题哨兵解决的是主节点故障时的自动切换问题集群解决的则是数据容量和横向扩展问题。单机则是一切的基础也是上手最快的模式。1.1 单机模式最简单但也最容易被忽略风险单机模式就是一个Redis进程对外提供服务所有数据都存在这一台机器的内存和持久化文件里。你本地安装redis-server后默认端口6379跑起来的就是单机模式。这种模式的优势非常明显部署成本低、运维简单、没有节点间通信开销、数据一致性天然保证。开发调试阶段用它完全没有问题。缺点同样扎眼一台机器挂了Redis直接不可用数据量增长到单机内存上限扩容方案有限写请求和读请求都压在同一个节点上并发瓶颈很快到来。在Spring Boot里配置单机模式也是最省心的。只需要指定host、port、password再把database选好一个RedisTemplate就能直接注入使用。但要注意单机模式通常只适合以下场景开发环境、预发环境、业务量比较小的生产环境、或者已经有其他高可用方案兜底的服务。1.2 主从复制把数据安全感和读写能力提上去主从复制解决的是单点数据和单点故障问题。一个主节点若干个从节点主节点负责接收写命令从节点通过复制机制同步主节点数据同时可以承担读请求。Redis里复制数据的过程大致是从节点向主节点发送PSYNC命令主节点fork出子进程生成RDB快照发给从节点期间产生的增量写命令会缓存在复制积压缓冲区里之后继续通过命令流同步给从节点。在主从模式下主节点仍然只有一台一旦主节点宕机如果没有额外的故障转移机制从节点不会自动上位写服务就中断了。这是主从模式和哨兵模式最核心的区别。所以主从模式适合做数据备份和读写分离扩展高可用还得靠哨兵来补。Spring Boot直接配置主从复制其实没什么特别之处因为它只是把连接信息指向其中一个节点。如果你想在应用层做读写分离得给主节点和从节点各配一个连接工厂再分别封装写操作和读操作的RedisTemplate。我一般不建议新手一开始就自己封装读写分离先确保主从同步稳定再慢慢优化。1.3 哨兵模式在主从复制之上增加自动切换能力哨兵模式的核心是建一组哨兵进程专门用来监控Redis主从节点的运行状态。哨兵会定期向所有节点发送心跳命令某个主节点被判断为客观下线后哨兵集群会投票选出一个从节点晋升为新主节点并通知客户端更新连接信息。哨兵通常部署奇数个节点比如3个或5个内部通过类似Raft的一致性协议做领导者选举避免脑裂场景。哨兵模式下整个Redis系统对外仍然表现为一个主节点地址客户端连接到的实际上是哨兵然后由哨兵告诉客户端当前真正的master是谁。Spring Boot对哨兵的支持是原生集成的配置上要指定master名称和哨兵节点列表。这样配置之后当主节点发生故障切换Spring Data Redis会重新从哨兵获取主节点信息客户端感知到的是短暂的连接中断但不需要人工改配置。1.4 集群模式把数据分片到多台机器上Redis Cluster在Redis 3.0版本正式引入它把整个数据空间划分成16384个哈希槽每个节点负责其中一部分槽位。写入某个key时Redis会根据CRC16算法算出key属于哪个槽再由该槽所在的节点提供服务。节点数量可以通过水平扩容来增加数据也能在多个主节点之间均衡分布。集群模式解决了单机内存上限和大并发写入的问题也具备一定的容错能力每个主节点都可以挂若干从节点如果某个主节点挂了它的从节点会接替它继续服务。但集群带来的限制也很现实多key操作只有在所有key的哈希槽一致时才能执行比如事务、Lua脚本、跨key的rename操作都会受限。Spring Boot配置集群模式同样不复杂把集群所有节点地址填进去Spring Data Redis会自动完成槽位探测、节点发现和请求路由。但应用层代码需要遵守集群约束否则线上会出现MOVED、CROSSSLOT这类错误。四种模式的关键差异我用下面这个表格再压缩一遍方便你和业务需求对照。模式数据容量高可用能力读写扩展运维复杂度单机单节点内存无节点宕机即不可用有限单节点承载最低主从复制受限于主节点从节点冗余数据主节点故障需人工切换从节点可以扩展读较低哨兵模式受限于主节点自动故障切换高可用仍依赖主节点写可扩展读中等集群模式多主节点水平扩展主节点由从节点自动接管读写都可以分散多节点较高2. Spring Boot集成Redis的前置准备依赖、序列化与环境不管最终用哪种模式Spring Boot集成Redis的基础工作是一样的。先要把依赖加对、序列化策略想清楚、连接工厂选好再往上搭建各种模式不然后面配置集群或哨兵时容易把错误来源搞混。2.1 引入依赖时注意Spring Boot版本带来的配置前缀变化在Spring Boot项目中接入Redis常规做法是添加spring-boot-starter-data-redis依赖。这个起步依赖会把Spring Data Redis、连接工厂、RedisTemplate等核心组件全部引入进来。如果你用的是Maven以前的项目一般这么写dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId version2.7.18/version /dependency如果是Spring Boot 3.x起步依赖坐标不变但默认会和Java 17、Jakarta EE体系绑定。需要注意的配置项前缀变化是Spring Boot 2.x使用spring.redis开头的配置Spring Boot 3.0以后改成了spring.data.redis开头。这两种前缀不通用。网上很多教程没有注明版本直接把旧前缀配置复制到新工程里会发现Redis相关的自动配置似乎没生效。依赖引入时不需要手动添加Lettuce或Jedis库Spring Boot起步依赖里已经带上了默认客户端。但如果要显式切换客户端就得自己排除默认依赖再引入另一个客户端这一点后面细说。2.2 序列化策略不规划好后面全是乱码事Redis本身只存储字节数据不关心你存进去的Java对象是JSON还是JDK序列化的产物。Spring Data Redis默认用JdkSerializationRedisSerializer做对象的序列化这对熟悉原理的人来说问题不大但对业务系统而言非常不友好。最直接的表现是你用Redis Desktop Manager看缓存里的数据看到的是一长串以AC ED 00 05开头的二进制乱码Key也不直观难以排查线上问题。我的做法是给RedisTemplate统一指定key和value的序列化方式。key使用StringRedisSerializervalue使用GenericJackson2JsonRedisSerializer。这样存进去的对象自动转成JSON可读性大大提升绝大多数项目都能直接用。配置代码也不要写得太花哨够用即可import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; Configuration public class RedisConfig { Bean public RedisTemplateString, Object redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplateString, Object template new RedisTemplate(); template.setConnectionFactory(connectionFactory); StringRedisSerializer stringSerializer new StringRedisSerializer(); GenericJackson2JsonRedisSerializer jsonSerializer new GenericJackson2JsonRedisSerializer(); template.setKeySerializer(stringSerializer); template.setHashKeySerializer(stringSerializer); template.setValueSerializer(jsonSerializer); template.setHashValueSerializer(jsonSerializer); template.afterPropertiesSet(); return template; } }注意GenericJackson2JsonRedisSerializer在序列化时会写入对象类型信息反序列化时才能恢复成正确的Java对象。如果业务里对JSON格式有洁癖也可以自己定义ObjectMapper但普通项目里用默认的就够了。2.3 连接客户端选型Lettuce还是JedisSpring Boot默认Lettuce它对Redis Cluster和哨兵模式的支持也更完善。Lettuce本身基于Netty使用单连接多路复用的机制在大多数并发场景下节省资源。Jedis更偏向传统阻塞IO模型每申请一个连接都需要走网络握手高并发环境下更容易出现连接数不足的问题。除非是团队里有人特别熟悉Jedis或者历史项目一直用Jedis否则我建议直接用Lettuce。后续配置池化参数时Lettuce和Jedis的配置前缀有差异这个我会在单机模式章节给出一份完整的配置。3. 单机模式配置从最简起步到连接池调优单机模式是其他所有模式的基础。先把这一套配置跑通再谈主从、哨兵、集群思路会清晰很多。3.1 一份可以直接使用的Spring Boot单机配置在application.yml中如果用的是Spring Boot 3.x默认配置如下spring: data: redis: host: 127.0.0.1 port: 6379 database: 0 password: yourpassword timeout: 3s lettuce: pool: max-active: 16 max-idle: 8 min-idle: 0 max-wait: 3s如果你的项目还在Spring Boot 2.x上把前缀改成spring.redis即可其他字段含义一致。注意database这个参数很多教程喜欢在这里写个1或者2来区分业务缓存实际使用中Redis默认有16个数据库线上我基本只用0号库。如果确实要隔离我更推荐直接用不同key前缀或者拆Redis实例因为集群模式下database 0以外的库并不支持。password字段如果没有设置就注释掉或者留空。如果开启了Redis的protected-mode并设置了密码这里不填启动时会直接报NOAUTH Authentication required。timeout字段是连接超时时间线上一般设3秒到5秒。如果Redis响应很慢设得太短会导致大量请求提前超时设得太长又会让线程长时间卡住要根据业务接口的耗时来决定。3.2 Lettuce连接池参数的直观理解连接池参数看起来不多但含义容易混淆。max-active代表连接池中最多可以有多少个活跃连接好比一条高速公路的收费站最多同时放行多少辆车。max-idle是最多保留多少个空闲连接空闲连接过多占用内存过少又可能在突发流量时来不及创建新连接。max-wait是当连接池资源耗尽时新请求最多等待多长时间再报错等待时间设成3秒意味着超过3秒还拿不到连接就会抛出连接池耗尽异常。在单机模式下我建议起步阶段用一组保守参数max-active不超过CPU核数的两倍max-idle保持和min-idle一致可以避免频繁创建销毁连接。等到压测时再根据实际线程数调整而不是一上来就调大否则连接池反而变成新的瓶颈。3.3 快速验证单机配置是否生效配置写完以后最简单的验证方式就是在启动类里临时注入RedisTemplate然后在ApplicationRunner里执行一次set操作import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; Component public class RedisConnectChecker implements ApplicationRunner { private final RedisTemplateString, Object redisTemplate; public RedisConnectChecker(RedisTemplateString, Object redisTemplate) { this.redisTemplate redisTemplate; } Override public void run(ApplicationArguments args) { String key boot:connect:test; redisTemplate.opsForValue().set(key, ok); Object value redisTemplate.opsForValue().get(key); System.out.println(Redis connect test result: value); } }看到控制台输出ok的字符串说明连接和序列化都正常。如果看到拒绝连接或者反序列化异常那就反过来检查host、port、password和database序号。这一步最考验耐性但值得先跑通。4. 主从复制与哨兵模式配置高可用才是核心目标很多人跑通单机模式后马上就想上哨兵。这里我要提醒一句哨兵模式的前提是主从复制已经稳定工作所以在配置Spring Boot之前至少先搭建好一主一从或者一主多从的Redis节点。如果连主从同步都做不好哨兵切换再顺数据完整性也没法保证。4.1 先把主从复制搭建起来搭建主从复制本身不复杂。假设我已经有一台主节点运行在127.0.0.1:6379现在要加一个从节点运行在127.0.0.1:6380。只需要在第二台Redis的配置文件里加一行replicaof 127.0.0.1 6379如果是老版本Redis可能会看到slaveof这个写法效果一样。修改完配置文件后启动实例在主节点上执行info replication就能看到从节点已经接入。此时向主节点写入的数据会自动同步到从节点。主从模式下有个容易误判的点如果Redis实例开启了密码复制链路上也需要配置相同的密码否则主从同步会反复失败。通常方式是给主节点和从节点设置同样的requirepass同时在从节点的配置文件里配置masterauth填主节点的密码。4.2 应用层如何对接主从架构Spring Boot原生的Redis配置对象只能填写一个standalone host和port所以主从架构下最直接的做法还是连接主节点让写请求和读请求都走主节点。从节点更多的意义是热备份以及当主节点故障时可以被哨兵提升为新的主节点。如果业务确实要求读请求分散到从节点从而缓解主节点的读压力就需要自己实现路由。常见做法是定义两个连接工厂一个指向主节点一个指向从节点然后封装一个自定义的RedisTemplate或者工具类读操作走从节点的template写操作走主节点的template。这里不推荐自己用代码判断当前节点是不是master然后动态切换。主从模式下从节点挂掉一样会有部分读失败你要有自己的降级策略比如读请求临时切回主节点。4.3 哨兵模式在Spring Boot中的标准配置哨兵模式的搭建需要至少三个Sentinel进程分别跑在26379端口上。配置Spring Boot时不需要填写具体的master地址而是告诉它哨兵节点在哪、master在哨兵里叫什么名字。在Spring Boot 3.x的配置文件中spring: data: redis: password: yourpassword sentinel: master: mymaster nodes: - 127.0.0.1:26379 - 127.0.0.1:26380 - 127.0.0.1:26381在Spring Boot 2.x中把spring.data.redis改为spring.redis即可。这里的password是哨兵监控的Redis节点密码一般指Redis实例自身的requirepass。如果哨兵节点本身也配置了密码Spring Data Redis也支持哨兵密码配置但Spring Boot的application.yml里不一定有直接对应的属性很多时候需要走Java配置类。如果想用Lettuce的自动故障转移能力还有一种灵活的Java配置方式import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisPassword; import org.springframework.data.redis.connection.RedisSentinelConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; Configuration public class SentinelConfig { Bean public LettuceConnectionFactory lettuceConnectionFactory() { RedisSentinelConfiguration sentinelConfig new RedisSentinelConfiguration() .master(mymaster) .sentinel(127.0.0.1, 26379) .sentinel(127.0.0.1, 26380) .sentinel(127.0.0.1, 26381); sentinelConfig.setPassword(RedisPassword.of(yourpassword)); return new LettuceConnectionFactory(sentinelConfig); } }这种配置方式能更精确地控制Sentinel密码、主节点密码等细节也更适合在Spring Boot自动配置不满意的时候介入。验证哨兵配置是否生效可以这么做先人工方式停掉当前master节点观察哨兵日志是否完成主从切换。切换完成后再检查Spring Boot应用日志正常情况下应该能看到连接被关闭随后自动恢复并连接到新的master。如果应用侧迟迟不恢复那就涉及Lettuce的拓扑刷新具体排查我在第六章写清楚。5. 集群模式配置多节点水平扩展的正确打开方式集群模式和前面几种模式有很大不同。集群模式下客户端需要知道每个key的哈希槽分布在哪个节点上一开始连上任意一个节点后客户端会自动学习整个集群的slot分布后续请求直接路由到正确的节点。如果集群扩容或者节点故障导致slot重新分配客户端需要对MOVED和ASK错误进行处理。5.1 搭建Redis Cluster的最低要求生产环境至少3个主节点、3个从节点即6个Redis进程。每个主节点分布一部分哈希槽每个从节点作为对应主节点的备份。用docker-compose搭建时通常会为每个节点准备独立的data目录和redis.conf。为了演示Spring Boot配置我把最关键的cluster相关参数列出来port 7001 cluster-enabled yes cluster-config-file nodes-7001.conf cluster-node-timeout 15000 appendonly yes protected-mode nocluster-enabled yes是开启集群功能最核心的一项。关掉protected-mode是为了让集群节点之间能完成通信。节点全部启动后需要通过redis-cli把节点聚合成集群例如redis-cli --cluster create \ 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 \ 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 \ --cluster-replicas 1如果一切顺利终端会提示16384个槽已经全部分配完毕每个主节点都接上了至少一个从节点。5.2 Spring Boot中配置cluster节点列表Spring Boot里配置集群并不需要把6个节点全写上去但为了可用性最好把主节点和从节点都填上。客户端启动时会主动感知集群拓扑后续会自动处理节点间路由。在Spring Boot 3.x中配置如下spring: data: redis: password: yourpassword cluster: nodes: - 127.0.0.1:7001 - 127.0.0.1:7002 - 127.0.0.1:7003 - 127.0.0.1:7004 - 127.0.0.1:7005 - 127.0.0.1:7006 max-redirects: 3 lettuce: cluster: refresh: adaptive: true period: 30smax-redirects表示一次操作请求最多跟随多少次MOVED重定向。配置太大会掩盖路由问题太小又可能在节点迁移过程中造成不必要的失败我一般设3到5。又到了集群使用必须要面对的限制多key操作。在Redis Cluster中只有所有key的哈希槽一致时才能执行多个key的原子操作。如果你硬要执行MSET或Lua脚本Redis会返回CROSSSLOT错误。解决办法是使用哈希标签也就是给key加一个带花括号的公共子串让Redis按照花括号里的内容计算哈希槽。例如把业务id作为标签让相关key都落到同一个槽位。5.3 集群模式下的模板使用经验Spring Data Redis针对集群这套逻辑已经封装得比较好。你注入RedisTemplate之后底层会自动处理MOVED、ASK重定向普通业务代码基本感受不到集群的存在。但要注意几个容易踩坑的地方。事务支持在集群模式下非常受限MULTI/EXEC事务只能在同一槽位的多个key上执行跨槽位就报错。Lua脚本同样需要脚本里涉及的key都在同一个槽位。管道操作在集群中也比单机复杂得多不是简单把所有命令塞到同一个管道就能保证性能。用集群做分布式锁时要格外小心。RedissonFairLock、RedLock这些分布式锁方案在集群模式下的可用性需要结合业务对一致性的要求来判断常规的单节点SETNX锁在故障转移瞬间可能会出现锁丢失这是Redis集群本身的AP属性决定的不要因为代码能跑通就忽视这个风险。6. 配置后的故障排查与避坑实录这一章全部来自我在真实项目里验证过的排查思路。你会发现很多故障不是Redis本身的问题而是配置和应用层理解不到位造成的。6.1 无法连接Redis先分清是哪一层断了最常见的报错是Unable to connect to Redis后面跟着ConnectException: Connection refused或Connection timed out。遇到这种错误先别急着看Spring配置先用redis-cli在应用所在机器上手动执行一次PING命令。本地能PING通说明Redis进程和端口没问题再检查Spring Boot配置里的host、port、password、database是否和redis-cli执行时使用的一致。本地也连不上就要看Redis进程是否存活、端口监听是否正常、有没有防火墙或者云安全组拦着。很多内网环境只放行了6379但集群或哨兵用的26379、7001这些端口没有放行最后排查出一堆网络层面的问题。如果是启动后一小时才开始报警多半是连接池或者服务端连接数达到上限了。Lettuce单连接模型在超高并发下也会遇到连接耗尽检查Redis的maxclients和服务端连接数同时看应用日志里有没有RedisConnectionFailureException。6.2 配置前缀错误导致什么都没生效前面反复强调Spring Boot 2.x用spring.redis.Spring Boot 3.x用spring.data.redis.。有一个很容易误解的场景是项目升到Spring Boot 3后旧配置还留在yml里启动时并没有报错因为Spring Boot不再认识这个前缀也不会强行校验未知配置项结果RedisTemplate拿到的连接工厂完全没有使用你填的那台Redis默认走127.0.0.1:6379。遇到这种很诡异的故障排查办法很简单在启动日志里搜Redis相关AutoConfiguration的日志或者直接打印RedisConnectionFactory连接的地址。如果你看到host还是默认值第一反应就应该是配置前缀写错了。6.3 哨兵切换后应用迟迟连不上新主节点哨兵完成了自动切换应用却仍然报错或者无法恢复这种现象在早期Redis客户端里比较常见。因为客户端缓存了旧master的连接信息哨兵切换后客户端要继续保持旧连接直到连接被断开。Spring Data Redis默认使用的Lettuce在新版本中已经支持自动刷新集群和哨兵拓扑但部分Spring Boot版本需要显式开启。如果是哨兵模式重点检查连接工厂用的是不是LettuceConnectionFactory并且确认sentinel配置里的master名称和哨兵配置文件里的master名称完全一致。大小写不一致、多了个空格都会导致客户端反复从哨兵拿不到正确的master地址。实在不行就把Java配置里的RedisSentinelConfiguration拉出来在测试代码里主动调用getMaster方法看看返回的节点地址是否符合预期。这能快速区分是哨兵配置问题还是客户端引用问题。6.4 集群模式下的MOVED和CROSSSLOT错误集群模式下如果配置只写了一个节点客户端发送key请求时如果那个key的槽位不在该节点会收到MOVED重定向。Spring Data Redis内置了底层重定向处理只要max-redirects配置合理就能自动跟随。但假如你在一个操作里同时访问了好几个key而这些key没有落在同一个哈希槽就会返回CROSSSLOT错误。解决办法不是去关掉集群也不是提升max-redirects。而是要从业务上调整key的设计使用哈希标签把需要绑定操作的key固定到同一个槽位。Redis的哈希标签规则很简单key里有花括号时key的实际哈希只针对花括号内的字符串比如cache:{order}:1001和cache:{order}:1002的哈希槽只由order决定。6.5 数据乱码和反序列化异常系统运行正常但Redis Desktop Manager里全是类似\xAC\xED\x00\x05t的乱码这是默认JDK序列化器在作怪。此时的value虽然也能正常读写但运维人员排查缓存时非常痛苦而且JDK序列化对象还要考虑类版本兼容问题稍微改动类结构就可能反序列化失败。还有一种情况是使用了GenericJackson2JsonRedisSerializer之后自己用String类型写入了缓存再用RedisTemplate读取结果类型转换报错。这通常是因为value序列化器不统一。最简单的做法是纯字符串的缓存用StringRedisTemplate对象缓存用自定义的RedisTemplate两套模板各自命名清楚避免混用。6.6 连接池耗尽和超时参数调优速查现象可能原因处理思路Connection timeoutRedis单机过载或网络拥塞调大timeout检查Redis slowlogRedis connection pool exhaustedmax-active过小或连接泄漏检查业务是否正确关闭连接调大max-activeNOAUTH Authentication requiredpassword未填写或写错和redis.conf中requirepass对比MOVED重定向集群节点路由信息过期开启Lettuce集群拓扑刷新或适当调大max-redirectsCROSSSLOT操作受限集群下多key操作跨槽用哈希标签聚合key槽位哨兵切换后重连慢客户端拓扑刷新关闭或配置错误打开刷新机制检查sentinel master名称连接池参数最好不要拍脑袋定。先压测得到TPS和平均耗时然后计算每分钟新增连接数再看空闲连接被回收的速率据此调整max-active和max-idle。我见过一个项目把max-active设成512结果高并发下一堆线程挤在连接池等待Redis本身却非常空闲。连接池的合理值一般和业务线程池大小、IO耗时强相关不是越大越好。如果你现在还在调试阶段我个人的建议是先跑通单机模式把序列化、连接池、模板注入这些基础都验证一遍再逐步升级到主从、哨兵、集群。每一步切换都单独做一次验证别一次性把所有节点都上线。尤其是集群和哨兵模式部署脚本越稳重后续故障越少。最后分享一个小技巧我在项目里习惯给不同的Redis连接工厂起明确的bean名称比如redisTemplateSingle、redisTemplateSentinel、redisTemplateCluster。这样在代码里看到哪个模板报错就能直接对应到配置不用再花时间推测当前代码使用的是哪套连接。处理Redis这种中间件最大的成本永远不是部署而是出了问题以后还要靠猜来定位原因。
返回列表