zoukankan      html  css  js  c++  java
  • Redis必须注意的慢查询问题

    今天解析服务在查询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相关操作在项目代码结构中集中管理。

  • 相关阅读:
    使用mybatis报错constructor found in com.atguigu.mybatis.bean.Department matching [java.lang.Integer, java.lang.String]
    mybatis报错 Error instantiating interface com.atguigu.mybatis.dao.DepartmentMapper with invalid types () or values ()
    报错Mapped Statements collection does not contain value for com.atguigu.mybatis.dao.EmployeeMapperPlus
    mybatis学习(2)
    resultType没有指定就会报错
    使用Mybatis时报错Cause: java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符
    Oracle操作ORA-02289: 序列不存在
    在数据库中添加数据以后,使用Mybatis进行查询结果为空
    program
    codevs4817 江哥的dp题d
  • 原文地址:https://www.cnblogs.com/you-you-111/p/5719349.html
Copyright © 2011-2022 走看看