分布式架构-CAP

  • Post author:
  • Post category:其他




分布式架构-CAP

分布式系统基础原则

分布式架构

集群,系统多节点

痛点:网络不可靠

维护各个节点的状态,保障各个节点之间数据的同步



1、概述:

  • 布鲁尔定理
  • 对于一个分布式系统而言,不能同时满足以下三点:

    • 一致性(consisteny)
    • 可用性(Availability)
    • 分区容错性(Partition tolerance)
  • 最多只能同时满足以上两点,其中P是必须要保留的
  • 一致性:系统中的所有数据备份,在同一时刻是同样的值,所有节点在同一时间的数据完全一致,越多节点,数据同步越耗时(数据同步耗时),

    • 强一致性:对于关系型DB,更新过的数据后续的访问都能看到。比如小明更新V0到V1,那么小华读取的时候也应该是V1。
    • 弱一致性:能容忍后续的部分或者全部访问不到。比如小明更新VO到V1,可以容忍那么小华读取的时候是V0。
    • 最终一致性:经过一段时间后要求能访问到更新后的数据。比如小明更新VO到V1,可以使得小华在一段时间之后读取的时候是V0。
  • 可用性:每个请求都能在合理的时间内获得符合预期的响应(不保证获取的结果是最新的数据)。
  • 分区容错性:当节点之间的网络出现问题之后,系统依然能正常提供服务。单节点故障(必不可少),由于网络问题,将系统的成员隔离成了2个区域,互相无法知道对方的状态,系统中任意信息的丢失或失败不会影响系统的继续运作



2、分析CA\CP\AP



2.1、CA不可取(网障)

  • 选择CA,放弃p分区容错性,假设有两个节点互相通信,当发生网络故障时,为了保证 C(一致性),那么就必须将系统锁住(进行数据同步),不允许任何写入操作,否则就会出现节点之间数据不一致了,此时如果有其他请求,系统是不可用的,违背了可用性A
  • 在网络正常情况下,CA是可以实现的
  • 没有p,不能叫分布式系统



2.2、CP架构:

  • 当有客户端向节点A进行写入请求时(准备写入Message 2),节点A会不接收写入操作,导致写入失败,这样就保证了节点A和节点B的数据一致性,即保证了Consisteny(一致性)。
  • 如果有另一个客户端向B节点进行读请求的时候,B请求返回的是网络故障之前所保存的信息(Message 1),并且这个信息是与节点A一致的,是整个系统最后一次成功写入的信息,是能正常提供服务的,即保证了Partition tolerance(分区容错性)。
  • 必须在p的保证下,各个节点之间进行数据同步(耗时),此时服务不可用,违反了可用性,如果仍然对外提供服务,就又违背了一致性,故必须保证此时服务不可用
  • zookeeper
  • Nacos 持久实例



2.3、AP架构

  • 由于网络问题,节点A和节点B之前不能互相通讯。
  • 当有客户端(向节点A进行写入请求时(准备写入Message 2),节点A允许写入,请求操作成功。但此时,由于A和B节点之前无法通讯,所以B节点的数据还是旧的(Message 1)

    同步失败

  • 当有客户端向B节点发起读请求时候,读到的数据是旧数据,与在A节点读到的数据不一致。但由于系统能照常提供服务,所以满足了Availability(可用性)要求。
  • EUREKA,REDIS,Nacos 临时实例



3、注意事项;



3.1、注册中心的选择:

  • Zookeeper:CP设计,保证了一致性(数据同步),集群搭建的时候,某个节点失效,则会进行选举行的leader,或者半数以上节点不可用,则无法提供服务,因此可用性没法满足—金融行业,数据同步,锁服务,此时服务不可用
  • Eureka:AP原则,无主从节点,一个节点挂了,自动切换其他节点可以使用,去中心化–,数据有可能不一致



3.2、分布式锁

Redis分布式锁和Java锁的区别

  1. 分布式部署的话,Java锁是锁当前机器上的请求,无法对其他机器的请求进行加锁,因为Java锁用的是jvm的机制,只在本机生效
  2. 即使项目就是单机部署的,那么在加锁的时候,Java锁的粒度会更大,Java锁会对接口的其他请求全部阻塞,但是分布式锁,只会对接口的某一个key进行请求的时候,加锁;
  3. Redis分布式锁有key的入参,如果同时key1和key2都来请求接口,那么Redis分布式锁可以同时执行,但是Java锁,不行,会阻塞key2的请求

Redis分布式锁和zk分布式锁怎么选择:

  1. Redis采用的是AP模式,zk采用的是CP模式
  2. Redis分布式锁简单粗暴,获取不到锁,就直接不断的重试,比较消费资源、性能
  3. Redis本身的设计就不是强一致性的,所以,在一些极端的场景下,会出现问题,但是大部分情况下,是不会遇到所谓的极端复杂场景,所以,使用Redis锁也是一个选择
  4. zk的设计就是强一致性,如果获取不到锁,就添加一个监听,不用一直轮询,但是zk也有其缺点,如果有较多的客户端频繁的申请加锁解锁,对zk集群的压力比较大

https://www.csdn.net/tags/MtTaMg0sNDc4OTcxLWJsb2cO0O0O.html



4、BASE理论



4.1、介绍:

BASE是三个单词的缩写:

  • Basically Available(基本可用)
  • Soft state(软状态)
  • Eventually consistent(最终一致性)


    我们解决分布式事务,就是根据上述理论来实现。



4.2、例子:

下单减库存和扣款为例:

  • 订单服务、库存服务、用户服务及他们对应的数据库就是分布式应用中的三个部分。
  • CP:现在如果要满足事务的强一致性,就必须在订单服务数据库锁定的同时,对库存服务、用户服务数据资源同时锁定。等待三个服务业务全部处理完成,才可以释放资源。此时如果有其他请求想要操作被锁定的资源就会被阻塞,这样就是满足了CP。这就是强一致,弱可用
  • AP:三个服务的对应数据库各自独立执行自己的业务,执行本地事务,不要求互相锁定资源。但是这个中间状态下,我们去访问数据库,可能遇到数据不一致的情况,不过我们需要做一些后补措施,保证在经过一段时间后,数据最终满足一致性。这就是高可用,但弱一致(最终一致)。



4.3、总结:

由上面的两种思想,延伸出了很多的分布式事务解决方案:

  • XA
  • TCC
  • 可靠消息最终一致
  • AT



版权声明:本文为ADCQprogrammer原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。