在正式介绍分布式锁之前,我们有必要再回顾下分布式系统和CAP定理,知己知彼才能知道为什么会出现分布式锁的概念。

话不多说,直接进入本篇文章的主题。

一、分布式与集群的区别

分布式系统并非是一蹴而成的,而是经过几个阶段演化而来。

1、单机

单机就是将一个系统部署在一台服务器上,所有请求都由这台服务器处理。

【分布式】01-分布式系统和CAP理论_BASE理论


很明显,当业务增长过快时,一台服务器根本无法满足业务需求,同时单体应用也很复杂无法满足需求开发,一旦机器故障整个应用就是不可用。

2、集群

当一台机器不够支撑业务的发展时,比如QPS过大,这个时候我们就会想到扩容,同一个服务部署在多态机器上,对外提供服务。这样处理能力就会提升N倍(非直线关系)。这就是集群,集群是单机的多实例。

【分布式】01-分布式系统和CAP理论_分布式系统_02


缺点:业务耦合严重,非核心业务可能会影响核心业务;造成资源浪费;不利于拓展。

3、分布式

虽然集群能够分担一点业务请求压力,但是试想下如果一个淘宝的所有系统(订单、物流、支付、营销、风控等)都在一个应用里,估计应用会大到爆炸;同时即使有1000个机器的集群也不一定能够撑得住业务压力。这个时候就想到服务拆分,将整个应用拆分成订单、物流、支付、营销等应用,不同应用之间通过RPC或HTTP进行通信。同时为了保证服务可用性,每个拆分后的应用可以做成集群模式。

分布式系统就是由独立的服务器通过网络松散耦合组成。在这个系统中每个服务器都是一台独立的主机,服务器之间通过内部网络连接。

【分布式】01-分布式系统和CAP理论_数据_03

二、拜占庭将军问题

在讲分布式系统之前需要提一下”拜占庭将军问题“。

拜占庭将军问题实际只是一个虚构的历史故事,用来解释在分布式系统中网络通信容错的问题。

拜占庭将军问题假设有9名将军共同作战,在决定是要进攻还是撤退的时候,选择投票解决,每位将军选择以后通过信使传给其他将军。正常情况下,假设战况应该撤退,5名将军选择撤退,4名将军选择进攻,那么就会遵循少数服从多数原则,选择撤退;但是假如这5名将军中有2名叛徒,本应该选择撤退但是他们选择了进攻,6进攻 > 3撤退,最后进攻却失败;也有可能2名信使被杀,最后4进攻 > 3撤退,也会失败。

对应实际分布式环境,

  • 正常的将军对应计正常运行的计算机节点;
  • 叛变的将军对应发生故障发送误导信息的计算机节点;
  • 信使被杀对应网络通信故障、信息丢失。

拜占庭将军问题主要是为了解决网络通信中由于网络通信不可控,让多个计算机达成一致性协议的问题。

三、分布式系统

《分布式系统概念与设计》一书中,对分布式系统做了如下的定义:

分布式系统是一个硬件或软件组织分布在不同的网络计算机之上,彼此之间仅通过消息传递进行通信和协调的系统。

简单来说,一个典型的分布式系统是由一系列在空间上任意分布的多个进程组成。

这些进程部署的机器可以是在同一台上,也可以是不同机器、不同机房的机器、甚至是不同城市的机器之上。不同机器上部署的服务通过网络进行通信。

分布式系统具有如下特征:

  • 分布性:分布式系统中机器分布情况可以随时变动,比如服务A可以部署在城市B的机器1上,也可以立刻变成部署在城市C的机器1上;
  • 对等性:分布式系统之中的计算机没有主从之分,所有节点都是对等的。但是会提供副本(Replica)的概念,如来保证数据数据不丢失和服务可用。
  • 数据副本是指在不同节点上持久化同一份数据,当某一个节点数据丢失时可以从副本数据节点上获取该数据,这也是解决分布式系统数据丢失问题的有效解决手段。
  • 服务副本是指多个节点提供同样的服务,这样当一个节点发生故障时,副本节点仍然可以提供服务处理请求。
  • 并发性:同一个分布式系统中多个节点可能会并发操作一些共享资源,如数据库或分布式存储,带来的常见问题有数据一致性或并发更新等。在设计分布式系统的时候需要考虑这些因素;
  • 缺乏全局时钟:分布式系统中缺乏一个全局时钟来控制分布式系统的时钟和事件顺序;
  • 故障总是会发生:分布式系统中任何节点都有可能发生故障。在设计分布式系统中要考虑这些异常情况。

分布式系统存在的问题

  • 消息丢失和延迟:分布式系统各个节点之间通过网络通信,由于网络存在光纤、路由器、DNS硬件设备故障的问题导致通信失败,可能会造成消息丢失;此外网络通信存在延迟(1ms甚至更多),因此存在消息延迟的问题。我们的微服务RPC调用过程中出现的超时异常就是由于通信延迟造成的。
  • 网络分区:网络分区,简单的理解就是一个服务在分布式系统中有多个节点,这些节点之间互相通信(同步数据)同时共同对外提供服务(比如请求A在会被服务1处理,请求B会被服务2处理)。当其中几个节点出现异常(可能宕机,也可能网络延时而无法通信),正常的节点与这几个节点就失去了通信,只有正常的节点之间可以通信,这就是网络分区。
    而为了保证系统可用,即分区容错性,通常来说正常的几个节点仍然可以正常处理请求;但是这时可能出现的问题是:异常节点可能仍然可以处理请求(注意,只是无法与正常节点通信,异常节点不一定是宕机),这样就可能出现正常节点与异常节点在处理数据时出现数据不一致的情况。
    举个例子:假设有五个节点:n1~n5 ,出现网络分区被分成两组:[n1n2]和[n3n5]。
    为了保持P(分区容错),请求到来时n1处理请求。
    如果为了保证C(一致性),n1需要将处理的结果同步到 n2 和[n3 ~ n5],由于网络分区n13-n5无法同步到该数据,所以只能返回失败(此时系统就处于不可用状态);
    如果为了保证A(可用性), n1只需要将处理的结果同步到 n2 。那么n3-n5在处理同样的请求时数据就有可能不一致。
  • 三态:分布式系统存在"三态"概念:成功、失败、超时。成功、失败很好理解,超时是由于网络不可能导致的。通常有两种情况:
  • 发送方发出的响应在发送过程中出现消息丢失,未被成功发送至接收方;
  • 接收方成功接收消息,但是并未将响应成功返回给发送方,发生消息丢失。

四、CAP定理

谈到分布式系统,就不可避免地讲到CAP定理。

2000年7月,Eric Brewer教授提出了著名的CAP猜想,后续被证明并被称为CAP定理。

1、CAP定理:

分布式系统不能同时满足一致性(C:Consistency)、可用性(A:Availability)和分区容错性(P:Partition tolerance)。

最多只能满足其中两项。

实际分布式场景中,只能满足AP或CP。

【分布式】01-分布式系统和CAP理论_CAP_04

  • 一致性(C:Consistency):分布式系统中,一致性是指数据在多个副本节点之间保持一致。客户端无论访问哪个节点,读到的都是同一份最新写入的数据,否则读取失败(强一致性)。一致性保证数据正确。
    举个例子:用户1购买1件商品,商品数量减1(假设减1后商品数变为0),商品数-1操作在节点1上;如果没有保持一致性(商品数变为0未从1节点同步到2节点上),此时用户2在2节点上查看商品时发现商品数量仍然为1,点击购买,这样就发生超卖的现象。在电商或者金融场景下,数据强一致性是常见的要求。
  • 可用性(A:Availability):客户端访问任意一个非故障节点,都能在有限时间内正确返回响应。但不保证每个节点的数据是同一份最新数据。可用性保证服务可用,但是不保证数据正确。
    还是上面的例子,商品数减1之后,两个用户请求到达不同节点看到的商品数量可能不一致,但是能返回商品数量的响应数据。
  • 分区容错性(P:Partition tolerance):是指分布式系统在遇到网络分区(节点之间网络故障失去通信无法同步数据)的情况时,仍然需要对外提供正常的服务。强调集群对分区故障的容错能力。 分区容错性是分布式系统最基本的要求,否则也就没有必要使用分布式系统。
    举个例子:数据库主节点1和从节点2、3、4部署在不同城市或机房保证服务可用性,之间通过网络通信来同步数据保证数据一致性。当发生网络分区时,假设数据库节点3、4发生失去响应,变为[1,2] 和 [3, 4] 两个分区,那么[1,2]仍然需要正常对外提供服务。

2、CP or AP?

在分布式系统中,CAP定理的三者只能满足两者:CP或AP。

以数据库同步更新的场景来分析,用户请求通过机房1的数据访问层更新到MySQL主库,通过网络将该数据同步到机房2的MySQL从库。如下图所示:

【分布式】01-分布式系统和CAP理论_分布式系统_05


​ (图片来源:https://mp.weixin.qq.com/s/dnNUmlHR7-sjzjMYXID_Cw)

在此场景下,CAP对应定义为:

C:机房1的MySQL数据库主节点发生数据更新,机房2的MySQL数据库从节点也要更新,保证两个数据库同一份数据保持 一致;

A:同一时刻,两个请求到达MySQL数据库的主从节点上,都能正常的更新、查询;

P:当机房1和2出现网络分区,无法进行网络通信来同步数据,整体系统必须可用。

那么如果为了保证A,那么就可能出现同一时刻访问MySQL主从节点的同一份数据结果不一致,即保证A无法保证C;

如果因为消息丢失、延迟高发生网络分区,为了保证C不破坏一致性,节点可能无法响应最新数据最后返回出错响应;

如何选择呢?

注意:只有在产生网络分区的情况时,我们才需要去选择CP或AP。系统正常运行的时候C和A是可以同时存在的。

当读到旧数据会影响系统运行或业务运行(比如下单不同用户查看同一件商品如果数量不一致),就选择CP;否则可以选择AP。

五、BASE理论

CAP定理中可以看出,在分布式系统中无法同时满足3者,只能从CP或AP中进行取舍和平衡。因此诞生了BASE理论。

BASE是基本可用(Basically Available)、软状态(Soft state)和最终一致性(Eventually consistent)。

BASE理论的核心就是基本可用和最终一致性。

BASE理论是CAP理论中AP的延伸,强调可用性,这个理论很重要,现在互联网后台分布式系统中都有BASE理论的支持。

(1)基本可用(Basically Available)

基本可用是指系统在出现不可预知的故障时(如节点故障、突发流量导致系统过载等),允许通过服务降级,牺牲部分非核心功能的可用性来保证系统核心功能的可用性。

实现基本可用的常见手段有:

  • 流量削峰:将访问请求错开,削弱请求峰值,如淘宝双11前的预售,可以减弱双11当晚的大量请求访问;
  • 延迟响应:当系统流量过大时,采用延迟队列处理请求,通过牺牲接口的响应时间保障核心 功能使用;
  • 体验降级:如微博流量过大时可以采取降低图片、视频清晰度等方法提升系统处理能力;
  • 过载保护:系统请求量过大时,将请求放在指定队列中处理。如果请求等待时间过长或者队列过大,都可以采取直接拒绝的方式避免系统过载。

(2)软状态(Soft state)

软状态是指数据存在中间状态,即允许不同节点在数据副本之间同步时存在延迟的过程,

(3) 最终一致性(Eventually consistent)

最终 一致性是指系统中所有数据副本经过一段时间同步后,最终能够达到一致。最终一致性强调的是 经过短暂的延迟后数据达到一致。而CAP中的一致性是强一致性,是指任意时刻数据都是一致的。强一致性是最终一致性的特例。


参考:
​​​基于CAP模型设计企业级真正高可用的分布式锁​​ 《从Paxos到Zookeeper 分布式一致性原理与实战》