这一次,吃了Redis的亏,也败给了GPT
创始人
2025-05-30 23:10:41
0

关注【离心计划】,一起离开地球表面

 

背景

组内有一个系统中有一个延迟任务的需求,关于延迟任务常见的做法有时间轮、延迟MQ还有Redis Zset等方案,关于时间轮,这边小苏有一个大学时候做的demo:

https://github.com/JAYqq/GoDelayTasks

该系统采用的是zset的方案,在系统稳定运行了三年多后,这周出现了一个大面积故障,背后的原因居然是zscan的问题,我们今天就简单复盘一下这次的故障,好好盘一盘zset。

 

zset实现延时任务队列

关于zset的底层数据结构和基本操作,在之前的文章就已经阐述过了,简单来说就是底层由ziplist组织,超过一定阈值(默认128)就改为由skiplist:

【专栏】基础篇03| Redis 花样的数据结构

最常见的延迟任务就是下单,某宝中我们下单未支付后,会倒计时一段时间,到点后订单自动释放;还有完成订单后,超过一定时间就会自动签收。这些都是延迟任务,在zset中,我们将业务类型作为key、订单ID作为member、下单时间+延迟时间作为score,这样的一个zset结构,我们配合zrangeByScore(0,currentTime),就能获取到当前时间应该过期的任务了,简单操作如下:

127.0.0.1:6379> zadd order 100 111
(integer) 1
127.0.0.1:6379> zadd order 120 112
(integer) 1
127.0.0.1:6379> zadd order 140 113
(integer) 1
127.0.0.1:6379> zadd order 170 114
(integer) 1
127.0.0.1:6379> zrangebyscore order 0 130
1) "111"
2) "112"

zrangeByScore在异步线程定时执行就行了,这是延时任务的主动释放。而在组内应用的系统中,还有一个监听消息的机制,当接收到消息后需要取出sessionId,将zset中对应的session元素删除,这边就需要扫描zset所有元素,便用到了zscan命令。

zscan

zscan是一个增量命令,它在官网的定义如下:

所谓增量就是不会一次全部,而是返回一定数量的元素,也就是上面指定的count,然后返回cursor表示扫描到的位置,只要这个cursor不为0就表示扫描没有结束,这就是增量命令最重要的表现形式。

然而,这是我们对增量的理解,但是zset狗在对于元素数量比较少的时候,也就是底层以ziplist组织的时候,会忽视count,一次返回所有元素;而当以skiplist组织的时候,才会返回count个,如果没有传count,默认10个。这也是此次组内系统故障的根因,同事在用zscan的时候并没有传count,但是元素数量超过了128个,导致只扫描了10个后就停止了,代码也没有继续从返回的cursor扫描,导致了zset中存在大量的元素未被删除,被延迟任务队列监控线程通过zrangeByScore扫描到,错误地认为这些元素超时而返回了错误的系统信息。

从源码上看,也可以看出一些端倪

这边看确实默认值是10,但是直到我看到:

当是skiplist的时候,count会默认变成两倍,但是在我的电脑上并没有这个现象,可能是版本差异,但是我找了之前的release描述,没有找到相关的信息,这个问题因为我太饿了就查不下去了(其实是懒

),有读者知道的可以后台私信,感谢~

zset-max-ziplist-entries 3
127.0.0.1:6379> object encoding order
"ziplist"
127.0.0.1:6379> zscan order 0 match "order*" count 5
1) "0"
2)  1) "order-111"2) "100"3) "order-112"4) "110"5) "order-113"6) "120"7) "order-114"8) "130"9) "order-115"10) "140"11) "order-116"12) "150"13) "order-118"14) "170"15) "order-119"16) "180"17) "order-120"18) "190"19) "order-121"20) "200"21) "order-122"22) "210"23) "order-123"24) "220"
127.0.0.1:6379> zadd order 230 order-124
(integer) 1
127.0.0.1:6379> object encoding order
"skiplist"
127.0.0.1:6379> zscan order 0
1) "5"
2)  1) "order-123"2) "220"3) "order-116"4) "150"5) "order-118"6) "170"7) "order-124"8) "230"9) "order-121"10) "200"11) "order-114"12) "130"13) "order-120"14) "190"15) "order-115"16) "140"17) "order-111"18) "100"19) "order-122"20) "210"

发现确实只返回了10个,并且cursor是5,表示并没有结束,至此我们复现了系统的问题,现象也是一致的。

解决方案

方案一:传一个很大的count

方案二:zrange扫描全部,代码内做筛选

方案三:循环zscan,直到cursor为0

业务方案:zrangeByScore扫描到后继续保底

复盘

故障从监控预警到定位问题时间较长,原因在于开发人员并没有直接定位到zscan的问题,并且这部分命令是作为lua脚本执行,调试困难。

流程上看,这种问题无法通过单测发现,确实需要开发人员本身对所用技术的深刻了解,任何流程规则只能降低问题发生概率。

最后,gpt给出的答案确实是生产方案

周末快乐,分享一句最近看到的诗

欲买桂花同载酒,终不似,少年游

相关内容

热门资讯

国医战士:我的觉醒之路与薪火守... 一、根脉:红土地上的传承之子 1974年,李铭豪出生在广东吴川一个淳朴的农家。这片南海之滨的红土地,...
库克预告:苹果今年有前所未见的... 1月31日消息,苹果日前交上了一份历史最强季度财报,多项核心财务指标创历史新高,iPhone业务成为...
原创 白... 一夜之间,全崩了 昨天白天的时候,看到白银和黄金在大跌,想想昨夜跌跌就差不多了,结果一觉醒来完全颠覆...
夜“血洗”!白银,史诗级暴跌!... 北京时间1月31日凌晨,现货白银价格一度暴跌36%,创出历史最大日内跌幅;现货黄金价格一度下跌超过1...
一老人家中发生火灾,近40万元... 前不久,自贡赵女士爷爷家发生了火灾。因为爷爷奶奶不喜欢把钱存银行,家里近40万现金被烧毁大半。赵女士...
史诗级暴跌!白银一度重挫18% 1月30日,此前连续暴涨的贵金属,集体踩下“急刹”,其中白银等品种更迎来史诗级暴跌。 国际市场上现货...
视频|黄金白银“瀑布流直线跳水... 1月29日至1月30日,黄金白银遭遇“瀑布流直线跳水”,现货黄金从猛冲5600美元/盎司,到跌穿50...
今天凌晨,黄金、白银、美股,全... 北京时间1月31日凌晨,恐慌性抛售席卷全球贵金属市场。 现货白银日内跌幅一度扩大至34.67%,从1...
OpenAI详解AI代理如何应... AIPress.com.cn报道 1月31日消息,OpenAI 在一篇官方博客中介绍了其 AI 代理...
21亿减值离场,分众掀开了网贷... 作为广告行业巨头的分众传媒,近期的几则公告却意外挑开了网贷行业正面临的艰难现状。 分众传媒近日发布的...
披露换手率、新增中长期业绩!公... 1月30日,中国证监会就《公开募集证券投资基金信息披露内容与格式准则第2号——定期报告的内容与格式》...
40年最大单日跌幅!现货黄金价... 美国总统特朗普提名凯文·沃什(Kevin Warsh)出任美联储主席,引爆市场鹰派预期,贵金属遭恐慌...
一纸提名引爆史诗级抛售:现货白... 1月31日,周五(1月30日)纽约时段,国际贵金属价格大幅跳水,其中现货白银一度跌超36%,黄金最高...
股票行情快报:工商银行(601... 证券之星消息,截至2026年1月28日收盘,工商银行(601398)报收于7.2元,下跌0.41%,...
002514、300087,被... 两家公司被证监会立案调查。 1月30日,宝馨科技(002514.SZ)公告称,公司及公司实际控制人马...
中山东方医院标准化就诊流程:从... 在医疗服务质量不断提升的今天,标准化就诊流程建设已成为医院提升服务效率、改善患者体验的重要抓手。医院...
彩票卖不动了?去年全国彩票收入... 中国彩票收入增速持续放缓。 1月30日,财政部公布2025年12月份全国彩票销售情况。2025年全年...
原创 超... 当消费者为家中购置新物品时,功能之外,产品在“家”中的融入感、协调性如何,正成为越来越重要的考量——...
寒武纪预计2025年至高盈利2... 《科创板日报》1月30日讯(记者 郭辉)寒武纪发布2025年年度业绩预告。 公告显示,寒武纪预计20...
2025年我国基本医保统筹基金... 2025年我国基本医保统筹基金收入约2.95万亿元 新华社北京1月30日电(记者彭韵佳)记者1月3...