redis 大 key 删除踩坑记

文章讲述了在使用Redis进行幂等控制时遇到的问题,包括大key过期导致的主从切换和加锁超时。提出了从优化数据结构、使用数据库实现幂等以及人工删除大key的策略,并详细描述了人工删除时触发的主从切换循环问题及其解决办法。
摘要由CSDN通过智能技术生成

关注公众号【1024个为什么】,及时接收最新推送文章!

业务场景

接受某个定时任务处理流水的一个接口,使用 redis 缓存流水ID,用做幂等控制,用的数据类型是 hash,

hash 内的

key=流水ID(长这个样子625736952578072728),

value=UUID(长这个样子9def28a8-cd48-4fb6-9c93-0ac66b8450f5),

数据量约 1600W,每月增量60W,约占 3G 内存空间。

任务每月 5 号执行一次,耗时 1.5 天,hash 的过期时间是月底,到期自动删除。

问题表象

最近 2 个月,连续发生了 2 次 服务加分布式锁超时的问题,持续几秒钟,出问题的服务都是和上面的接口共用的 redis。

排查是由于 redis 主从切换,导致加锁超时。

由于上游系统逻辑中没有兼容这种场景,加锁超时影响到了业务数据,所以就需要深入排查是什么导致的 redis 主从切换。

redis 部署结构

哨兵 + 主从

4e28b970d81f54be884fba0b87647443.png

问题原因

hash 的大 key 过期后自动删除,导致主线程阻塞,

哨兵检测到主节点异常,就启动了主从切换,

主节点的主线程阻塞 + 主从切换,就导致客户端的加锁请求超时。

本场景中 redis 使用不当之处

1、无效且过长的 value,hash 中的 value 如果用不到,设置一个字符即可,没必要设置那么长的,浪费内存

2、hash 上的自动过期慎用,你无法控制 hash 里的内容的数量大小,很容易造成大 key

3、自动过期的时间设置不合理,根据业务场景评估出合理的过期时间,而且不能设置同一时间

解决方案

把 hash 换成 string ?

1600W 数据,key 还是流水ID,value 按 1 个字节算,大约占用 1.6G 的空间。(可以根据 redis 对象结构估算)

空间占用是少了些,但一个业务场景就占这么多,感觉还是不太合理,而且每月数据量还会递增,还要考虑过期时间的设置。

通过数据库实现幂等

经过再次对业务场景的认真分析,1600W 数据,1.5天执行完,压力很小的,完全可以通过数据库实现幂等控制。

幸运的是,经过对业务场景的评估,发现此功能已经无用,所以就下掉了次功能。

但最后一次任务执行写入 redis 的数据到月底才会自动过期删除,我们想通过手动删除,立即释放这部分资源,缓解 redis 存储压力。

但不幸的是,又遇到了新的问题。

人工删除大 key 时的坑

人工删除的表现为:

也触发了主从切换,

而且切换后,发现主、从节点上大 key 又回来了。

具体过程为,老的主节点好不容易把大 key 删除了,

结果主从切换后,发生了主从同步,又把原来从节点上的大 key 同步过来了,

死循环了,删了个寂寞。

为什么哨兵自动主从切换没有陷入死循环?

人工删除属于立即删除,

过期删除属于惰性删除,

相比立即删除,要快一些,且主从同步不会同步过期 key 的数据。

怎么破解?

先手工断开主从关系

再进行大 key 删除

删除后再挂回主从关系

思考

看似很简单的一个业务场景,却涉及到了很多知识点。

redis 数据类型的选择,value 值的设置;

redis 对象结构,占用空间的预估;

redis 的惰性删除、立即删除;

redis 的部署结构,主从切换、主从同步;

对业务场景所耗资源的合理评估等等。

原创不易,多多关注,一键三连,感谢支持!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值