从硬件到软件去理解一致性

本文探讨了CPU的多核架构与分布式服务之间的相似性,指出两者都涉及一致性问题。CPU通过MESI协议解决缓存一致性,而分布式服务通常采用主从结构或数据隔离来确保一致性。同时,文章提到了服务SET化的趋势,以提高服务弹性和减少网络影响。总结中强调软件架构可以借鉴硬件解决方案,但需考虑网络因素带来的挑战。
摘要由CSDN通过智能技术生成


前言

看了很多操作系统和软件中间件之类的知识之后发现,软件和硬件在大的方面有时候解决的是一样的问题


一、CPU vs 分布式系统

如果咱们把多核CPU和分布式系统进行类比,发现有一些共同点。

1 CPU

每个CPU有自己的cache(level1和level2的cache都是每个核私有的),那么每个CPU对于私有cache的操作,是不是就很像是分布式系统

1 分布式服务

对于分布式服务,仔细考究起来,其实比CPU对于cache的处理还要简单。

一主多从:限制master才可以写,follower都是进行数据同步而已
多主服务:多主服务一般都是操作各自的数据,不管是Redis集群还是mysql的分库,只有当多主节点进行变化时才需要进行数据处理。Redis集群是重新处理hash槽的分布,mysql麻烦点,可能涉及到id的变化

二、一致性

一致性问题需要解决,最大的需要解决的问题就是顺序性

1.CPU

  1. CPU的MESI解决了cache的一致性问题,但是其实并没有明确要求顺序性,只需要遵循状态流转就行。
  2. 拿Intel的芯片架构举例,为了加快cache一致性,硬件层面添加了storeBuffer,来进行异步通知
  3. MESI解决的cache一致性,并不包括storeBuffer里的数据
  4. storeBuffer可以理解为cache line的缓存,所以相当于缓存的缓存又是各自维护,不一致;
  5. 即便是Java的增强型volatile,通过内存屏障也只是达到了cache的可见性:具体实现方式是通过执行lock前缀指令,而Intel芯片架构对于lock前缀指令的执行会将store buffer强制和cache刷进内存,见这一篇博客,所以可以发现volatile的最佳使用场景是一写多读,单例模式的懒汉方式
  6. volatile之所以不是线程安全的,也就是volatile只保证了可见性,写操作并发写的时候,线程就不安全的,当利用JIT编译之后查看汇编语言可以发现,变量的写操作,一般是先把变量复制到寄存器,然后在寄存器里更改,再写回cache line(volatile变量会先写回storeBuffer)。也就是写操作是个RMW(read-modify-write)的过程,所以要保证线程安全的话,必须得通过锁,将RMW变为原子操作

2.分布式服务

  1. 为了避免多核CPU的缓存一致性问题,多数中间件使用的方式都是只有leader支持写,follower只支持同步,剩下需要解决的问题就是要满足强一致性还是最终一致性
  2. 如果是多主节点的集群,譬如Redis,通过分配hash槽(16384个),来进行数据隔离,但是可能因此带来的问题就是当发生multiGet请求的时候,会生成IO放大的问题;mysql的多主集群的话,一般也会隔离数据,当然也会有双向同步的情况,不过一般会有中心库作为总数据备份

3. SET化服务

  1. 现在开始流行服务set化,不再是存储层进行分布式或者叫计算层服务分布式,而是集群之间并行,集群之间互不影响,集群内部,分布式。这样的服务更加弹性化。对于LBS服务效果明显。

总结

  1. 软件层面需要解决的问题,其实在硬件层面早就解决过,在软件层面进行技术架构时可以进行参考。
  2. 不过硬件层面比软件层面又好在没有网络因素在里面,所以需要对于具体的业务或者功能有相应的取舍
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值