关于 redis 的 scan 命令并发执行的问题,望解答 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
qqqasdwx
V2EX    Redis

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

  •  
  •   qqqasdwx 2020-12-15 23:59:09 +08:00 3571 次点击
    这是一个创建于 1822 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 多一点少一点,但也不能少太多吧

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

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

    既然你的问题的前提是:key 的数量时一直频繁变化的。那么问题 1 、2,返回的游标可能不一样,既然上面两个问题不相同,第 3 个问题就没法回答你了。
    xuanbg
        5
    xuanbg  
       2020-12-16 09:58:52 +08:00
    自己做一个 key 管理,Redis 已经很忙很辛苦了,就不要再为难 Redis 了。。。
    lithium4010
        6
    lithium4010  
       2020-12-16 11:47:59 +08:00
    你为啥要拿所有的 key ? key 很大的时候, 它这个就没有设计这种使用场景我理解
    lithium4010
        7
    lithium4010  
       2020-12-16 11:48:23 +08:00
    @lithium4010 我是只 key 的数量很大的时候
    lithium4010
        8
    lithium4010  
       2020-12-16 11:48:40 +08:00
    我是指..
    qqqasdwx
        9
    qqqasdwx  
    OP
       2020-12-16 18:07:35 +08:00
    @lpts007 和两个连接确实没什么关系,其实就是想问 scan 的游标是怎么维护的,多次扫描并行存在时会不会相互影响
    qqqasdwx
        10
    qqqasdwx  
    OP
       2020-12-16 18:20:48 +08:00
    @yRebelHero 谢谢您的耐心解答,那么用具体场景来举例子,比方说有两个用户查询全部 key,假设页面无限加载,一次 scan 的 count 设为 1,redis 里数量级相对固定(比如 2kw 数据,上下浮动 1w,但 key 会频繁变动,大量删除大量增加,但总数维持在 2kw ),那么如果出现了相同游标,会不会出现一个极限情况,用户 1 最终刷出了 2kw 数据,用户 2 只能刷出 2 条数据?
    qqqasdwx
        11
    qqqasdwx  
    OP
       2020-12-16 18:29:48 +08:00
    @lithium4010 比如淘宝商品页做无限加载,每秒都有大量商家上货,也有大量商家下架,不能说一个用户最终能看到全部商品,而另一个用户只能看到两页吧,当然这只是我假想了一个使用场景,想问的是在 redis 不维护 session 的情况下如何保证能扫描到大部分 key
    yRebelHero
        12
    yRebelHero  
       2020-12-16 20:16:37 +08:00
    @qqqasdwx 其实不是很明白你描述的具体场景,但应该不会这么极端的,毕竟 key 在字典里都是经过 hash 了一次的,肯定是比较均匀地分布,不会那么极端的。
    huskyui
        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 命令
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5094 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 08:04 PVG 16:04 LAX 00:04 JFK 03:04
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86