• 请不要在回答技术问题时复制粘贴 AI 生成的内容
liyunyang
V2EX  ›  程序员

分布式环境中,业务报错如何保证 redis 数据一致性?

  •  
  •   liyunyang · Jan 5, 2023 · 3278 views
    This topic created in 1230 days ago, the information mentioned may be changed or developed.
    这是一个困扰我很久的问题,一直不知道有什么好的处理方式,故来此地取经。

    举个例子:

    分布式订单服务 A 和库存服务 B

    服务 A 调用服务 B ,服务 A 修改了 redis 缓存,服务 B 报错了,全局事物回滚,服务 A 的缓存没有回滚

    各位大佬,这种情况有什么推荐处理方式吗?
    17 replies    2023-01-07 07:50:33 +08:00
    qq976739120
        1
    qq976739120  
       Jan 5, 2023
    redis 的数据应该是跟着 mysql 的,所以 a 服务的数据库回滚以后,redis 应该跟着 a 服务的 mysql 走,而不是在 b 服务里做处理
    liyunyang
        2
    liyunyang  
    OP
       Jan 5, 2023
    @qq976739120 #1 redis 怎么回滚?
    7911364440
        3
    7911364440  
       Jan 5, 2023
    加一个服务监听数据库日志,数据写入成功再刷新缓存。
    leonshaw
        4
    leonshaw  
       Jan 5, 2023
    @liyunyang 失效
    zuixinwenyue
        5
    zuixinwenyue  
       Jan 5, 2023
    我觉得应该把修改 redis 缓存,放在调用服务 B 之后,如果调用 B 报错也不需要回滚 redis
    dwlovelife
        6
    dwlovelife  
       Jan 5, 2023
    服务 A 为什么不等服务 B 成功了再去修改缓存
    liyunyang
        7
    liyunyang  
    OP
       Jan 5, 2023
    @7911364440 #3 诶,这个应该是最好的方式吧,不过实现起来比较复杂,维护成本也不低
    liyunyang
        8
    liyunyang  
    OP
       Jan 5, 2023
    @dwlovelife #6 一言难尽,老项目了,业务非常复杂,如果是新功能,肯定会注意到这个的
    gold2022
        9
    gold2022  
       Jan 5, 2023
    @liyunyang 失效原来 redis 缓存,让他重新根据 mysql 生成缓存
    CodeSorcerer
        10
    CodeSorcerer  
       Jan 5, 2023   ❤️ 1
    用 canal 来更新 redis ?
    fkdog
        11
    fkdog  
       Jan 5, 2023   ❤️ 1
    将刷新缓存、发送 mq 等操作放到事务提交成功的 callback 里。
    如果 A 服务在事务中修改了 redis ,那么其他线程会读到错误的缓存数据。
    等事务完成同步到 db 里以后再去做缓存的更新操作。

    其实有的时候也没必要追求强一致,存库实时都在变,某个用户在某个时间点看到的库存也许再下一秒就变了,只要 CUD 的时候保证一致就行了。
    qq976739120
        12
    qq976739120  
       Jan 5, 2023
    @liyunyang 不是回滚 redis,是 a 数据库回滚后,有个服务去修改 redis
    vitoliu
        13
    vitoliu  
       Jan 5, 2023 via iPhone
    最简单的解决方案:每次更新操作,先清空所有缓存。
    notwaste
        14
    notwaste  
       Jan 5, 2023
    类似八股文很多,最常见的面试产物就是延迟双删,而且这里 A 服务不应该修改缓存而是删除缓存
    Joker1995
        15
    Joker1995  
       Jan 5, 2023   ❤️ 1
    我自己认为不 manual 去处理缓存,通过 canal+kafka 进行处理会好些,确实会有短时间的不一致
    Haires
        16
    Haires  
       Jan 6, 2023
    缓存应该是删除,而不是更新
    pagewang
        17
    pagewang  
       Jan 7, 2023 via iPhone
    失败后重新生成新的缓存,只允许第一个请求去 db 查库存,其他的读缓存
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1468 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 72ms · UTC 17:01 · PVG 01:01 · LAX 10:01 · JFK 13:01
    ♥ Do have faith in what you're doing.