聊聊高并发(五)理解缓存一致性协议以及对并发编程的影响

简介:

Java作为一个跨平台的语言。它的实现要面对不同的底层硬件系统,设计一个中间层模型来屏蔽底层的硬件差异,给上层的开发人员一个一致的使用接口。Java内存模型就是这样一个中间层的模型,它为程序猿屏蔽了底层的硬件实现细节,支持大部分的主流硬件平台。

要理解Java内存模型以及一些处理高并发的技术手段,理解一些主要的硬件知识是必须的。

这篇会说一下跟并发编程相关的一些硬件知识。


一个主要的CPU运行计算的步骤例如以下:

1. 程序以及数据被载入到主内存

2. 指令和数据被载入到CPU的快速缓存

3. CPU运行指令,把结果写到快速缓存

4. 快速缓存中的数据写回主内存


这个过程中,我们能够看到有两个问题

1. 现代的计算芯片都会集成一个L1快速缓存,我们能够理解为每一个芯片都有一个私有的存储空间。

那么当CPU的不同计算芯片要訪问同一个内存地址时,该内存地址的值会在CPU的不同计算芯片之间有多个拷贝,怎样同步这些拷贝

2. CPU读写是直接和快速缓存打交道。而不是和主内存直接打交道。由于通常一次主存訪问在几十到几百个时钟周期。而一次L1快速缓存的读写仅仅须要1-2个时钟周期,而一次L2快速缓存的读写仅仅须要数十个时钟周期。

那么CPU写到快速缓存的值何时写回到主内?假设是多个计算芯片在处理同一个内存地址。那么怎样处理这个时间差是个问题


对于第一个问题。不同的硬件结构处理的方式不一样。我们来理解一下互连线的概念。

互连线是处理器于主存以及处理器与处理器之间进行通信的媒介,有两种主要的互联结构:SMP(symmetric multiprocessing 对称多处理)和NUMA(nonuniform memory access 非一致内存訪问)

SMP系统结构非常普通。由于它们最easy构建。非常多小型server採用这样的结构。处理器和存储器之间採用总线互联。处理器和存储器都有负责发送和监听总线广播的信息的总线控制单元。可是同一时刻仅仅能有一个处理器(或存储控制器)在总线上广播,全部的处理器都能够监听

非常easy看出,对总线的使用是SMP结构的瓶颈。


NUMP系统结构中,一系列节点通过点对点网络互联,像一个小型互联网,每一个节点包括一个或多个处理器和一个本地存储器。一个节点的本地存储对于其它节点是可见的,全部节点的本地存储一起形成了一个能够被全部处理器共享的全局存储器。能够看出,NUMP的本地存储是共享的,而不是私有的,这点和SMP是不同的。NUMP的问题是网络比总线复制。须要更加复杂的协议。处理器訪问自己节点的存储器速度快于訪问其它节点的存储器。NUMP的扩展性非常好,所以眼下非常多大中型的server在採用NUMP结构。


对于上层程序猿来说。最须要理解的是互连线是一种重要的资源。使用的好坏会直接影响程序的运行性能。


大概理解了不同的互连结构之后,我们来看看缓存一致性协议。它主要就是处理多个处理器处理同一个主存地址的问题。

MESI是一种主流的缓存一致性协议,已经用在Pentium和PowerPC处理器中。它定义了缓存块的几种状态

  • modified(改动):缓存块已经被改动,必须被写回主存。其它处理器不能再缓存这个块
  • exclusive(相互排斥):缓存块还没有被改动。且其它处理器不能装入这个缓存块
  • share(共享):缓存块未被改动。且其它处理器能够装入这个缓存块
  • invalid(无效):缓存块中的数据无效

上图展示了MESI快速缓存一致性协议的状态转换实例。

1. 在a中,处理器A从地址a读取数据,将数据存入它的缓存并置为exclusive

2. 在b中。当处理器B试图从同样地址a读取数据时。A检測到地址冲突,以相关数据做出响应。此时a同一时候被A和B以shared状态装入缓存

3. 在c中,当B要对共享地址a进行写操作。则将状态改为modified,并广播提醒A,让它将它的缓存块状态设置为Invalid

4. 在d中。当A试图从a读取数据,会广播它的请求。B则把它改动的数据发送到A和主存,并设置两个副本的状态为shared来做出响应


很多其它缓存一致性协议的细节參考这篇 http://blog.csdn.net/realxie/article/details/7317630


缓存一致性协议存在的一个最大的问题是可能引起缓存一致性流量风暴。之前我们看到总线在同一时刻仅仅能被一个处理器使用。当有大量缓存被改动,或者同一个缓存块一直被改动时,会产生大量的缓存一致性流量。从而占用总线。影响了其它正常的读写请求。


一个最常见的样例就是假设多个线程对同一个变量一直使用CAS操作。那么会有大量改动操作。从而产生大量的缓存一致性流量,由于每一次CAS操作都会发出广播通知其它处理器,从而影响程序的性能。


后面我们会讲怎样优化这样的使用方式。


对于第二个问题,怎样处理改动数据从快速缓存到主内存的时间差。通常使用内存屏障来处理,后面会有专门的主题。


转载请注明来源:http://blog.csdn.net/iter_zc







本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5068812.html,如需转载请自行联系原作者

相关文章
|
3月前
|
canal 缓存 NoSQL
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
根据对一致性的要求程度,提出多种解决方案:同步删除、同步删除+可靠消息、延时双删、异步监听+可靠消息、多重保障方案
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
|
4月前
|
消息中间件 缓存 监控
如何保证缓存和数据库的一致性?
保证缓存和数据库的一致性的做法
|
1月前
|
缓存 NoSQL 中间件
redis高并发缓存中间件总结!
本文档详细介绍了高并发缓存中间件Redis的原理、高级操作及其在电商架构中的应用。通过阿里云的角度,分析了Redis与架构的关系,并展示了无Redis和使用Redis缓存的架构图。文档还涵盖了Redis的基本特性、应用场景、安装部署步骤、配置文件详解、启动和关闭方法、systemctl管理脚本的生成以及日志警告处理等内容。适合初学者和有一定经验的技术人员参考学习。
168 7
|
1月前
|
缓存 NoSQL 关系型数据库
mysql和缓存一致性问题
本文介绍了五种常见的MySQL与Redis数据同步方法:1. 双写一致性,2. 延迟双删策略,3. 订阅发布模式(使用消息队列),4. 基于事件的缓存更新,5. 缓存预热。每种方法的实现步骤、优缺点均有详细说明。
|
2月前
|
缓存 监控 算法
小米面试题:多级缓存一致性问题怎么解决
【10月更文挑战第23天】在现代分布式系统中,多级缓存架构因其能够显著提高系统性能和响应速度而被广泛应用。
56 3
|
2月前
|
缓存 弹性计算 NoSQL
新一期陪跑班开课啦!阿里云专家手把手带你体验高并发下利用云数据库缓存实现极速响应
新一期陪跑班开课啦!阿里云专家手把手带你体验高并发下利用云数据库缓存实现极速响应
|
2月前
|
消息中间件 缓存 中间件
缓存一致性问题,这么回答肯定没毛病!
缓存一致性问题,这么回答肯定没毛病!
|
2月前
|
存储 缓存 NoSQL
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
71 4
|
2月前
|
缓存 NoSQL Ubuntu
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
57 3
|
3月前
|
消息中间件 缓存 NoSQL
奇怪的缓存一致性问题
本文记录了缓存一致性问题的排查过程和解决方案,同时带读者朋友们一起回顾下相关的八股文。