
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 你为啥要拿所有的 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 命令 |