V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ben548
V2EX  ›  Redis

缓存失效后先返回再触发更新的场景要怎么处理?

  •  
  •   ben548 · 277 天前 · 1136 次点击
    这是一个创建于 277 天前的主题,其中的信息可能已经有所发展或是发生改变。
    场景:我要缓存一份数据,比如缓存 10 分钟,然后如果有访问,发现缓存失效了,就先返回,然后再触发缓存更新,这个先返回再触发缓存更新要怎么做呢?
    我想的方案:
    往消息队列里面发消息的方式,但是多用户并发的情况下,其实会有多个用户过来请求更新缓存,当然可以用分布式锁来处理,只让一个用户生成缓存成功。
    这个就是我的一个想法,有没有更好的方案?
    第 1 条附言  ·  276 天前
    更新缓存获取数据这个操作需要依赖外部接口,不是可以自行获取的
    5 条回复    2023-07-27 17:15:12 +08:00
    lanlanye
        1
    lanlanye  
       276 天前 via iPhone
    返回前用另外的线程/协程处理一下不就好了吗?还是说一个查询重到必须用消息队列?
    并发问题要看具体需求,一般来说加锁就完事了。
    RoninZc
        2
    RoninZc  
       276 天前
    设置两个 key,一个是 key_name 不过期,一个是 key_name_ttl 过期时间 10 分钟,每次拿这两个 key ,带 ttl 的不存在就异步更新缓存,直接返回第一个 key 的结果就好了,更新缓存可以加锁,没获取到锁就不执行就好
    ben548
        3
    ben548  
    OP
       276 天前
    @lanlanye 没记错的话另起一个协程,也要等这个更新缓存的协程执行结束才能返回结果吧,而且这个更新缓存获取数据的操作需要依赖外部接口,有请求失败的可能
    ben548
        4
    ben548  
    OP
       276 天前
    @RoninZc 可以是可以,我也是这么想的,不做缓存失效,因为可能存在缓存失效后一直更新失败的情况,那么会出现缓存一直为空接口返回数据也为空的状态。
    现在想的优化是是不是在高并发的情况下是不是可以减少竞争锁的请求量,比如已经有一个用户触发了异步更新,那么我就直接返回。
    比如有用户触发了异步更新就直接设置一个标志位这种处理方式,如果这个标志位存在就不去更新,更新成功后就删除这个标识位,但是又可能存在更新失败的可能,还有这个标志位删除失败导致永不更新的情况。所以细想其实还是有很多细节值得考虑的,我是在想有没有更简单的处理方式。
    lanlanye
        5
    lanlanye  
       276 天前 via iPhone
    @ben548 呃,不需要的。虽然不知道你使用什么技术栈,但正常点的语言实现异步处理都不会很困难,无论你用线程协程还是其他进程(消息队列也属于跨进程异步)。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3201 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 12:02 · PVG 20:02 · LAX 05:02 · JFK 08:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.