分布式概念基础

一、CAP理论

(C)数据一致性:写操作成功,所有读都能成功;写操作失败,所有读都不能成功;

(A)服务可用:所有读写请求在一定时间内得到响应,可终止,不会一直等待;

(P)分区容错性:网络分区的情况下,被分隔的节点依然能正常对外服务;

单体应用下,CA原则是完全没问题的(不存在P);但是在分布式下架构下只能保证CP或者AP。

二、Base理论

CAP理论的一种折衷,由于在分布式架构下CAP只能二选其一,所以Base理论降低了发生分区容错时对可用性和一致性的要求;

  1. 基本可用:允许可用性降低(可能延长响应时间、可能进行服务降级)
  2. 软状态:允许系统中的数据存在中间状态,并且认为中间状态不会影响系统整体的可用性;
  3. 最终一致性:节点数据同步可以存在延时,但在一定期限后必须达成数据一致性,状态变为最终态;

三、数据一致性模型

  • 强一致性:用户上一次写了什么,下一次就能保证读到什么;
  • 弱一致性:系统写入数据不承诺立即读到最新写入,也不承诺多久后可以读到;
  • 最终一致性:弱一致性的特例,所有数据副本在经过一段时间的同步后最终都能达到一致;
  • 因果一致性:要求所有因果关系的操作顺序得到保证,非因果关系的操作顺序无所谓;
  • 会话一致性:对系统数据的访问过程框定在一个会话中,约定系统能保证在同一个有效会话中实现读已之所写的一致性;

四、Quorum机制

定义

10个副本,一次成功更新3个,那么至少需要读取8个副本的数据,可以保证读到了最新的数据。无法保证强一致性,也就无法实现任何时刻任何用户或节点都可以读到最近一次成功提交的副本数据。需要配合一个获取最新成功提交的版本号metadata服务,这样可以确定最新已经成功提交的版本号,然后从已经读到的数据中可以确认最新写入的数据;

至少读取副本节点数 = 总副本节点数 - 一次成功更新副本数 + 1

例如上面的例子:

8 = 10 - 3 + 1

五、WARO(Write All Read One)机制

定义

一种简单的副本控制协议。写操作时、只有当所有副本都更新成功后,本次写操作才算成功;否则视为失败;

优先保证读、任何节点读到的数据都是最新数据,牺牲了更新服务的可用性。

只要有一个副本宕机了,写服务就不会成功,但只要有一个节点存活,仍能提供读写服务

六、负载均衡策略

1. 轮询法

将请求按顺序轮流分配到后端服务上,均衡地等待后端的每台服务器,而不关心服务器的实际连接数和当前的系统负载;

2. 加权轮询法

不同的后端服务器可能的配置与当前系统的负载均衡并不相同,因此它们的抗压能力也不相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请求;反之给配置低,负载高的机器配置更低的权重,降低系统负载;

3. 随机法

借助于随机算法,根据后端服务器的列表大小值随机选取其中一台服务器进行访问,随着客户端请求次数的增多,实际效果会越来越接近于平均分配调用到后端的每台服务器;

4. 加权随机法

类似于加权轮询法,也是根据后端机器的配置,系统负载分配不同的权重,不同的是权重值随机请求后端服务器,而非顺序;

5. 源地址哈希法

根据获取客户端的IP地址,借助哈希算法计算除一个数值,用数值对服务器列表的大小进行取模运算,得到的结果是客户端要访问服务器的序号

采用源地址哈希法进行负载均衡,同一IP地址的客户端,当后端服务器列表不变时,每次都会映射到同一台后端服务器进行访问

6. 最小连接数法

根据后端服务的当前连接情况,动态选取其中当前积压连接数最小的一台服务器来作为处理当前的请求,尽可能地提高后端服务的利用效率,将负责合理地分流到每一台服务器;

一句话概括:谁空闲谁去处理

七、分布式系统设计

  • 可扩展:通过对服务、存储的扩展,提高系统的处理能力。通过对多台服务器协同工作,来完成单台服务器无法处理的任务、尤其是高并发或者大数据量的任务;
  • 高可用:单点故障不影响整体,单点故障指的是系统中某个组件一旦失效,会让整个系统瘫痪无法工作;
  • 无状态:无状态的服务才能满足部分机器宕机不影响全部,可以随时进行扩展的需求;
  • 可管理:便于运维,出问题能否及时发现定位
  • 高可靠:同样的请求返回同样的数据,更新能够持久化,数据不丢失;

八、分布式事务的解决方案

  • 基于XA协议:两阶段提交和三阶段提交,需要数据库层面支持;

  • 基于事务补偿机制:TCC(Try-Confirm-Cancel),基于业务层面实现;

    TCC事务模型:也称为两阶段补偿事务。第一阶段Try只预留资源,第二阶段明确告诉服务提供者,这个资源你到底要不要,对应第二阶段的confirm / cancel。

    直白一点就是:你要这个资源,我先帮你留着,然后要的话我就给你,不要我就扔掉了;

  • 本地消息表:基于本地数据库 + MQ,维护本地表状态(进行中),通过MQ调用服务,完成响应后回一条消息回调;将状态更改为完成。需要配合定时任务扫表,重新发送消息调用服务,保证幂等性;

    消息幂等:当出现消费者对某条消息重复消费的情况时,重复消费的结果与消费一次的结果是相同的,并且多次消费并未对业务系统产生任何负面影响

    MQ系统内部必须生成一个inner-msg-id,作为去重和幂等的依赖,并且ID是全局唯一且与业务无关,对消息发送方和接收方都屏蔽

  • 基于事务消息:例如MQ服务;

九、讲讲TCC事务模型

TCC补偿事务:Try、Confirm、Cancel

针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作;

  • Try:操作业务检查以及资源预留;
  • Confirm:业务确认操作;
  • Cancel:实现一个与Try相反的操作(即回滚操作)

TCC模型对业务的侵入行较强,改造难度较大,每个操作都需要TCC操作;

TCC会增加事务日志,如果Confirm或者Cancel阶段出错,则会进行重试,所以这两个截断需要支持幂等;如果充实失败,则需要人工介入进行恢复和处理;

十、如何理解RPC

远程过程调用(Remote Process Callable)

RPC要求在调用方中放置被调用的方法接口,调用方只需要调用了这些接口,就相当于调用了被调用方的实际方法,十分易用。于是调用方可以像调用内部接口一样调用远程方法,而不是封装参数名和参数值等操作;

包含:

  • 动态代理,封装调用细节;
  • 序列化与翻序列化,数据传输与接收;
  • 通信,可以选择七层http协议,四层tcp/udp协议;
  • 异常处理机制

首先,调用方调用的是接口,必须为接口构造一个假的实现,因此需要使用动态代理。这样,调用方的调用就被动态代理接收了。

其次,动态代理接收到调用后,应该想办法调用远程的实际实现,包括下面几步:

  • 识别具体要调用的远程方法IP、端口;
  • 将调用方法的入参进行序列化;
  • 通过通信将请求发送到远程方法中;

这样,远程的服务就接收到了调用方法的请求,应该:

  • 反序列化各个调用参数
  • 定位到实际要调用的方法,然后输入参数,执行方法;
  • 按照调用的路径返回调用的结果;

十一、zookeeper分布式锁实现原理


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!