在分布式系统中,Redisson 的调优是提升性能、稳定性和资源利用率的关键。以下是针对 Redisson 的详细调优策略和实践:
1. 连接池与网络优化
1.1 连接池参数
# application.yml 或 Redisson Config 中配置
singleServerConfig:
connectionPoolSize: 128 # 最大连接数(默认64)
connectionMinimumIdleSize: 32 # 最小空闲连接(默认10)
idleConnectionTimeout: 30000 # 空闲连接超时(默认10000ms)
connectTimeout: 5000 # 连接超时(默认3000ms)
timeout: 3000 # 命令等待超时(默认3000ms)
- 建议:根据并发量和业务负载调整,监控连接池利用率(如
redisson.connection.active
指标)。
1.2 Netty 线程模型优化
Config config = new Config();
// 调整 Netty 线程数(默认CPU核心数*2)
config.setNettyThreads(32); // I/O 线程(处理网络通信)
config.setEventLoopGroup(new NioEventLoopGroup(16)); // 事件处理线程
- 场景:高并发或大量异步操作时,避免线程竞争导致吞吐量下降。
2. 分布式锁优化
2.1 锁超时与续期
RLock lock = redissonClient.getLock("orderLock");
try {
// 设置明确的锁持有时间,避免依赖看门狗(默认30秒续期)
boolean acquired = lock.tryLock(5, 15, TimeUnit.SECONDS); // 等待5秒,锁持有15秒
if (acquired) {
// 业务逻辑(确保执行时间 < 15秒)
}
} finally {
lock.unlock();
}
-
关键点:
- 避免锁持有时间过长,导致其他线程长时间等待。
- 明确指定
leaseTime
可禁用看门狗自动续期,减少不必要的续期开销。
2.2 锁粒度优化
-
细粒度锁:对资源分段加锁(如按订单ID哈希取模)。
String lockKey = "orderLock:" + orderId % 16; // 分为16个锁段 RLock lock = redissonClient.getLock(lockKey);
-
读写锁:区分读多写少场景。
RReadWriteLock rwLock = redissonClient.getReadWriteLock("resourceLock"); rwLock.readLock().lock(); // 共享读锁 rwLock.writeLock().lock(); // 排他写锁
3. 序列化优化
3.1 选择高效序列化方式
config.setCodec(new MsgPackJacksonCodec()); // MsgPack 二进制协议(默认JSON)
// 或
config.setCodec(new KryoCodec()); // Kryo(高性能但需注册类)
-
对比:
- JSON:可读性好,但性能较低。
- MsgPack:体积小,序列化速度快。
- Kryo:性能最优,但需手动管理类注册。
3.2 避免大对象序列化
-
对大型对象(如
List<User>
)进行分页存储或压缩:RList<User> userList = redissonClient.getList("users"); userList.addAll(users.subList(0, 100)); // 分批次存储
4. 数据结构与命令优化
4.1 选择合适的数据结构
场景 | 推荐数据结构 | 优势 |
---|---|---|
实时排行榜 | RScoredSortedSet | 支持按分数范围查询,自动排序 |
分布式去重 | RHyperLogLog | 低内存占用,统计唯一值 |
高频计数器 | RAtomicLong | 原子操作,高性能 |
发布订阅 | RTopic | 支持多播,异步消息传递 |
4.2 批量操作与管道
RBatch batch = redissonClient.createBatch();
batch.getMap("data").fastPutAsync("k1", "v1");
batch.getMap("data").fastPutAsync("k2", "v2");
BatchResult<?> result = batch.execute();
- 优势:减少网络往返次数,提升吞吐量。
5. 内存与GC优化
5.1 限制缓存大小
RMapCache<String, User> cache = redissonClient.getMapCache("userCache");
cache.setMaxSize(10000); // 限制最大条目数
cache.setTimeToLive(1800, TimeUnit.SECONDS); // 全局TTL
- 避免内存溢出:通过
maxSize
和TTL
控制内存占用。
5.2 JVM 参数调优
# 启动参数示例
java -Xms4g -Xmx4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 ...
-
关键参数:
-Xmx
:堆内存大小(建议不超过物理内存的50%)。-XX:+UseG1GC
:G1垃圾回收器适合大内存场景。-XX:MaxDirectMemorySize
:限制堆外内存(Netty使用)。
6. 监控与诊断
6.1 集成 Prometheus
<!-- 添加依赖 -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.23.4</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
-
指标示例:
redisson_execution_latency
:命令执行延迟。redisson_connection_active
:活跃连接数。
6.2 日志调优
logging:
level:
org.redisson: WARN # 生产环境避免DEBUG级别日志
7. 高可用与故障转移
7.1 集群模式配置
spring:
redis:
cluster:
nodes: redis-node1:6379,redis-node2:6379,redis-node3:6379
scan-interval: 5000 # 节点发现间隔(默认1000ms)
config.useClusterServers()
.setScanInterval(5000) // 节点发现频率
.setRetryAttempts(3) // 命令重试次数
.setRetryInterval(1500); // 重试间隔
7.2 哨兵模式配置
spring:
redis:
sentinel:
master: mymaster
nodes: sentinel1:26379,sentinel2:26379
password: "your_password"
config.useSentinelServers()
.setMasterName("mymaster")
.addSentinelAddress("redis://sentinel1:26379", "redis://sentinel2:26379");
8. 流量控制与限流
8.1 使用 RRatelimiter
RRateLimiter rateLimiter = redissonClient.getRateLimiter("apiLimit");
rateLimiter.trySetRate(RateType.OVERALL, 100, 1, RateIntervalUnit.SECONDS); // 每秒100次
if (rateLimiter.tryAcquire()) {
// 执行业务
}
9. 高级调优技巧
9.1 禁用不必要的功能
config.setUseScriptCache(false); // 禁用LUA脚本缓存(默认启用)
config.setLockWatchdogTimeout(30000); // 调整看门狗超时(默认30秒)
9.2 优化本地缓存
LocalCachedMapOptions<String, User> options = LocalCachedMapOptions.defaults()
.cacheSize(1000) // 本地缓存大小
.evictionPolicy(EvictionPolicy.LRU) // 淘汰策略
.timeToLive(10, TimeUnit.MINUTES);
RMap<String, User> map = redissonClient.getLocalCachedMap("users", options);
10. 典型调优场景
场景1:高并发锁竞争
-
优化策略:
- 使用
RedLock
多节点锁提升可用性。 - 降低锁粒度(如按业务ID分片)。
- 设置合理的
leaseTime
避免看门狗频繁续期。
- 使用
场景2:缓存穿透
-
优化策略:
- 使用
RBloomFilter
过滤无效请求。 - 对空结果设置短TTL:
cache.put("key", null, 10, TimeUnit.SECONDS);
- 使用
总结
- 性能优先:根据监控数据调整连接池、线程池参数。
- 资源可控:限制缓存大小,避免内存泄漏。
- 容灾设计:配置集群/哨兵模式,启用持久化。
- 持续监控:通过指标(如QPS、延迟、连接数)发现瓶颈。
通过以上调优手段,可显著提升 Redisson 在分布式锁、缓存、队列等场景下的性能,同时保障系统的稳定性和可扩展性。