Redisson/Jedis 线程数不足报错问题的思考

redisson,jedis,线程,不足,报错,问题,思考 · 浏览次数 : 385

小编点评

**分析问题核心:** * 高并发情况下,jedis中客户端创建的连接数量超过了可配置的连接池数,导致异常。 * 解决方案是增加`nettyThreads`值来设置连接池的数量,但仅缓解问题并增加系统开销。 **衍生问题:** 1. **线程切换过多导致网络性能下降** 2. **设置多个redis连接池可能导致连接竞争** 3. **使用多个redis节点连接集群可能导致性能下降** **解决方案:** 1. **调整`nettyThreads`值**:降低线程数以减少开销,但可能影响性能。 2. **优化代码以减少redis连接数量**,例如减少使用多个连接池或使用批量操作。 3. **使用单台redis节点连接集群**,减少客户端连接数量。 4. **使用连接池监控工具**,实时检测连接数和性能。 **其他建议:** * 考虑使用其他连接池监控工具,例如 `Redisson` 中的 `RedisPoolConfig` 类。 * 可以使用 `redis.info()` 方法获取连接池信息,以便进行性能分析。 * 建议在生产环境中测试和优化redis配置。

正文

Redisson/Jedis 线程数不足报错问题的思考


背景

最近公司内总出现 Redis相关的错误
!-_-! 看我最近发的博客就可以看的出来.

这个错误提示其实是 两年前 清明节进行 压测时发现的.
当时其实没有将这个问题细致分析下去. 
最近学习的比较多. 感觉可以尝试分析一下这个问题. 

报错的详细信息

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Fri Apr 02 11:38:27 GMT+08:00 2021
There was an unexpected error (type=Internal Server Error, status=500).
Unable to send command! Try to increase 'nettyThreads' and/or connection pool size settings Node source: NodeSource 
[slot=2958, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0,
freeSubscribeConnectionsCounter=value:50:queue:0, freeConnectionsAmount=29, freeConnectionsCounter=value:61:queue:0, freezed=false, 
freezeReason=null, client=[addr=redis://127.0.0.1:7000], nodeType=MASTER, firstFail=0]]], connection: RedisConnection@1228620800 
[redisClient=[addr=redis://127.0.0.1:7000], channel=[id: 0x6e9362f5, L:/127.0.0.1:55126 - R:127.0.0.1/127.0.0.1:7000], currentCommand=null],
command: (HMSET), params: [[99, 97, 102, 45, 115, 101, 115, 115, 105, 111, ...], [108, 97, 115, 116, 65, 99, 99, 101, 115, 115, ...], 
[-84, -19, 0, 5, 115, 114, 0, 14, 106, 97, ...]] after 3 retry attempts; nested exception is org.redisson.client.RedisTimeoutException:
Unable to send command! Try to increase 'nettyThreads' and/or connection pool size settings Node source: NodeSource [slot=2958, addr=null, 
redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=value:50:queue:0,
freeConnectionsAmount=29, freeConnectionsCounter=value:61:queue:0, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7000], 
 nodeType=MASTER, firstFail=0]]], connection: RedisConnection@1228620800 [redisClient=[addr=redis://127.0.0.1:7000], 
channel=[id: 0x6e9362f5, L:/127.0.0.1:55126 - R:127.0.0.1/127.0.0.1:7000], currentCommand=null], command: (HMSET), params: 
[[99, 97, 102, 45, 115, 101, 115, 115, 105, 111, ...], [108, 97, 115, 116, 65, 99, 99, 101, 115, 115, ...], [-84, -19, 0, 5, 115, 114, 0, 14, 106, 97, ...]] 
after 3 retry attempts

本问题的思考

这个问题的核心其实很简单:
高并发情况下jedis后者是redisson的客户端需要创建太多的连接池, 连接池数不足时就会出现异常. 导致报错.
但是这个问题也说明, 我们的redis客户端,或者是我们的使用方式存在问题,可能有太多的独占的连接, 非短促型的导致大量的线程使用. 

另外此问题可能会有如下几个衍生的问题: 
1. 如果很多应用服务器 redis 的client 会很多 , client很多之后 
   redis的epoll的 io多路复用的 路径选择性能会下降. 而且也会产生大量的tcp 连接. 对系统层也不友好. 
2. 应用服务器如果netty有限 会偶发性的出现错误. 导致客户响应不好. 
   如果满足应用服务器的要求可能会对redis节点产生大量的redis连接. 甚至会超过redis服务器的限制. 
3. 集群模式下因为应用服务器需要与所有的节点进行联系, 3主3从的节点理论上会使用六倍左右的线程数,
   应用服务器的线程数量会剧增, 线程切换增多, 性能会下降. 对每个redis节点的的压力也不好

错误问题解决

1. 理论上通过增加redisson后者是jedis的线程数来进行解决. 
2. 解决方式也表简单. 通过修改配置就可以了. 

下面会给出两个例子, 可以修改 max 值来增加threads的线程数. 

理论上可以解决这个问题 但是这样仅是缓解 和 水多了加面来处理. 
理论redis的没一个请求都是毫秒级给予结果, 理论上使用都是短促的. 
应该通过优化代码来避免长时间占用这么多连接

jedis的设置

  redis:
    cluster:
      max-redirects: 3
      nodes: 10.110.139.190:8001,10.110.139.190:8002,10.110.139.190:8003,10.110.139.190:8004,10.110.139.190:8005,10.110.139.190:8006
# 这是是集群的配置地址
    password: Testxxxxxxxx
# Redis必须要设置密码
    jedis:
      pool:
        min-idle: 1
        max-active: 100
        max-wait: -1
        max-idle: 50
# 这个配置节是jedis的. 应该可以设置jedis的连接池配置. 

redisson的设置

caching-configuration:
  enableRedis: true
  redisManagers:
  - name: default
    mode: cluster
    nodes: 10.110.139.190:8001,10.110.139.190:8002,10.110.139.190:8003,10.110.139.190:8004,10.110.139.190:8005,10.110.139.190:8006
    password: Testxxxxxxxx
    idleConnectionTimeout: 100000
    pingTimeout: 100000
    connectTimeout: 100000
    timeout: 30000
    retryAttempts: 30
    retryInterval: 60000
    reconnectionTimeout: 60000
    failedAttempts: 3
    masterConnectionPoolSize: 512
    readMode: SLAVE
    scanInterval: 10000
    threads: 400
    nettyThreads: 400

与Redisson/Jedis 线程数不足报错问题的思考相似的内容:

Redisson/Jedis 线程数不足报错问题的思考

Redisson/Jedis 线程数不足报错问题的思考 背景 最近公司内总出现 Redis相关的错误 !-_-! 看我最近发的博客就可以看的出来. 这个错误提示其实是 两年前 清明节进行 压测时发现的. 当时其实没有将这个问题细致分析下去. 最近学习的比较多. 感觉可以尝试分析一下这个问题. 报错的

[转帖]Redis客户端Jedis、Lettuce、Redisson

https://www.jianshu.com/p/90a9e2eccd73 在SpringBoot2.x之后,原来使用的jedis被替换为了lettuce Jedis:采用的直连,BIO网络模型 Jedis有一个问题:多个线程使用一个连接的时候线程不安全。 解决思路是: 使用连接池,为每个请求创建

Redis中 HyperLogLog数据类型使用总结

转载请注明出处: 目录 1. HyperLogLog 的原理 2.使用步骤 3.实现请求ip去重的浏览量使用示例 4.Jedis客户端使用 5.Redission使用依赖 6.HyperLogLog 提供了哪些特性和方法 7.使用场景总结 1. HyperLogLog 的原理 Redis Hyper

接口防刷!利用redisson快速实现自定义限流注解

问题: 在日常开发中,一些重要的对外接口,需要加上访问频率限制,以免造成资��损失。 如登录接口,当用户使用手机号+验证码登录时,一般我们会生成6位数的随机验证码,并将验证码有效期设置为1-3分钟,如果对登录接口不加以限制,理论上,通过技术手段,快速重试100000次,即可将验证码穷举出来。 解决思

Redisson 限流器源码分析

Redisson 限流器源码分析 对上篇文章网友评论给出问题进行解答:redis 的key 是否会过期,过期指的限流器 可以先阅读上篇文章: redis + AOP + 自定义注解实现接口限流 - 古渡蓝按 - 博客园 (cnblogs.com) 注解AOP 代码部分提取 // 调用Reids工具类

Redisson 限流器源码分析

Redisson 限流器源码分析 对上篇文章网友评论给出问题进行解答:redis 的key 是否会过期 可以先阅读上篇文章: redis + AOP + 自定义注解实现接口限流 - 古渡蓝按 - 博客园 (cnblogs.com) 注解AOP 代码部分提取 // 调用Reids工具类的rateLim

记一次 Redisson 线上问题 → ERR unknown command 'WAIT' 的排查与分析

开心一刻 昨晚和一个朋友聊天 我:处对象吗,咱俩试试? 朋友:我有对象 我:我不信,有对象不公开? 朋友:不好公开,我当的小三 问题背景 程序在生产环境稳定的跑着 直到有一天,公司执行组件漏洞扫描,有漏洞的 jar 要进行升级修复 然后我就按着扫描报告将有漏洞的 jar 修复到指定的版本 自己在开发

详解Redisson分布式限流的实现原理

摘要:本文将详细介绍下RRateLimiter的具体使用方式、实现原理还有一些注意事项。 本文分享自华为云社区《详解Redisson分布式限流的实现原理》,作者: xindoo。 我们目前在工作中遇到一个性能问题,我们有个定时任务需要处理大量的数据,为了提升吞吐量,所以部署了很多台机器,但这个任务在

RabbitMQ+redis+Redisson分布式锁+seata实现订单服务

引言 订单服务涉及许多方面,分布式事务,分布式锁,例如订单超时未支付要取消订单,订单如何防止重复提交,如何防止超卖、这里都会使用到。 开启分布式事务可以保证跨多个服务的数据操作的一致性和完整性, 使用分布式锁可以确保在同一时间只有一个操作能够成功执行,避免并发引起的问题。 订单流程(只展示重要的内容

【Azure Redis 缓存】示例使用 redisson-spring-boot-starter 连接/使用 Azure Redis 服务

问题描述 在 Spring Boot 项目中,使用 Redisson 连接 Azure Redis 服务,如下是详细的操作步骤(项目源代码文末可下载) 示例步骤 第一步: 在 Spring Boot 的项目中,添加 redisson-spring-boot-starter 依赖 在项目的pom.xm