Redisson 配置速查:最小可用配置、连接池调优与踩坑处理
【免费下载链接】redissonRedisson: Valkey & Redis Java Client and Real-Time Data Platform. Sync/Async/RxJava/Reactive API. Over 50 Valkey and Redis based Java objects and services: Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Bloom filter, Spring, Tomcat, Scheduler, JCache API, Hibernate, RPC, local cache..项目地址: https://gitcode.com/GitHub_Trending/re/redisson
连接池参数设错,线上 Redisson 客户端就会频繁重建连接、锁看门狗行为异常。本文按"单机 → 集群 → 哨兵 → Spring Boot"四类场景给出最小可用配置和参数取值依据,读完能直接套用,并知道压测后该动哪几个数字。
先搞清楚:这套配置到底在配什么
Redisson 所有模式(单机、主从、哨兵、集群)共用一个Config对象,配置分两层:全局层(线程、编解码、看门狗)和模式层(地址、连接池、扫描间隔)。全局层定义在redisson/src/main/java/org/redisson/config/Config.java,各模式的连接池参数散落在同目录的SingleServerConfig、ClusterServersConfig等类里,官方完整字段说明见docs/configuration.md。
| 参数 | 源码默认值 | 作用 |
|---|---|---|
connectionPoolSize | 64 | 每条连接池的最大连接数,决定单机吞吐上限 |
connectionMinimumIdleSize | 24 | 最小空闲连接,突发流量下免冷启动 |
connectTimeout | 10000ms | TCP 建连超时,不是命令超时 |
timeout | 3000ms | 命令发出后的应答超时,超时未返回即失败 |
retryAttempts | 4 | 命令发送失败后的重试次数 |
idleConnectionTimeout | 10000ms | 空闲连接回收阈值,连接数高于最小空闲值时才回收 |
threads/nettyThreads | 16 / 32 | 业务回调线程数 / Netty IO 线程数 |
codec | Kryo5Codec | 数据序列化方案,影响体积、速度和跨语言兼容性 |
lockWatchdogTimeout | 30000ms | 分布式锁看门狗续期周期 |
集群scanInterval | 5000ms | 集群拓扑扫描间隔,节点扩缩容后多久生效 |
⚠️ 注意:retryInterval已在源码中标记为废弃,重试间隔改用retryDelay的延迟策略(如EqualJitterDelay)控制,旧配置里写这个字段只会收到警告日志。
按部署场景对号入座
单机:YAML 五分钟内跑通
singleServerConfig: address: "redis://127.0.0.1:6379" database: 0 connectionPoolSize: 32 connectionMinimumIdleSize: 16 connectTimeout: 5000 timeout: 1000 retryAttempts: 3 password: "yourpassword" threads: 8 nettyThreads: 16加载方式:Config.fromYAML(new File("redisson.yaml"))后交给Redisson.create(config)。
为什么这么设:
connectionPoolSize从默认的 64 降到 32,是因为单机开发/中小规模下 64 条长连接会推高 Redis 端maxclients压力,32 已覆盖多数接口 QPS;timeout收到 1000ms:命令超时设太大会让慢查询把线程挂死,快速失败交给上层重试更可控;address支持${VAR}变量语法(环境变量优先于系统属性),同一份 YAML 可复用到多环境。
集群:程序化配置 + 读策略
Config config = new Config(); config.useClusterServers() .addNodeAddress("redis://10.0.0.1:7000", "redis://10.0.0.2:7000", "redis://10.0.0.3:7000") .setPassword("yourpassword") .setMasterConnectionPoolSize(32) .setSlaveConnectionPoolSize(32) .setReadMode(ReadMode.SLAVE) .setSubscriptionMode(SubscriptionMode.SLAVE) .setScanInterval(5000); RedissonClient client = Redisson.create(config);为什么这么设:
- 集群只要求给出部分节点地址,其余拓扑靠
CLUSTER SLOTS自动发现,nodeAddresses里放 3 个不同 master 即可; - ✅
ReadMode.SLAVE把读流量分摊到从节点,主节点只扛写;纯读场景收益最大,但要求从节点复制延迟可接受; SubscriptionMode控制 pub/sub 订到哪个角色,订阅量大的业务选 SLAVE 可避免打满主节点连接数。
哨兵:把主节点名字交给哨兵
sentinelServersConfig: sentinelAddresses: - "redis://10.0.0.1:26379" - "redis://10.0.0.2:26379" masterName: "mymaster" slaveConnectionPoolSize: 32 masterConnectionPoolSize: 32 password: "yourpassword"为什么这么设:
- 代码里不写任何数据节点地址,主/从全部由
masterName向哨兵查询得到,主切换后下一次查询自动跟随新主; sentinelAddresses至少配 2 个,避免单个哨兵故障时客户端失去寻址能力;- 哨兵模式下
scanInterval默认 1000ms,比集群的 5000ms 更激进,因为主切换需要更快感知。
Spring Boot:一个属性指向 YAML
Starter 的RedissonAutoConfiguration读取前缀为spring.redis.redisson的属性(见redisson-spring/redisson-spring-boot-starter/src/main/java/org/redisson/spring/starter/RedissonAutoConfiguration.java),源码侧对应RedissonProperties,只有file与config两个字段:
# 二选一:文件路径 或 直接内联 YAML 文本 spring.redis.redisson.file=classpath:redisson.yaml若不想维护 YAML,也可以直接注册 Bean:
@Configuration public class RedissonConfig { @Bean(destroyMethod = "shutdown") public RedissonClient redissonClient() { Config cfg = new Config(); cfg.useSingleServer().setAddress("redis://10.0.0.1:6379"); return Redisson.create(cfg); } }注意 Bean 上保留destroyMethod = "shutdown",否则容器关闭时连接池不会释放,日志里会留一堆未关闭的 Netty channel。
让性能跟上来
三个维度(线程、序列化、连接)合并成一张表,按适用条件取用:
| 参数 | 建议值 | 适用条件 |
|---|---|---|
threads | 2 × CPU 核数(默认 16) | 回调里有较重业务逻辑(反序列化、加锁判断)时上调 |
nettyThreads | 4 × CPU 核数(默认 32) | 高连接数 + 高消息频率,IO 成为瓶颈时上调 |
codec | 纯 Java 生态用 Kryo5(默认);跨语言/需人工读数据换JsonJacksonCodec | JSON 体积约为二进制 2~3 倍,带宽紧张时别用 |
connectionPoolSize | 按QPS × 平均命令耗时(ms) / 1000估算,向上取整留 20% | 压测时观察连接等待队列,池子打满再加大,不要拍脑袋给 200 |
connectionMinimumIdleSize | 约为池子的 50% | 突发流量场景,避免峰值瞬间集中建连 |
idleConnectionTimeout | 默认 10000ms;NAT/防火墙环境调大到 30000ms 以上 | 小于中间设备断连空闲阈值时,连接会被"半路切断" |
lockWatchdogTimeout | 默认 30000ms,续期周期约为其 1/3 | 业务持锁时间远超默认值时单独调整,别全局放宽 |
💡 一个容易忽略的点:threads和nettyThreads是每客户端实例的量。同一进程里创建多个RedissonClient时,线程总量要合并核算,否则实际线程数是配值的 N 倍。
踩坑速查
| 症状 | 常见原因 | 动作 |
|---|---|---|
启动即RedisConnectionException,提示连接超时 | connectTimeout与网络实际 RTT 不匹配;地址写错协议(rediss://连到非 TLS 端口) | 先telnet验证端口连通性;核对 scheme 前缀;跨网段把connectTimeout提到 5000 以上 |
| 读写报序列化/反序列化异常,或旧数据读不出 | 换了 codec(Kryo5 ↔ JSON),历史数据的字节结构不兼容 | codec 一旦上线不可随意更换;新旧客户端同版本发布,必要时双读过渡 |
| 集群扩缩容后请求持续路由到旧节点 | scanInterval未到扫描周期,拓扑未刷新 | 短期手动重建客户端;长期把scanInterval调小,但别低于 2000ms,避免CLUSTER SLOTS风暴 |
| 分布式锁"莫名释放",业务并发冲突 | 看门狗续期任务被 GC 长停顿或threads池饥饿拖垮 | 检查threads是否被业务逻辑占满;确认锁对象在同一 JVM 生命周期内未重复 unlock |
| 空闲一段时间后首条命令报连接断开 | idleConnectionTimeout小于防火墙/NAT 的空闲断连时间,池里留了"尸体连接" | 把idleConnectionTimeout调小到低于中间设备空闲阈值,让客户端主动回收 |
收尾清单
- 开发/测试环境用 YAML(
${VAR}变量化端口和密码),生产环境保持文件配置并纳入配置中心,程序化配置只用于需要按机器规格动态算线程数的场景; - 上线前固定一次 codec 选型并写进代码评审 checklist,序列化方案变更等同于数据迁移;
- 连接池参数以压测数据为准:等待队列空着就把池子调小,打满就按估算公式加大,禁止直接给最大值;
- 每 3 个月核对一次
Config.java默认值变更(如重试策略、DNS 监控参数),避免"没配"和"默认改了"之间的行为漂移; - 客户端实例数 × 每实例线程数 = 进程总线程预算,多客户端场景先算账再配置。
【免费下载链接】redissonRedisson: Valkey & Redis Java Client and Real-Time Data Platform. Sync/Async/RxJava/Reactive API. Over 50 Valkey and Redis based Java objects and services: Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Bloom filter, Spring, Tomcat, Scheduler, JCache API, Hibernate, RPC, local cache..项目地址: https://gitcode.com/GitHub_Trending/re/redisson
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考