问题产生


这两天业务系统在redis的使用过程中,当并行客户端数量达到200+之后,产生了大量timeout异常,典型的异常信息如下:

Timeout performing HVALS Parser2#Hash#VersionState, inst: 1, mgr: ExecuteSelect, err: never, queue: 2, qu: 0, qs: 2,
qc: 0, wr: 0, wq: 0, in: 0, ar: 0, clientName: GS-SERVER-2894, IOCP: (Busy=0,Free=1000,Min=8,Max=1000), WORKER:
(Busy=0,Free=32767,Min=8,Max=32767), Local-CPU: 0% (Please take a look at this article for some common client-side
issues that can cause timeouts: https://github.com/StackExchange/StackExchange.Redis/tree/master/Docs/Timeouts.md)

No connection is available to service this operation: HVALS Parser2#Hash#VersionState

SocketFailure on HVALS

运行环境:

Redis服务器版本:2.8.19
.net Framework版本:4.5.2
StackExchange.Redis版本:1.1.603

问题分析


首先定位问题,排除Redis基础组件本身问题,使用redis提供的benchmark工具进行测试:

redis-benchmark -h  -q -n  -c  -d 

由于redis使用docker提供服务因此端口映射到30301,模拟100000次真实场景请求,300并发,每次请求数据大小10K。

经测试,对常见的hset,hget,sadd,spop等短耗时操作,TPS均保持在25K-30K之间,因此初步排除docker提供的redis服务的问题。

因此问题大致定位在了业务系统代码中,即使用的redis客户端工具(StackExchange.Redis)这部分。

通过StackExchange对Timeout异常的相关信息(可见这个问题挺常见)及stackoverflow等站点上的相关内容,产生timeout异常比较常见的原因包含(但不限于):

1:服务器资源不足;

2:耗时过长的指令(StackExchange客户端连接的只读属性TimeoutMilliseconds=1000);

3:StackExchange阻塞任务过多(异常信息中的qs值持续增长),对这种情况,StackExchange给出的建议是实现一个复用器池(ConnectionMultiplexer Pool)并动态选取最低负载的复用器进行连接,避免一个链接timeout导致所有链接阻塞的情况;

4:CLR中Thread Pool最小按需创建线程数过小导致的等待成本(500ms),可见StackExchange的ConnectionMultiplexer使用的是线程池;

此外,在StackExchange.Redis项目的Issue中与Time out相关的主题中,也有人提及在更新StackExchange.Redis的客户端版本后(1.1.605+)该异常不再出现的问题。

问题解决


根据以上可能产生问题的原因,对业务代码做出以下修改:

1:不再继续使用StackExchange.Redis内部封装的主/从线程池,明确主/从ConnectionMultiplexer对象;

2:修改CLR的Thread Pool最小创建线程阈值数量;

3:在ConnectionMultiplexer单例视线中加入对其IsConnected属性的判断,在其连接断开后手动释放资源并重新连接;

4:避免如HVALS等可能导致慢操作的指令;

5:升级StackExchange.Redis版本至1.1.605+(目前最新版本1.1.608)。

修改完毕后进行测试,time out异常目前已排除。

2016-10-17 补充


StackExchange.Redis客户端(V1.1.608)经测试有这么一个特质,即,由complexer单例对象创建的IDatabase对象,在产生Timeout异常后会导致这个complexer单例对象超时,即由其创建的新的IDatabase对象也会继续Timeout,相当蛋疼。。。

实际使用过程中,由于网络各种原因,出现Timeout异常难免,但是无法恢复确实很麻烦。测试complexer对象无法dispose,close后重建。。

使用StackExchange.Redis客户端进行Redis访问出现的Timeout异常排查的更多相关文章

  1. 大数据学习day31------spark11-------1. Redis的安装和启动,2 redis客户端 3.Redis的数据类型 4. kafka(安装和常用命令)5.kafka java客户端

    1. Redis Redis是目前一个非常优秀的key-value存储系统(内存的NoSQL数据库).和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list ...

  2. 【Redis连接超时】记录线上RedisConnectionFailureException异常排查过程

    项目架构: 部分组件如下: SpringCloudAlibaba(Nacos+Gateway+OpenFeign)+SpringBoot2.x+Redis 问题背景: 最近由于用户量增大,在高峰时期, ...

  3. Redis客户端ServiceStack.Redis的简单使用

    在nuget中下载ServiceStack.Redis,但是运行之后会出现一个问题: Exception: "Com.JinYiWei.Cache.RedisHelper"的类型初 ...

  4. Redis 客户端重试指南

    本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可. 在互联网服务中,特别是在云环境下,网络及硬件环境复杂,所有应用程序都可能遇到暂时性故障.暂时性故障包括瞬时的网络抖动,服务暂时不可 ...

  5. 全球领先的redis客户端:SFedis

    零.背景 这个客户端起源于我们一个系统的生产问题. 一.问题的发生 在我们的生产环境上发生了两次redis服务端连接数达到上限(我们配置的单节点连接数上限为8000)导致无法创建连接的情况.由于这个系 ...

  6. Redis 客户端 Jedis、lettuce 和 Redisson 对比

    Redis 支持多种语言的客户端,下面列举了部分 Redis 支持的客户端语言,大家可以通过官网查看 Redis 支持的客户端详情. C语言 C++ C# Java Python Node.js PH ...

  7. Redis客户端命令

    Redis客户端命令 Redis 命令用于在 redis 服务上执行操作. 要在 redis 服务上执行命令需要一个 redis 客户端.Redis 客户端在我们之前下载的的 redis 的安装包中. ...

  8. 一文彻底理解Redis序列化协议,你也可以编写Redis客户端

    前提 最近学习Netty的时候想做一个基于Redis服务协议的编码解码模块,过程中顺便阅读了Redis服务序列化协议RESP,结合自己的理解对文档进行了翻译并且简单实现了RESP基于Java语言的解析 ...

  9. Redis客户端、服务端的安装以及命令操作

    目的: redis简介 redis服务端安装 redis客户端安装 redis相关命令操作 redis简介 官网下载(https://redis.io/) Redis 是完全开源免费的,遵守BSD协议 ...

随机推荐

  1. ListView setOnItemClickListener无效原因分析

    前言 最近在做项目的过程中,在使用listview的时候遇到了设置item监听事件的时候在没有回调onItemClick 方法的问题.我的情况是在item中有一个Button按钮.所以不会回调.上百度 ...

  2. 几个常用的adb命令

    adb全程为Android Debug Bridge,字面意思就是安卓调试桥接.就是android系统提供的一套 工具帮我们建议一个连接android设备的通道,然后在电脑上发送一些指令,完成工作. ...

  3. ansible使用文档

    假设A机器上安装ansible yum install ansible vim /etc/ansible/hosts 对每个主机加key认证ssh-copy-id -i ~/.ssh/id_rsa.p ...

  4. 有氧运动 && 无氧运动

    有氧运动也叫做有氧代谢运动,是指人体在氧气充分供应的情况下进行的体育锻炼.有氧运动的好处是:可以提升氧气的摄取量,能更好地消耗体内多余的热量.也就是说,在运动过程中,人体吸入的氧气与需求相等,达到生理 ...

  5. Ajax.ActionLink参数详解

    该语法会生成一个a标签,点击a标签会执行一个Ajax请求. 有12个方法重载,下面详解方法中的各项参数: 参数一:linkText string类型 说明:链接显示的文字内容 参数二:actionNa ...

  6. [MySQL] Buffer Pool Adaptive Flush

    Buffer Pool Adaptive Flush 在MySQL的帮助文档中Tuning InnoDB Buffer Pool Flushing提到, innodb_adaptive_flushin ...

  7. JVM之GI收集器

    Garbage-First,面向服务端的垃圾收集器. 并行与并发:充分利用多核环境减少停顿时间, 分代收集:不需要配合其它收集器 空间整合:整体上看属于标记整理算法,局部(region之间)数据复制算 ...

  8. 从零自学Hadoop(03):Linux准备上

    阅读目录 序 检查列表 常用Linux命令 搭建环境 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,Sou ...

  9. android穿越之旅--如何弹出一个非比寻常的窗体

    上一篇中介绍了一种闻所未闻在android执行java命令的方法,虽然这是一种非常"高级"的技术,然后并没有什么卵用,因此被移除了博客园首页.实际上也并不是一点用处也没有,对已立即 ...

  10. mysql5.7 root password change

    mysqld_safe --skip-grant-tables &update mysql.user set authentication_string=password('Root_1234 ...