今天解析服务在查询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. Google类VR设备知识

    前言 本文所指的google类vr设备是指: 谷歌的Cardboard.三星Gear VR.暴风魔镜等这样的手机VR盒子,而并不是HTC Vive这类. 人眼立体感知能力 人的左右眼看到的东西是有差别 ...

  2. java 22 - 3 多线程的概述以及其它所涉及的东西(看)

    1:要想了解多线程,必须先了解线程,而要想了解线程,必须先了解进程,因为线程是依赖于进程而存在. 2:什么是进程? 通过任务管理器我们就看到了进程的存在. 而通过观察,就可以发现只有运行的程序才会出现 ...

  3. 转: Eclipse 分屏显示同一个文件

    Eclipse 分屏显示同一个文件   场景 : 某个类很大,可能有数千行.当你想要将类开头部分与中间或者靠后的部分进行对比时,请follow如下步骤: Window -> Editor -&g ...

  4. 一种Docker image镜像的取代方案

    在http://openvz.org/Download/templates/precreated中有很多压缩的镜像文件,可以将这些文件下载后采用import方式使用镜像,也可以采用我原来的博文:doc ...

  5. iOS原生项目中集成React Native

    1.本文的前提条件是,电脑上已经安装了CocoaPods,React Native相关环境. 2.使用Xcode新建一个工程.EmbedRNMeituan [图1] 3.使用CocoaPods安装Re ...

  6. Codevs 1910递归函数

    1910 递归函数  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 对于一个递归函数w(a, b, c). 如果a <= ...

  7. Codevs1026 逃跑的拉尔夫

    题目描述 Description 年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他没想到的是那辆车属于警察局,并且车上装有用于发射车子移动路线的装置. 那个装置太旧了,以至于只能发射关于那辆车的移动 ...

  8. Tomcat6配置webdav协议

    Tomcat6默认是支持webdav协议的,只是webapps目录中不带例子而已.要添加支持很简单,在webapps目录中建立webdav目录,在webdav目录中建立WEB-INF目录,加入web. ...

  9. 代码滑动panorama-即程序中设置SelectedIndex

    我们都知道panorama的SelectedIndex属性是只读的,所以通过修改它,在程序滑动panorama似乎不可能.那么是不是就没有办法了呢?其实我们可以通过设置SelectedItemProp ...

  10. DOM与元素节点内联样式

    获取.设置及移除单个内联 CSS 属性 每个 HTML 元素都有个 style 属性,可以用来插入针对该元素的内联 CSS 属性. <div style='background-color:bl ...