精华内容
下载资源
问答
  • 缓存一致性

    千次阅读 2019-01-10 18:39:42
    缓存一致性硬件单核多核缓存一致性协议(MESI)MESI 状态转换 硬件 硬件之间的处理速度不相等,尤其是处理器和内存之间。一般都是内存跟不上处理器的处理速度。 所有在他们之间引入了缓存(cache)。 缓存有2大特点...

    硬件

    硬件之间的处理速度不相等,尤其是处理器和内存之间。一般都是内存跟不上处理器的处理速度。
    所有在他们之间引入了缓存(cache)。
    缓存有2大特点:
    1.时间局部性(被使用过的内存地址很有可能被再次使用到)
    2.空间局部性(被使用的地址周围部分也有可能被使用到,所以将内存中某块地址引入缓存里的时候通常会将周围的也引入缓存中)

    单核

    在这里插入图片描述
    单核单缓存,这种就直来直往,从memory中取出数据通过bus(总线)放入cache,然后cpu访问cache。

    多核

    在这里插入图片描述
    多核下,每个核拥有自己的一级缓存,可能每个一级缓存里面都有一部分的共享内存,即他们保存着memory中相同的一块。
    如果没有约束,这可能会对memory中的数据造成破坏,如果多个一级缓存同时修改了共享区域,并保存至主存中。
    所以引入了 缓存一致性协议(MESI)

    缓存一致性协议(MESI)

    M:被修改(Modified)处理器对缓存的值进行了修改,但是还么同步到主存上,或者发送给其他处理器。
    E:独占(Exclusive)存在于某个缓存中,其他缓存中没有与他相同的地址,且还没有被修改过。
    S:共享(Share)多于一个缓存拥有同一块地址。
    I:无效(Invalid)缓存不在拥有这块地址。

    MESI 状态转换

    在这里插入图片描述
    local 表示当前缓存,remote 表示其他缓存
    例如:
    E表示独享的,就是只有当前缓存存在这块地址,当他被修改了则会从E转换成M
    如果多核(A、B。。。)读取了同样的数据,则他们是S(共享的)。
    A对共享的数据进行了修改,那么S会转换成M,且其他缓存中的S会被转换成I,因为需要进行同步。A将修改的数据同步会主存后,他的状态会变成S,A无法感知他就是唯一的。B如果在读取共享数据,则还是S状态的数据。

    展开全文
  • 缓存一致性?get

    2021-09-15 18:41:41
    人人都懂缓存一致性,咱也得懂。

    大家好,我是老三,今天又是被算法致郁的一天,写篇文章缓一缓。

    这篇文章,我们来看看缓存一致性问题。

    缓存一致性

    我接下来会巴巴说一堆缓存一致性,但是——

    作为一名暴躁老哥,我先把结论撂这了!

    缓存和数据库的强一致性无法实现!

    CAP理论了解一下,缓存适用的场景属于CAP中的AP,是非强一致性的场景。

    那还扯个犊子的缓存一致性?洗洗睡吧。

    BASE理论接着了解一下,强一致性保证不了,那只好委屈求全,尽量保证最终一致性呗。

    最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。

    所以,我们追求的是尽可能保证缓存和数据库的最终一致性。

    CAP和BASE理论

    先更新数据库,再删除缓存

    Cache Aside Pattern

    在开始之前,我们先来科普一下缓存+数据库读写,最经典的Cache Aside Pattern。

    • 读取:先读取缓存,缓存里没有,读取数据库,然后返回响应,顺斌保存缓存

    读取

    • 更新:先更新数据库,然后删除缓存

    更新

    为什么是删除缓存,而不是更新缓存?

    • 并发情况下更新缓存可能会带来种种问题,直接删除缓存更加稳妥。
    • 缓存更新在很多时候需要耗费资源,直接删除,用时再从数据库读取,写进缓存,更省性能。

    一致性问题

    那么我们采用这种先更新数据库,再删除缓存,可能会出现什么问题呢?

    假如,我们更新数据库成功,接下来还没来删除缓存,或者删除缓存失败怎么办?

    那么很明显,这时候其它线程进来读的就是脏数据。

    先更数据库,后删缓存问题

    那怎么解决呢?

    解决方案

    既然删除缓存失败会导致脏数据,那我们就想办法让它能删除成功呗。

    消息队列重试机制

    我们可以引入一个重试机制。

    如果删除缓存失败,向消息队列发送消息,把删除失败的key放进去,消费消息队列,获取要删除的key,然后去重试删除。

    引入消息队列重试

    但是,这么干,好好的业务,咱们又引入了消息队列,对现有的业务造成了入侵,复杂度又提升了。

    监听binlog异步删除

    其实还有另外一种办法,我们可以用一个服务(比如阿里的 canal)去监听数据库的binlog,获取需要操作的数据。

    然后用另外一个服务获取订阅程序传来的信息,进行缓存删除操作。

    监听binlog异步删除

    这样一来,对我们本身的业务入侵就小了很多。

    先删除缓存,再更新数据库

    一致性问题

    我们看一下,如果先删除缓存,再更新数据库可能会带来什么问题。

    在并发情况下,先删除缓存,再更新数据库,此时数据库还未更新成功,这时候有其它线程进来了,读取缓存,缓存不存在,读取数据库,读取的是旧值,这时候,缓存不一致就发生了。

    先删缓存,后更数据库不一致

    解决方案

    延时双删

    延时双删是什么意思呢?

    就是在删除缓存,更新数据库之后,休眠一段时间后,再次删除缓存。

    延时双删

    延时删除之后,就把缓存里缓存的旧值给删除了。

    再有请求进来,就是读取数据库里的新值,再把新值保存进缓存。

    当然,第二次删除也有失败的可能,怎么办呢?重试。那怎么重试呢?前面写了。

    关于删除,还有一个兜底的方案——设置缓存过期时间,这样一来,哪怕缓存了脏数据,但是脏数据总有过期的时候,不至于一直不一致。

    总结

    我们来简单总结一下,首先对缓存的操作,删除优于更新,所以要删除,而不是更新。

    删除缓存两种方式:

    • 先更新数据库,在删除缓存。缓存不一致的两种处理方式是消息队列重试机制binlog异步删除
    • 先删除缓存,再更新数据库。缓存不一致的处理方式是延时双删

    当然,这些方案无疑都增加了系统的复杂度。

    如果不是并发特别高的话,就没有必要过度设计。

    简单的事情重复做,重复的事情认真做,认真的事情有创造性地做。

    我是三分恶,一个努力学习中的程序员。

    点赞关注不迷路,咱们下期见!



    参考:

    [1]. 缓存与数据库一致性问题深度剖析

    [2]. 数据库和缓存一致性的几种实现方式,我们来聊聊?

    [3]. 面试官:缓存一致性问题怎么解决?

    [4]. 美团二面:Redis与MySQL双写一致性如何保证?

    展开全文
  • 多处理器缓存一致性方案的系统可靠性分析
  • 缓存一致性协议

    千次阅读 2018-03-28 22:55:13
    缓存一致性协议 简介 缓存一致性协议是为了解决多核以及多处理器的多个缓存之间的数据不一致提出来的,缓存一致性协议分为两种,第一种是基于窥探的协议(snoop-based),第二种是基于目录的协议(directory-based...

    缓存一致性协议

    简介

    缓存一致性协议是为了解决多核以及多处理器的多个缓存之间的数据不一致提出来的,缓存一致性协议分为两种,第一种是基于窥探的协议(snoop-based),第二种是基于目录的协议(directory-based),基于窥探的协议在共享总线上广播一致信息,基于目录的协议能更好地扩展。MESI协议是基于目录的协议,本文主要讲述MESI协议。

    MESI协议

    MESI协议为cache block定义了四种状态,分别是Modified(M),Exclusive(E),Shared(S)和Invalid(I)。

    • Modified状态:当前cache block的内容与内存不同,是脏的(dirty),并且只有一个core拥有这个cache block的副本
    • Exclusive状态:当前cache block的内容与内存一致,是干净的(clean),并且只有一个core拥有这个cache block的副本
    • Shared状态:当前cache block的内容与内存一致,是干净的(clean),但是不止一个core拥有这个cache block的副本
    • Invalid状态:当前cache block的内容过时(无效)

    举个不那么恰当的例子:
    比如说现在有一个project,需要四个人(core)参与到coding工作,为了版本控制,我们将代码传到github(内存)上,四个人分别是甲乙丙丁,对应着core0,core1,core2和core3,每个人都有自己的计算机(local cache),平时在自己的计算机上coding。
    现在,假设甲从github(内存)上下载(load)了某一个类文件(cache block)到他的计算机(甲的local cache),而乙丙丁的计算机并没有这个类文件(cache block)的副本,这时候甲独占着这个类文件的副本,并且和github(内存)上一样,所以此时这个类文件的状态是exclusive。
    假设这时候丁也从github上下载了这个类文件到他的计算机上,这时候,这个类文件在甲和丁两个人的计算机上都有副本,并且和github上一样,所以此时这个类文件的状态是shared。
    假设现在丁在自己的计算机上对这个类文件进行了修改,此时,甲的计算机上的这个类文件就过时了,成了invalid状态,而这个类文件的最新副本在丁的计算机上,且只有丁的计算机上有这个类文件的最新副本,同时这个类文件和github上的内容不一致,是脏的(dirty),所以这个类文件的状态就是modified。

    下面是《大话处理器》书中MESI的状态迁移图,拿过来借用一下:
    这里写图片描述

    • local read代表着本内核读取本内核的cache中的数据,相当于甲在自己的计算机上阅读类文件
    • load write代表着本内核写本内核的cache中的数据,相当于甲在自己的计算机上修改类文件
    • remote read代表着其他内核读取其他内核的cache中的数据,假设我就是甲,那么乙丙丁就是其他人,这就相当于乙在乙的计算机上读取类文件
    • remote write代表着其他内核写其他内核的cache中的数据,同样,假设我是甲,这就相当于乙在乙的计算机上修改类文件。

    MESI状态迁移:

    • 如果当前core的cache block状态是invalid

      • 那么当前core读取这个cache block(local read)的时候,考虑两种情况:
        • 如果其他core的cache上没有这个cache block的副本,那么从内存中加载,此时只有当前core拥有和内存中一致的cache block副本,所以转移到exclusive状态
        • 如果其他core的cache上有这个cache block的副本,那么从LLC中加载,此时不止一个core拥有和内存中一致的cache block副本,所以转移到shared状态
      • 当前core修改这个cache block(local write)的时候,这个cache block的内容与内存中不一致(dirty),并且只有当前core拥有这个最新的副本,所以转移到modified状态
      • 其他core读取这个cache block(remote read)以及其他core修改这个cache block(remote write)的时候,对当前core的cache中的cache block没有任何影响
    • 如果当前core的cache block状态是exclusive,

      • 那么当前core读取这个cache block(local read)的时候,当前core的cache block的状态还是exclusive,因为local read不会让其他core拥有这个cache block的副本,并且也不会对这个cache block进行修改
      • 当前core修改这个cache block(local write)的时候,因为对这个cache block进行了修改,也就和内存中不一致了,所以当前core的cache block转移到modified状态
      • 其他core读取这个cache block(remote read)的时候,其他core的cache中也会拥有这个cache block的副本,所以此时当前core的cache block转移到shared状态
      • 其他core修改这个cache block(remote write)的时候,当前core的cache block数据过时,不再有效,所以当前core的cache block转移到invalid状态
    • 如果当前core的cache block处于shared状态

      • 那么当前core对cache block的读取(local read)以及其他core对cache block的读取(remote read)对当前core的cache block状态无影响,所以还是shared状态
      • 当前core对cache block的修改(local write)会使得当前core的cache block内容与内存中不一致,所以会转移到modified状态
      • 其他core对cache block的修改(remote write)会使得当前core的cache block内容过时失效,所以转移到invalid状态
    • 如果当前core的cache block处于modified状态

      • 那么当前core对cache block的读取(local read)以及当前core对cache block的修改(local write)对当前core的cache block状态不产生影响,所以还是modified状态
      • 其他core对cache block的读取(remote read)会导致其他core拥有这个cache block的最新副本,所以此时不再是当前core独占,所以转移到shared状态
      • 其他core对cache block的修改(remote write)会导致当前core的cache block内容过时失效,所以转移到invalid状态
    展开全文
  • 行业分类-设备装置-为缓存一致性处理缓存回写和缓存淘汰
  • 文章目录系列文章目录前言一、MESI缓存一致性协议二、MESI协议怎么保证数据一致性的呢?三、cpu是怎么更新这4种状态的呢?总结 前言 上篇文章《多核cpu怎么保证数据一致性(二)cpu为什么要用高速缓存?L1,L2,L3 ...

    系列文章目录

    多核cpu怎么保证数据一致性(一)为什么要做指令重排序?
    多核cpu怎么保证数据一致性(二)cpu为什么要用高速缓存?L1,L2,L3 cache
    多核cpu怎么保证数据一致性(三)MESI缓存一致性协议
    多核cpu怎么保证数据一致性(四)volatile关键字、happens-before原则、内存屏障



    前言

    上篇文章《多核cpu怎么保证数据一致性(二)cpu为什么要用高速缓存?L1,L2,L3 cache》我们说了为什么要用多核cpu,以及为什么要用cpu高速缓存,但是因为L1,L2cache是每个cpu的核独有的,怎么保证缓存一致性就成了一个问题,那么cpu是怎么解决缓存一致性的呢?


    一、MESI缓存一致性协议

    之所以叫做MESI是因为把cpu的内核中的高速缓存分成了四种状态分别是:

    • M(Modified):已修改-数据被修改了
    • E(Exclusive):独占的-数据是此cpu核独占的
    • S(Shared):共享的-此数据是多个cpu核所共享的
    • I(Invalid):失效的-此数据被其他cpu核所修改了,失效

    二、MESI协议怎么保证数据一致性的呢?

    cpu核心
    上图中,假使有一个数据int a = 1,这个数据被两个线程读取到了,线程1在cpu核心1上面执行,线程2在cpu核心2上面执行

    • 此时数据a的状态在cup核心1和cpu核心2上面就是S(Shared)共享的,
    • 线程1执行指“a=a+1”,此时数据a在cpu核心1中的状态就是M(Modified)修改的,数据a在cpu核心2上面的状态就变成了I(Invalid)失效的,此时如果cpu核心2再去读取a的数据,会发现a数据的状态是Invalid,那么就会直接去内存读取。
    • 如果数据a,只在cpu核心1的高速缓存里面,而在cpu核心2的高速缓存里面没有,此时数据a在cpu核心1中就是E(Exclusive)独占的。

    三、cpu是怎么更新这4种状态的呢?

    如果每个cpu核心都要与其他cpu核心交互这样的复杂度就是N2,而cpu核心不止与其他cpu核心通信还要与一些内存等等数据通信,这样复杂度会很高。

    如果有一根总线,所有的cpu都与这根总线通信,复杂度就会降低很多,而真实的cpu的核心也是这样的,最新的Intel处理器中,有一种快速通道互联的技术(如果你是搞软件的,我觉得了解到这里就够了,没必要再去研究什么是快速通道互联技术)。


    总结

    今天我们说了什么是MESI缓存一致性协议,就是(M、E、S、I)以及MESI怎么保证缓存一致性,和cpu更新这4种状态的方式,就是通过总线,下篇文章,我们将一起学习volatile关键字、happens-before原则,以及实现他们的基础内存屏障。

    其实我一直认为,工欲善其事,必先利其器,在工具的使用上,我准备了专栏《java开发工具》,如果你感兴趣可以来看看

    展开全文
  • 内存屏障保证缓存一致性

    千次阅读 2017-12-24 15:32:59
    缓存一致性协议给缓存行(通常为64字节)定义了个状态:独占(exclusive)、共享(share)、修改(modified)、失效(invalid),用来描述该缓存行是否被多处理器共享、是否修改。所以缓存一致性协议也称MESI。
  • 多处理器环境下的存储模型与缓存一致性协议的分析。
  • 这次就来介绍一下Redis的缓存一致性的问题。 对于缓存和数据库的更新操作,主要分为以下两种 先删除缓存,再更新数据库 先更新数据库,再删除缓存 首先可能会带来疑惑的点是,为什么这里是删除缓存而不是更新缓存...
  • 提升稀疏目录缓存一致性系统性能的方法
  • 遇到缓存一致性问题,你怎么解决的? 由于缓存和数据库不属于同一个数据源,本质上非原子操作,所以是无法保证强一致性的,只能去实现最终一致性。 解决方案: 延时双删:先更新数据库同时删除缓存,等2秒后再删除...
  • 10 张图打开 CPU 缓存一致性的大门.pdf
  • 10张图打开CPU缓存一致性的大门.pdf
  • 缓存一致性协议MESI,cpu cache

    万次阅读 2018-05-15 10:08:08
    不论是cpu中cache缓存还是项目开发中的缓存,缓存的好处是提高运行速度,带来的问题是如何保证缓存一致性。 cpu的内置缓存保证与主内存一致性的方法有2种:1.总线锁(锁住总线,同步cpu缓存与内存中的脏数据,...
  • 面试官:缓存一致性问题怎么解决?.pdf
  • 详细介绍计算机缓存一致性协议的概念,以及指令重排序的概念。
  • 分布式缓存一致性问题解决方案

    千次阅读 2020-08-22 21:27:03
    该文章主要是来自于通用配置系统使用了文件缓存作为二级缓存,他的一致性如果保证的问题,目前了解到的有三种方案: ... 2.采用队列方式,将更新作为消息放入mq中进行...3.缓存同步、如何保证缓存一致性、缓存误用 ...
  • 1、cpu高速缓存 工业实践表明,三层最合适 读 l0 >l1 > l2 > 内存 写 内存 > l2 >...同一颗cpu可能有多核,他们之间有缓存一致性保障,也就是同一行的数据发生改变后,需要通知彼此。 ...
  • MESI缓存一致性协议 多核CPU多级缓存一致性协议MESI 多核CPU的情况下有多个一级缓存,如何保证缓存内部数据的一致,不让系统数据混乱。这里就引出了一个一致性的协议MESI。 MESI协议缓存状态 MESI 是指4中...
  • Arteris全新半导体架构重新定义异构多核高速缓存一致性.pdf
  • 缓存一致性协议是Java内存模型中的一种协议,具体如图所示: 缓存一致性协议分为四种状态: Modified(修改):数据有效,数据被修改了,和内存中数据不一致,数据只存在于本Cache中。 Exclusive(独享):数据...
  • 数据库和缓存一致性的问题

    千次阅读 2020-04-01 16:58:36
    经常看到有人问怎么解决数据库和缓存一致性的问题,这个问题我觉得是不要去解决。 如果你不信你先看我列的几种情况 假设 数据库一开始和缓存都是1元。 用户更新数据库的同时双写缓存。 1.双写不删 写库充值...
  • CPU缓存一致性协议MESI - 笔记

    万次阅读 2020-04-08 19:49:19
    CPU缓存一致性协议MESI CPU高速缓存(Cache Memory) CPU为何要有高速缓存 CPU在摩尔定律的指导下以每18个月翻一番的速度在发展,然而内存和硬盘的发展速度远远不及CPU。这就造成了高性能能的内存和硬盘价格及其...
  • 缓存一致性和跨服务器查询的数据异构解决方案canal.pdf
  • VISU:一种基于自更新的简单有效的缓存一致性协议
  • redis缓存一致性问题解决方案

    万次阅读 2019-03-18 22:39:19
    但是引入缓存之后,随之而来的问题就是当DB数据更新时,缓存中的数据就会与db数据不一致,这时候就需要对缓存的数据进行更新或者淘汰缓存,这篇文章就是分析各种处理缓存一致性问题的解决方案。 先更新DB还是操作...
  • 万字长文深入剖析缓存一致性协议(MESI),内存屏障.pdf

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 390,402
精华内容 156,160
关键字:

缓存一致性