reids 推荐在生产环境中使用scan
命令来代替keys
命令获取所有 key,我有些疑惑,望各位大佬解答🙏。
前提:redis 中 key 的数量一直在频繁变化
我已经测试了单连接快速多次执行scan 0
,返回的游标是相同的,那么问题是:
scan 0
命令,redis 返回的游标是否可能相同(因 redis 是单线程,所以响应肯定有先有后,所以这个问题是:临近的两次响应,返回的游标是否可能相同)?scan
命令,返回游标是否可能相同?像这样,每次 scan 一万条数据,会不会出现 [连接 2 ] 获取的 key 比 [连接 1 ] 少两万个呢?极限情况, [连接 1 ] 已经扫描到数据结尾,会不会导致 [连接 2 ] 只能获取两万个 key 呢?
提前感谢各位大佬,我查了半天,只能查到just do my best
,我可以允许 scan 出来的 key 多一点少一点,但也不能少太多吧
1
lpts007 2020-12-16 06:38:25 +08:00 via Android
不知道说啥,scan 和两个连接有啥关系?
|
2
teek 2020-12-16 08:59:21 +08:00
取决于你数据变动情况。redis.io/commands/scan#scan-guarantees
|
3
yRebelHero 2020-12-16 09:30:48 +08:00
redis 里的 key 都是存储在一个字典里的,有点类似于 Java 里的 HashMap,一维是数组,二维是链表,游标返回的就是第一维数组的位置索引,而且它的遍历不是从一维数组的第 0 位一直遍历到末尾,而是用的一种高位进位加法来遍历。举个例子,普通的是 0->1->2->3,高位进位加法是 0 -> 8 -> 4 -> 12 -> 2 这样的。
|
4
yRebelHero 2020-12-16 09:34:58 +08:00
不好意思,先发出去了,接上文。
遍历的时候如果有数据修改,改动后的数据能不能遍历到是不一定的。 既然你的问题的前提是:key 的数量时一直频繁变化的。那么问题 1 、2,返回的游标可能不一样,既然上面两个问题不相同,第 3 个问题就没法回答你了。 |
5
xuanbg 2020-12-16 09:58:52 +08:00
自己做一个 key 管理,Redis 已经很忙很辛苦了,就不要再为难 Redis 了。。。
|
6
lithium4010 2020-12-16 11:47:59 +08:00
你为啥要拿所有的 key ? key 很大的时候, 它这个就没有设计这种使用场景我理解
|
7
lithium4010 2020-12-16 11:48:23 +08:00
@lithium4010 我是只 key 的数量很大的时候
|
8
lithium4010 2020-12-16 11:48:40 +08:00
我是指..
|
9
qqqasdwx OP @lpts007 和两个连接确实没什么关系,其实就是想问 scan 的游标是怎么维护的,多次扫描并行存在时会不会相互影响
|
10
qqqasdwx OP @yRebelHero 谢谢您的耐心解答,那么用具体场景来举例子,比方说有两个用户查询全部 key,假设页面无限加载,一次 scan 的 count 设为 1,redis 里数量级相对固定(比如 2kw 数据,上下浮动 1w,但 key 会频繁变动,大量删除大量增加,但总数维持在 2kw ),那么如果出现了相同游标,会不会出现一个极限情况,用户 1 最终刷出了 2kw 数据,用户 2 只能刷出 2 条数据?
|
11
qqqasdwx OP @lithium4010 比如淘宝商品页做无限加载,每秒都有大量商家上货,也有大量商家下架,不能说一个用户最终能看到全部商品,而另一个用户只能看到两页吧,当然这只是我假想了一个使用场景,想问的是在 redis 不维护 session 的情况下如何保证能扫描到大部分 key
|
12
yRebelHero 2020-12-16 20:16:37 +08:00
@qqqasdwx 其实不是很明白你描述的具体场景,但应该不会这么极端的,毕竟 key 在字典里都是经过 hash 了一次的,肯定是比较均匀地分布,不会那么极端的。
|
13
huskyui 2021-03-02 23:46:34 +08:00
可以看一下 https://tech.meituan.com/2018/07/27/redis-rehash-practice-optimization.html
文章里面的 Redis 使用 Scan 清理 Key 由于 Rehash 导致清理数据不彻底 今天刚看到 dict 这边的 scan 命令 |