关于 redis 的 scan 命令并发执行的问题,望解答

2020-12-15 23:59:09 +08:00
 qqqasdwx

reids 推荐在生产环境中使用scan命令来代替keys命令获取所有 key,我有些疑惑,望各位大佬解答🙏。

前提:redis 中 key 的数量一直在频繁变化

我已经测试了单连接快速多次执行scan 0,返回的游标是相同的,那么问题是:

  1. 如果两个连接同时发送scan 0命令,redis 返回的游标是否可能相同(因 redis 是单线程,所以响应肯定有先有后,所以这个问题是:临近的两次响应,返回的游标是否可能相同)?
  2. 进阶问题:多个连接中多次执行scan命令,返回游标是否可能相同?
  3. 如果上述两个问题中会出现相同游标,那么如何保证两个连接获取到相同数量级的 key ?

像这样,每次 scan 一万条数据,会不会出现 [连接 2 ] 获取的 key 比 [连接 1 ] 少两万个呢?极限情况, [连接 1 ] 已经扫描到数据结尾,会不会导致 [连接 2 ] 只能获取两万个 key 呢?

提前感谢各位大佬,我查了半天,只能查到just do my best,我可以允许 scan 出来的 key 多一点少一点,但也不能少太多吧

2777 次点击
所在节点    Redis
13 条回复
lpts007
2020-12-16 06:38:25 +08:00
不知道说啥,scan 和两个连接有啥关系?
teek
2020-12-16 08:59:21 +08:00
取决于你数据变动情况。redis.io/commands/scan#scan-guarantees
yRebelHero
2020-12-16 09:30:48 +08:00
redis 里的 key 都是存储在一个字典里的,有点类似于 Java 里的 HashMap,一维是数组,二维是链表,游标返回的就是第一维数组的位置索引,而且它的遍历不是从一维数组的第 0 位一直遍历到末尾,而是用的一种高位进位加法来遍历。举个例子,普通的是 0->1->2->3,高位进位加法是 0 -> 8 -> 4 -> 12 -> 2 这样的。
yRebelHero
2020-12-16 09:34:58 +08:00
不好意思,先发出去了,接上文。

遍历的时候如果有数据修改,改动后的数据能不能遍历到是不一定的。

既然你的问题的前提是:key 的数量时一直频繁变化的。那么问题 1 、2,返回的游标可能不一样,既然上面两个问题不相同,第 3 个问题就没法回答你了。
xuanbg
2020-12-16 09:58:52 +08:00
自己做一个 key 管理,Redis 已经很忙很辛苦了,就不要再为难 Redis 了。。。
lithium4010
2020-12-16 11:47:59 +08:00
你为啥要拿所有的 key ? key 很大的时候, 它这个就没有设计这种使用场景我理解
lithium4010
2020-12-16 11:48:23 +08:00
@lithium4010 我是只 key 的数量很大的时候
lithium4010
2020-12-16 11:48:40 +08:00
我是指..
qqqasdwx
2020-12-16 18:07:35 +08:00
@lpts007 和两个连接确实没什么关系,其实就是想问 scan 的游标是怎么维护的,多次扫描并行存在时会不会相互影响
qqqasdwx
2020-12-16 18:20:48 +08:00
@yRebelHero 谢谢您的耐心解答,那么用具体场景来举例子,比方说有两个用户查询全部 key,假设页面无限加载,一次 scan 的 count 设为 1,redis 里数量级相对固定(比如 2kw 数据,上下浮动 1w,但 key 会频繁变动,大量删除大量增加,但总数维持在 2kw ),那么如果出现了相同游标,会不会出现一个极限情况,用户 1 最终刷出了 2kw 数据,用户 2 只能刷出 2 条数据?
qqqasdwx
2020-12-16 18:29:48 +08:00
@lithium4010 比如淘宝商品页做无限加载,每秒都有大量商家上货,也有大量商家下架,不能说一个用户最终能看到全部商品,而另一个用户只能看到两页吧,当然这只是我假想了一个使用场景,想问的是在 redis 不维护 session 的情况下如何保证能扫描到大部分 key
yRebelHero
2020-12-16 20:16:37 +08:00
@qqqasdwx 其实不是很明白你描述的具体场景,但应该不会这么极端的,毕竟 key 在字典里都是经过 hash 了一次的,肯定是比较均匀地分布,不会那么极端的。
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 命令

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/735827

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX