这个问题本身不难,但网上的教程答案让我很不理解,所以单独拿来吐槽一下

来源与网络的答案

redis-scan-command-benchmark

我特意用了截图而不是贴链接。其中“如何”还打成了如果…

有什么问题?

如果我是面试官,问了这个问题,如果你第一回答是 keys,那么恭喜你可以回去等通知了(言重了,说白了就不往下问了)

1 亿个,你知道什么概念吗?如果直接 keys 一下线上的数据不知道要阻塞多久,你下面的回答明明就知道答案偏偏把人家往沟里带…

但如果就只是如此,我也不用写这篇博客了,我想说的是 SCAN 也不是最优解

SCAN 有什么问题

不卡,但是慢,下面是来源与网络的一个测试结果,Redis 性能问题诊断以及 scan 命令耗时分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
测试命令:
./redis-benchmark -a xxxx -r 10000 -n 100 -c 8000 scan 0 match zhaobsh* count 10000
10000个随机key, 测试100次, 使用 80000个client进行测试验证.
被测试的命令为: scan 0 match zhaobsh* count 10000

一万个key时count 一万时:
Summary:
throughput summary: 99.11 requests per second
latency summary (msec):
avg min p50 p95 p99 max
993.304 17.472 1004.543 1005.055 1005.055 1005.055

十万个key时 count 十万时
Summary:
throughput summary: 11.54 requests per second
latency summary (msec):
avg min p50 p95 p99 max
2970.660 135.680 3000.319 3000.319 3000.319 3000.319
五十万个key时 count 五十万时
Summary:
throughput summary: 3.46 requests per second
latency summary (msec):
avg min p50 p95 p99 max
2972.532 322.816 3000.319 3000.319 3000.319 3000.319

自己进行了一下验证, 如果直接一次scan 一千万的记录
耗时为: 10.15秒.
理论上scan 一个键值对的时间为 1微秒左右.

如果redis里面有 1000万个key的话 60台服务器如果同时进行一次所有的scan
那么搞不好至少会有在 运行期间内产生总计 600S 的延迟时间.

显然,多少还是会给线上系统有影响的,可以有个毛刺?具体就看实际情况了。

那么我们来分析一下问题,如果面试官只是要考查你 KEYS 命令和 SCAN 命令的区别,并且想要看看你知不知道 KEYS 命令的阻塞问题,那么你回答 SCAN 就已经过了。

而实际中,如果真的有经验,你就会发现 SCAN 的能力阈值是在那里的。于是你需要继续反问面试官,是否有时间要求。

实际业务

在实际业务中,我能想到的场景有两个:

  1. 明知山有虎:就是你本身就有这样的业务场景需要去做所有当前 key 的统一操作,那么以空间换时间,提前以其他数据结构存储你需要的 key 才合理。比如,现在想要让 user 的 key 全部过期,至少我不会去考虑使用 scan 遍历出来然后再进行处理。
  2. 意外的统计:我现在突然有一个统计的需求,但统计的数据只有缓存里面有。那么没办法,甲方最大,SCAN 就 SCAN 吧。但要注意 SCAN 重复性的问题。

总结

我其实想说的是,作为线上的数据和操作,你的每次操作都需要明确可能会带来的后果是什么,并不是简单的别人说 SCAN 就 SCAN 了,你需要清楚的了解可能的后果,你才有底气去操作。同时也会让问你的人清楚,你是有过经验的人,而非纸上谈兵。