今天解析服务在查询Redis的Set数据过程中抛出timeout exception,产生异常的方法是:

db.SetMembers(key);

这个API返回结果是指定set内的所有kv对象; 解决这个问题的方法仅仅是使用另一个api:

db.SetScan(key);

这个API也是返回set内所有的kv对象。 从功能上来说这2个API是一样的,但是其返回对象,前者是RedisValue[],后者是IEnumerable。但是在今天的实际场景中的结果是不同的。 从返回类型能看出的是,前者是一个同步查询的API,而后者是一个lazy的查询,在今天的实际场景中,Set内数据量大概为20+M,单次request同步查询timeout也属正常。 以上是这个问题本身的原因及解决方案。

* * *

更深入一步,这两个同样功能的API的执行机制反映出stackexchange封装API的思想,考虑redis是一个单线程的操作,如果在redis中执行耗时较长的操作,将会阻塞其它的请求。stackexchange中一个ConnectionMultiplexer封装一个TCP连接,之前某次早会也说过,ConnectionMultiplexer的成本很高,一般是以单例的形式存在的,到这里就能解释为什么stackexchange会直接对慢查询抛出timeout,而并不是request后等待其timeout,原因很简单,单个TCP连接同一时间只能处理一个request/response,如果处理了慢查询,后续的request就会被阻塞,这点在stackexchange抛出的timeout异常中也有侧面证明:qs数值表示了当前ConnectionMultiplexer所使用的TCP连接阻塞的request数量。 而同时stackexchange的API封装是比较“智能”的,还是以今天出异常的API:SetMembers来说明,在set内数据量较小的时候,正常返回所有KV没有问题,但是数据量一大,比如今天20+M的情况,stackexchange就直接不会发送这个request并抛出timeout。这种“智能”也给项目开发测试工作带来隐患:测试中因为数据量较小,这个问题不会凸显,而在生产环境中则一定会出现问题,并且是数据量到一定程度后才出现。 因此Redis的种种慢查询,如Key *,Keys以及今天的SetMembers,都属于需要小心处理的隐患。牢记Redis单线程的特征,尽量控制耗时的慢查询,以免降低Redis的整体性能。 为便于排查Redis的问题减小Codereview工作量,也可以考虑将Redis相关操作在项目代码结构中集中管理。

Redis必须注意的慢查询问题的更多相关文章

  1. 本地缓存,Redis缓存,数据库DB查询(结合代码分析)

    问题背景 为什么要使用缓存?本地缓存/Redis缓存/数据库查询优先级? 一.为什么要使用缓存 原因:CPU的速度远远高于磁盘IO的速度问题:很多信息存在数据库当中的,每次查询数据库就是一次IO操作所 ...

  2. StackExchange.Redis 使用LuaScript脚本模糊查询hash

    原文:StackExchange.Redis 使用LuaScript脚本模糊查询hash 获取redis连接 public class RedisHelper { private static rea ...

  3. 基于redis的IP地址快速查询

    在一些大数据处理中,我们需要用到IP地址查询,一般为了查询一个IP属于哪个地址,我们通常需要根据一个IP数据库来查询,网络上比较常用的IP库是纯真IP数据库.IP数据库里面的记录一般存储方式为IP的开 ...

  4. stackExchange.redis 实现模糊匹配批量查询

    如果使用redis的频次较高,那么业务中经常会出现需要根据关键字进行批量查询,所以总结一下StackExchange中使用批量查询的方法(如果数据量很大,那么在redis中模糊查询很耗时,请慎用!) ...

  5. Redis 根据Key模糊批量查询数据

    前言 经常会有这样一种业务逻辑,就是需要根据Redis中Key的规则,模糊查询对应的数据,当数据量少时,利用常规的命令也能满足需求,但是数据量大时,就会导致堵塞,就算是采用不堵塞的函数,如果数据需要显 ...

  6. Redis使用场景一,查询出的数据保存到Redis中,下次查询的时候直接从Redis中拿到数据。不用和数据库进行交互。

    maven使用: <!--redis jar包--> <dependency> <groupId>redis.clients</groupId> < ...

  7. 使用Spring Cache + Redis + Jackson Serializer缓存数据库查询结果中序列化问题的解决

    应用场景 我们希望通过缓存来减少对关系型数据库的查询次数,减轻数据库压力.在执行DAO类的select***(), query***()方法时,先从Redis中查询有没有缓存数据,如果有则直接从Red ...

  8. 面试突击 | Redis 如何从海量数据中查询出某一个 Key?附视频

    1 考察知识点 本题考察的知识点有以下几个: Keys 和 Scan 的区别 Keys 查询的缺点 Scan 如何使用? Scan 查询的特点 2 解答思路 Keys 查询存在的问题 Scan 的使用 ...

  9. 结合redis缓存的方式,查询和展示分类信息

    package cn.itcast.travel.service.impl;import cn.itcast.travel.dao.CategoryDao;import cn.itcast.trave ...

随机推荐

  1. AC日记——回文子串 openjudge 1.7 34

    34:回文子串 总时间限制:  1000ms 内存限制:  65536kB 描述 给定一个字符串,输出所有长度至少为2的回文子串. 回文子串即从左往右输出和从右往左输出结果是一样的字符串,比如:abb ...

  2. Json数据的学习

    JSON 教程 <body><h2>JSON Object Creation in JavaScript</h2> <p>Name: <span ...

  3. [No00004A]为什么你看了很多书,却依然没有洞见

    摘要: 前几天有人在知乎上问:今天就回答下很多人问了很久的这个问题,并且解释一下如何构建系统化的知识体系.我想很多人看到这个问题,期待的答案是一个书单,可是我要告诉你这并没有什么卵用.我想大部分人都经 ...

  4. HTML DOM Document 对象

    HTML DOM Document 对象 HTML DOM 节点 在 HTML DOM (Document Object Model) 中 , 每一个元素都是 节点: 文档是一个文档. 所有的HTML ...

  5. Python的高级特性8:你真的了解类,对象,实例,方法吗

    Python的高级特性1-7系列是本人从Python2过渡3时写下的一些个人见解(不敢说一定对),接下来的系列主要会以类级为主. 类,对象,实例,方法是几个面向对象的几个基本概念,其实我觉得很多人并不 ...

  6. JAVA常用的XML解析方法

    转并总结自(java xml) JAVA常用的解析xml的方法有四种,分别是DOM,JAX,JDOM,DOM4j xml文件 <?xml version="1.0" enco ...

  7. Html5 Egret游戏开发 成语大挑战(四)选关界面

    通过前面的开始界面基本上了解了eui的使用方法,可以简单快速的制作一个UI界面,本篇使用第二界面选关界面展示更为难一点的代码控制,来展现关卡地图的内容,请确保素材和资源完整,可以在前面的教程中找到下载 ...

  8. Visual Studio 2012 cannot identify IHttpActionResult

    使用ASP.NET Web API构造基于restful风格web services,IHttpActionResult是一个很好的http结果返回接口. 然而发现在vs2012开发环境中,Syste ...

  9. nginx图片处理相关

    nginx本身有支持图片处理的模块,通过外部插件也可以实现此功能. libgd的安装 前提是要有libgd的库文件, (1)去官网访问主页没问题,下载文件还是FQ下的,为了方便大家提供一个链接:htt ...

  10. 20145230GDB调试汇编堆栈过程分析

    20145230GDB调试汇编堆栈过程分析 分析过程 出现的问题:一开始无法编译,是因为我们的Linux中没有安装一个库. 进入之前先设置断点,之后disassemble可以获取汇编代码,用i r指令 ...