使用StackExchange.Redis客户端进行Redis访问出现的Timeout异常排查
问题产生
这两天业务系统在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异常排查的更多相关文章
- 大数据学习day31------spark11-------1. Redis的安装和启动,2 redis客户端 3.Redis的数据类型 4. kafka(安装和常用命令)5.kafka java客户端
1. Redis Redis是目前一个非常优秀的key-value存储系统(内存的NoSQL数据库).和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list ...
- 【Redis连接超时】记录线上RedisConnectionFailureException异常排查过程
项目架构: 部分组件如下: SpringCloudAlibaba(Nacos+Gateway+OpenFeign)+SpringBoot2.x+Redis 问题背景: 最近由于用户量增大,在高峰时期, ...
- Redis客户端ServiceStack.Redis的简单使用
在nuget中下载ServiceStack.Redis,但是运行之后会出现一个问题: Exception: "Com.JinYiWei.Cache.RedisHelper"的类型初 ...
- Redis 客户端重试指南
本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可. 在互联网服务中,特别是在云环境下,网络及硬件环境复杂,所有应用程序都可能遇到暂时性故障.暂时性故障包括瞬时的网络抖动,服务暂时不可 ...
- 全球领先的redis客户端:SFedis
零.背景 这个客户端起源于我们一个系统的生产问题. 一.问题的发生 在我们的生产环境上发生了两次redis服务端连接数达到上限(我们配置的单节点连接数上限为8000)导致无法创建连接的情况.由于这个系 ...
- Redis 客户端 Jedis、lettuce 和 Redisson 对比
Redis 支持多种语言的客户端,下面列举了部分 Redis 支持的客户端语言,大家可以通过官网查看 Redis 支持的客户端详情. C语言 C++ C# Java Python Node.js PH ...
- Redis客户端命令
Redis客户端命令 Redis 命令用于在 redis 服务上执行操作. 要在 redis 服务上执行命令需要一个 redis 客户端.Redis 客户端在我们之前下载的的 redis 的安装包中. ...
- 一文彻底理解Redis序列化协议,你也可以编写Redis客户端
前提 最近学习Netty的时候想做一个基于Redis服务协议的编码解码模块,过程中顺便阅读了Redis服务序列化协议RESP,结合自己的理解对文档进行了翻译并且简单实现了RESP基于Java语言的解析 ...
- Redis客户端、服务端的安装以及命令操作
目的: redis简介 redis服务端安装 redis客户端安装 redis相关命令操作 redis简介 官网下载(https://redis.io/) Redis 是完全开源免费的,遵守BSD协议 ...
随机推荐
- Servlet的生命周期+实现方式
1.Servlet的生命周期: (1)被创建: 默认情况下,Servlet第一次被访问时,被服务器创建.会调用init()方法. 一个 ...
- 在 CentOS7 上部署 zookeeper 服务
在 CentOS7 上部署 zookeeper 服务 1 用 SecureCRT 或 XShell 等 Linux 客户端工具连接至 CentOS7 服务器: 2 进入到 /usr/local/too ...
- mac brew & gcc安装
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" ...
- MySQL备份还原——mysqldump工具介绍
mysqldump是一款MySQL逻辑备份的工具,他将数据库里面的对象(表)导出成SQL脚本文件.有点类似于SQL SEVER的"任务-生成脚本"的逻辑备份功能.mysqldump ...
- Database 'xxxx' is being recovered. Waiting until recovery is finished.
巡检发现一个SQL SERVER Express 2005数据库备份时出现下面错误: Database 'xxxx' is being recovered. Waiting until recover ...
- Database 'xxx' cannot be upgraded because it is read-only or has read-only file Make the database or files writeable, and rerun recovery.
在分离数据库DatabaseName(暂且用DatabaseName代替该数据库名)后,我将其数据文件以及日志文件移动到新增的磁盘上.然后附加该数据库,结果报如下错误: Database 'Dat ...
- Webservice详解
WebService是什么? 1. 基于Web的服务:服务器端整出一些资源让客户端应用访问(获取数据) 2. 一个跨语言.跨平台的规范(抽象) 3. 多个跨平台.跨语言的应用间通信整合的方案(实际) ...
- hibernate基础dao类
此文章是基于 搭建SpringMVC+Spring+Hibernate平台 功能:数据库的保存.更新.删除:sql.hql查询:分页查询:调用存储过程 创建hibernate基础dao类: BaseD ...
- charles 抓取eclipse中的请求
charles抓取eclipse中的请求 有时候,想要监测eclipse中发送get获取post请求,一样可以使用代理方式: 1.eclipse代码设置 代码中添加,可以就写在主函数中,然后再调用请求 ...
- PL/SQL入门理解(一)
1.PL/SQL概述 1)概念 pl/sql(procedural language)是Oracle在标准sql语言的基础上的扩展,可以实现定义变量.使用逻辑控制语句等 作用:默认oracle一次只能 ...