假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 是以某个固定的已知的前缀开头的,如何将它们全部找出来?
这个问题本身不难,但网上的教程答案让我很不理解,所以单独拿来吐槽一下
来源与网络的答案
我特意用了截图而不是贴链接。其中“如何”还打成了如果…
有什么问题?
如果我是面试官,问了这个问题,如果你第一回答是 keys,那么恭喜你可以回去等通知了(言重了,说白了就不往下问了)
1 亿个,你知道什么概念吗?如果直接 keys 一下线上的数据不知道要阻塞多久,你下面的回答明明就知道答案偏偏把人家往沟里带…
但如果就只是如此,我也不用写这篇博客了,我想说的是 SCAN 也不是最优解
SCAN 有什么问题
不卡,但是慢,下面是来源与网络的一个测试结果,Redis 性能问题诊断以及 scan 命令耗时分析
1 | 测试命令: |
显然,多少还是会给线上系统有影响的,可以有个毛刺?具体就看实际情况了。
那么我们来分析一下问题,如果面试官只是要考查你 KEYS 命令和 SCAN 命令的区别,并且想要看看你知不知道 KEYS 命令的阻塞问题,那么你回答 SCAN 就已经过了。
而实际中,如果真的有经验,你就会发现 SCAN 的能力阈值是在那里的。于是你需要继续反问面试官,是否有时间要求。
实际业务
在实际业务中,我能想到的场景有两个:
- 明知山有虎:就是你本身就有这样的业务场景需要去做所有当前 key 的统一操作,那么以空间换时间,提前以其他数据结构存储你需要的 key 才合理。比如,现在想要让 user 的 key 全部过期,至少我不会去考虑使用 scan 遍历出来然后再进行处理。
- 意外的统计:我现在突然有一个统计的需求,但统计的数据只有缓存里面有。那么没办法,甲方最大,SCAN 就 SCAN 吧。但要注意 SCAN 重复性的问题。
总结
我其实想说的是,作为线上的数据和操作,你的每次操作都需要明确可能会带来的后果是什么,并不是简单的别人说 SCAN 就 SCAN 了,你需要清楚的了解可能的后果,你才有底气去操作。同时也会让问你的人清楚,你是有过经验的人,而非纸上谈兵。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LinkinStar's Blog!
评论