笔记:Redis大key问题排查处理

一、背景

最近一段时间公司有个服务频繁出现"com.mongodb.MongoWaitQueueFullException:Too many threads are already waiting for a connection. Max number of threads (maxWaitQueueSize) of 100 has been exceeded",程序在获取连接的排队队列设置的100,连接使用时间过长导致获取连接溢出,

经DBA分析排除mongo 慢查询原因,对比异常出现时间跟redis监控cpu过高想吻合,怀疑redis rdb持久化导致,导出rdb,通过rdbtools分析工具做内存分析,查出内存占用最高前10个key,发现排第一的key 占用3G内存并且无过期时间hash结构key-value对有65W数据,经沟通此key数据可清理,清理内存,持久1天观察日志,问题解决.

 

二、排查过程

1.让dba导出rdb,本次导出文件名8140.rdb

2.安装redis内存分析工具rdbTools,此工具python所写,需要有python环境,安装完毕,通过命令“rdb --help”校验是否安装成功

 

3.开发库新建表,已创建,用于分析redis内存使用情况

CREATE TABLE `memory` (

  `databaseint(128) DEFAULT NULL,

  `type` varchar(128) DEFAULT NULL,

  `KEYvarchar(128) NOT NULL,

  `size_in_bytes` bigint(20) DEFAULT NULL,

  `encoding` varchar(128) DEFAULT NULL,

  `num_elements` bigint(20) DEFAULT NULL,

  `len_largest_element` varchar(128) DEFAULT NULL,

  `expiry` varchar(255) DEFAULT NULL,

  PRIMARY KEY (`KEY`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

4.将rdb上传机器,通过rdbtools生成内存统计数据报告,执行"rdb -c memory /data/pub/ytl/rdb/8140.rdb > memory.csv"

 

 

5.将生成好的memory.csv导入开发库表memory

6.通过以下sql分析各种数据

1、查询key的个数

select count(*) from memory;

 

2、查询总的内存占用

select sum(size_in_bytes) from memory;

 

3、查询内存占用最高的3个key

select * from memory order by size_in_bytes desc limit 3;

 

4、查询value个数1000个以上的hash

select * from memory where type='hash' and num_elements > 1000;

 

通过查询内存占用最高的key发现已占用3G内存,65W的k-v对并且没有过期时间,通过业务排查可以清除,处理后cpu就降下来了

 

三、hash处理过期时间失效问题

导致hash主key失效的几种可能,本次出现的过期失效属于第一种情况

1.经检查代码在spring容器初始化对象时直接expire给key设置了过期时间,此处逻辑有问题,第一没有判断redis是否存在此key,没有key时就设置操作无效,第二当redis的put操作不会刷新key的过期时间,当key过期后的put就会导致key长期有效

代码验证

1.1先创建个hash设置过期时间

 

1.2在put查看过期时间是否被刷新

 

控制台打印

 

可以得出结论,put时不会刷新hash的过期时间,这样可以推理出当程序运行到过期时间到了后,key被删除后后续的所有put的数据都是长期有效的,这样导致这个hashkey会越来越大,知道服务重启重新设置key的过期

 

2.hash的subkey被清空时会触发主key的删除

代码验证

2.1 先创建一个hash结构数据并设置过期时间

 

查询redis看下效果

 

 

2.2 在清除hash里唯一的一条subkey,在查看redis

 

查询redis

 

我们发现在hash的subkey被清理光时,主key也会被清理掉

2.3 我们在put一条数据,完整的模拟业务代码逻辑就是先创建hash的主key,在设置过期时间,在put一条数据

key被长期有效

所以在put数据的时候需要判断当前hashkey是否存在,不存在就要加过期时间,防止生成ttl:-1的key

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值