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相关操作在项目代码结构中集中管理。

时间: 2024-10-16 02:58:34

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

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

应用场景 我们希望通过缓存来减少对关系型数据库的查询次数,减轻数据库压力.在执行DAO类的select***(), query***()方法时,先从Redis中查询有没有缓存数据,如果有则直接从Redis拿到结果,如果没有再向数据库发起查询请求取数据. 序列化问题 要把domain object做为key-valuec对保存在redis中,就必须要解决对象的序列化问题.Spring Data Redis给我们提供了一些现成的方案: JdkSerializationRedisSerializer.

Redis 怎么实现保存Django 查询集

我们在用Python Django开发秒杀系统的时候,要将Django 查询到商品详细信息保存到Redis缓存中去,但Redis不能直接保存对象,但有什么方法呢? 我们发现可用Python的pickle模块. pickle模块可以序列化对象并保存到磁盘中,并在需要的时候读取出来,任何对象都可以执行序列化操作. Pickle模块中最常用的函数为: 1.pickle.dumps(obj[, protocol]) 函数的功能:将obj对象序列化为string形式,而不是存入文件中. 参数讲解: obj

Redis和Memchaed缓存数据查询

使用TreeNMS数据库管理工具 支持Redis和Memchaed并存同时管理维护,支持集群管理,减少运维成本,提高工作效率 自带环境,免安装.免布署,下载解压即可使用.适用于windows,Linux,Mac ,手机端 还有一个产品叫TreeDMS,支持MySQL,Oracle,PostgreSQL, SQL Server, MongoDB, Hive数据库 原文地址:https://www.cnblogs.com/yaotome/p/10112017.html

redis范围查询应用 数据库 数据库学习 Redis redis范围查询的方法

redis范围查询应用. 需求 根据IP找到对应的城市 原来的解决方案 oracle表(ip_country): 查询IP对应的城市: 1.把a.b.c.d这样格式的IP转为一个数字,例如为把210.21.224.34转为3524648994 2. select city from ip_country where ipstartdigital <= 3524648994 and 3524648994 <=ipenddigital redis解决方案 我们先把上面的表简化一下: id city

浅谈Redis之慢查询日志

首先我们需要知道redis的慢查询日志有什么用?日常在使用redis的时候为什么要用慢查询日志? 第一个问题: 慢查询日志是为了记录执行时间超过给定时长的redis命令请求 第二个问题: 让使用者更好地监视和找出在业务中一些慢redis操作,找到更好的优化方法 在Redis中,关于慢查询有两个设置--慢查询最大超时时间和慢查询最大日志数. 1. 可以通过修改配置文件或者直接在交互模式下输入以下命令来设置慢查询的时间限制,当超过这个时间,查询的记录就会加入到日志文件中. CONFIG  SET 

C# 使用 redis

概念 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set --有序集合)和hash(哈希类型).在此基础上,redis支持各种不同方式的排序.与memcached一样,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文

redis锁 和悲观锁的并发问题

1.在业务流程前后中,用到了redis锁 和 悲观锁两种不同的锁. 2.汇总账单的时候,从库中读取数据,将读取到的实收额也跟着更新,而在收费的时候添加了悲观锁, 在读账单表的时候 用到了 forupdate,但是redis锁那块同样会产生并发,因为redis锁那块在查询库的时候也需要对账单for update,这样可以防止并发,在悲观锁里若还没更新 则redis锁不去执行更新 3.解决方案 有上面的一个在 redis锁中的查询账单表的时候同样 for update,另外一种则是 对与我们业务相关

数据库连接池DBPool分析(七):Redis连接控制 RedisObj

因为这个连接控制的class当中使用了大量的引用,所以设置一个宏IN和OUT,仅仅只是一个标志,标记是输出还是输入. 这个class的设计和MysqlObj的设计非常像,但是不同的是这里并不需要一个对象来专门保存查询值,就因为Redis是key-value的,查询是直接返回一个字符串或者数字. 所以这里只需要一个成员变量来保存查询值,就是redisReply* r_pResult; redisReply是定义在hiredis.h头文件当中的. 另外一个设计上的需求是这里还没有加上登陆密码.Red

redis慢日志

redis的slowlog是redis用于记录记录慢查询执行时间的日志系统.由于slowlog只保存在内存中,因此slowlog的效率很高,完全不用担心会影响到redis的性能.Slowlog是Redis从2.2.12版本引入的一条命令. 一.slowlog设置 slowlog有两种设置方式: 1.redis.conf设置 在redis.conf中有关于slowlog的设置: slowlog-log-slower-than 10000 slowlog-max-len 128 其中slowlog-