zoukankan      html  css  js  c++  java
  • CacheAsidePattern和延时双删

    一、为什么不直接更新缓存?

    无论写数据库和写缓存,哪个操作在前,都不要更新缓存;

    因为更新数据库和更新缓存是两个独立的阶段,并发场景下不同线程的两个阶段,可能发生交叉,最终导致数据库和缓存长时间不一致,这种长时间的不一致是不能容忍的。

    不一致时长:缓存过期时间,或下一次更新。

    二、如何理解Cache Aside Pattern?

    这是一种公认的经典缓存一致性处理模式,采用先写库,再删缓存的操作。这种无锁的方案,只能保证并发的前提下,尽可能的降低不一致的概率。这也是AP策略下的一种BASE方案

    1. 理想状态:因为并发场景下,这两个阶段之间其他线程会读到旧的缓存数据,但经过这个极短的间隙后,最终会再次一致。

    不一致时长:写数据库后删除缓存前。

    1. 读卡顿问题:极端一点,在三个以上并发时,两写一读:
    1.线程1完成了写数据库和删缓存;
    2.此时由于缓存被删除,线程2只能读数据库,读完后写入缓存前,线程2卡顿了。
    3.线程3又完成了一次写和删。
    4.线程2才将其从数据库读到的数据写入缓存
    5.此时缓存和数据库就不一致了。
    

    不一致时长:缓存过期时间,或下一次更新。

    三、延时双删策略解决了哪些极端场景下的数据不一致问题?

    针对读卡顿问题,在Cache Aside Pattern的基础上,延时地再删一次缓存,能有效的缩短缓存不一致时长。

    可以采用MQ延时消息,或其他异步手段。

    延时的时长设定,通常1、2秒就能覆盖绝大多数场景。

    不一致时长:延时时长。

    四、注意

    1. 即便用【Cache Aside Pattern + 延时双删】这种组合,仍不能保证100%的缓存一致性。

    2. 但通常,使用缓存的场景本身就不要求强一致性。

    3. 实在要保证缓存和数据库的强一致性,最好的办法就是分布式锁,但是并发性能较差,除非场景要求强一致性,且能容忍较低的并发性才用锁。

    学习使我充实,分享给我快乐!
  • 相关阅读:
    ​Docker 数据卷的管理及自动构建docker镜像
    写代码有这16个好习惯,可以减少80%非业务的bug
    启动Docker“Got permission denied while trying to connect to the Docker daemon socket“问题(亲测可用)
    Docker从入门到干活,看这一篇足矣 [建议收藏]
    docker技术入门与精通(2020.12笔记总结)
    MySQL相关 死锁的发生和避免
    使用docker运行zabbixserver
    Cloudflare 是谁?
    扛得住的MySQL数据库架构
    好未来第一届PHP开源技术大会资料分享
  • 原文地址:https://www.cnblogs.com/JaxYoun/p/15456516.html
Copyright © 2011-2022 走看看