跳转至

分布式架构

1 分布式系统概述

1.1 分布式请求三态

一个请求执行的结果有三种状态:“成功”、“失败”、“超时(未知)”,称之为分布式系统的三态。

1.2 衡量分布式系统的指标

  1. 性能:常见的性能指标有:吞吐能力响应延迟并发能力,三个性能指标往往会相互制约,追求高吞吐的系统,往往很难做到低延迟;系统平均响应时间较长时,也很难提高 QPS。
    1. 系统的吞吐能力,指系统在某 一时间可以处理的数据总量,通常可以用系统每秒处理的总的数据量来衡量;
    2. 系统的响应延迟,指系统完成某一功能需要使用的时间;
    3. 系统的并发能力,指系统可以同时完成某一功能的能力,通常 也用 QPS(query per second)来衡量。
  2. 可用性:系统的可用性(availability)指系统在面对各种异常时可以正确提供服务的能力。系统的可用性可以用系统停服务的时间与正常服务的时间的比例来衡量,也可以用某功能的失败次数与成功次数的比例来衡量。可用性是分布式的重要指标,衡量了系统的鲁棒性,是系统容错能力的体现。
  3. 可扩展性:系统的可扩展性(scalability)指分布式系统通过扩展集群机器规模提高系统性能(吞吐、延迟、并发)、存储容量、计算能力的特性。可扩展性是分布式系统的特有性质。
  4. 一致性:分布式系统为了提高可用性,总是不可避免的使用副本的机制,从而引发副本一致性的问题。根据具体的业务需求的不同,分布式系统总是提供某种一致性模型,并基于此模型提供具体的服务。

2 ACID理论

  • A:Atomicity(原子性),一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复到事务开始前的状态,就像这个事务从来没有执行过一样。
  • C:Consistency(一致性),在事务开始之前和事务结束以后,数据库的完整性没有被破坏。完整性包括外键约束、应用定义的等约束不会被破坏。
  • I:Isolation(隔离性),数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。
  • D:Durability(持久性),事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

3 CAP理论

title: CAP只能同时满足其中2点
CAP原理证明,任何分布式系统只可同时满足以上两点,无法三者兼顾。由于关系型数据库是单节点无复制的,因此不具有分区容忍性,但是具有一致性和可用性,而分布式的服务化系统都需要满足分区容忍性,那么我们必须在一致性和可用性之间进行权衡。如果在网络上有消息丢失,也就是出现了网络分区,则复制操作可能会被延后,如果这时我们的使用方等待复制完成再返回,则可能导致在有限时间内无法返回,就失去了可用性:而如果使用方不等待复制完成,而在主分片写完后直接返回,则具有了可用性,但是失去了一致性。
  • C:Consistency(一致性),在分布式系统中的所有数据,在同一时刻具有同样的值;所有节点在同一时刻读取的数据都是最新的数据副本。
  • A:Availability(可用性),完全的可用性指的是在任何故障模型下,服务都会在有限的时间内处理完成并进行响应。
  • P:Partition tolerance(分区容错性),尽管网络上有部分消息丢失,但系统仍然可继续工作。

4 BASE理论

1. BASE思想解决了CAP提出的分布式系统的一致性和可用性不可兼得的问题。
2. BASE思想与ACID原理截然不同,它满足CAP原理,通过牺牲强一致性获得可用性,一般应用于服务化系统的应用层或者大数据处理系统中,通过达到最终一致性来尽量满足业务的绝大多数需求。
3. 软状态是实现BASE思想的方法,基本可用和最终一致是目标。以BASE思想实现的系统由于不保证强一致性,所以系统在处理请求的过程中可以存在短暂的不一致,在短暂的不一致的时间窗口内,请求处理处于临时状态中,系统在进行每步操作时,通过记录每个临时状态,在系统出现故障时可以从这些中间状态继续处理未完成的请求或者退回到原始状态,最终达到一致状态。
  • B:Basiclly Available(基本可用):
  • S:Soft state(软状态),状态可以在一段时间内不同步。
  • E:Eventually consistent(最终一致性):在一定的时间窗口内,最终数据达成一致即可。

5 一致性

  • 一致性:多个副本间数据是否相同
  • 强一致性:更新后任何时间读数据是最新数据
    • 模型:
    • Paxos
    • Raft(muti-paxos)
    • ZAB(muti-paxos)
  • 弱一致性:更新后允许在一定时间内读取的数据不是最新数据
    • 模型:
    • Gossi
    • DNS系统
  • 一致性算法:参考
  • 参考

5.1 一致性算法Paxos

6 数据分布方式

通常数据会按一定的大小进行分段(数据段有很多不同的称谓, segment, fragment, chunk, partition 等等)切分,以提升数据处理性能,同样从副本数据中恢复数据也能更好的发挥所有集群中节点处理能力。

将一个单机问题使用分布式解决,首先要解决的就是如何将问题拆解为可以使用多机分布式解决,使得分布式系统中的每台机器负责原问题的一个子集。由于无论是计算还是存储,其问题输入对象都是数据,所以如何拆解分布式系统的输入数据成为分布式系统的基本问题,这样的数据拆解为数据分布方式。 常用的数据分布方式有: 1. 哈希 2. 一致性哈希(哈希环、虚拟节点) 3. 按数据范围分 4. 按数据量分

7 副本协议

7.1 中心化副本控制协议

中心化副本控制协议:基本思路是由一个中心节点协调副本数据的更新、维护副本之间的一致性。 - 优势: - 协议相对较为简单, 所有的副本相关的控制交由中心节点完成。 - 并发控制将由中心节点完成,从而使得一个分布式并发控制问题,简化为一个单机并发控制问题。(所谓并发控制,即多个节点同时需要修改副本数据时,需要解决“写写”、“读写”等并发冲突。单机系统上常用加锁等方式进行并发控制。对于分布式并发控制,加锁也是一个常用的方法,但如果没有中心节点统一进行锁管理,就需要完全分布式化的锁系统。 - 劣势: - 系统的可用性依赖于中心化节点,当中心节点异常或与中心节点通信中断时,系统将失去某些服务(通常至少失去更新服务) - 中心化副本控制协议结构体如下

7.2 去中心化副本控制协议

去中心化副本控制协议:没有中心节点,协议中所有的节点都是完全对等的, 节点之间通过平等协商达到一致。 从而去中心化协议没有因为中心化节点异常而带来的停服务等问题。 - 优势: - 相比中心化协议,不受中心化节点的异常而服务停止问题。 - 劣势: - 协议过程通常比较复杂 - 由于流程的复杂,去中心化协议的效率或者性能一般也较中心化协议 - 去中心化副本控制协议结构图

7.3 primary-secondary 协议

primary-secondary 协议:副本被分为两大类,其中有且仅有一个副本作为 primary 副本,除 primary 以外的副本都作为 secondary 副本。维护 primary 副本的节点作为中心节点,中心节点负责维护数据的更新、并发控制、协调副本的一致性。 - primary-secondary 协议结构体如下

8 负载均衡

为了实现系统的高性能、高并发、高可用,在构架中都会进行负载均衡设计,它是分布式系统的核心和中枢,负载均衡的好坏直接影响着整个系统的性能。负载均衡分为软件均衡和硬件均衡两类,比如apache、nginx、dubbo 等属于软件负载均衡,F5属于硬件负载均衡,当然他们都会使用到负载均衡算法。 常见的负载均衡算法包含: 1. 轮询法(Round Robin) 2. 加权轮询法(Weight Round Robin) 3. 随机法(Random) 4. 加权随机法(Weight Random) 5. 平滑加权轮询法(Smooth Weight Round Robin) 6. 源地址哈希法(Hash) 7. 最小连接数法(Least Connections)

9 分布式ID

10 分布式锁

11 分布式事务

  • 参考 事务具有 4 个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为 ACID 特性。

11.1 事务隔离级别

title: 不可重复读和幻读到底有什么区别呢?
(1) 不可重复读是读取了其他事务更改的数据,**针对update操作**
解决:使用行级锁,锁定该行,事务A多次读取操作完成后才释放该锁,这个时候才允许其他事务更改刚才的数据。

(2) 幻读是读取了其他事务新增的数据,**针对insert和delete操作**
解决:使用表级锁,锁定整张表,事务A多次读取数据总量之后才释放该锁,这个时候才允许其他事务新增数据。
这时候再理解事务隔离级别就简单多了呢。
  • 脏读(dirty read,DR):读取未提交数据;事务T1修改一个数据,事务T2在T1提交或者回滚之前读取到了这个数据。如果T1执行了回滚,那么T2就读取到了一个不存在的值。
  • 不可重复读(non-repeatable read,NRR):前后多次读取,数据内容不一致;事务T1读取一个数据,然后事务T2修改或者删除这个数据并提交。接下来,如果T1试图再次读取这个数据,那么它会读取到一个修改过的值,或者发现这个数据已经被删除了
  • 幻读(phantom read,PR):前后多次读取,数据总量不一致;务T1读取一组满足某一查询条件的数据,然后事务T2创建一组满足T1查询条件的新数据并提交。如果T1再次按这一查询条件读取,那么它将获得不同于第一次读取的数据。
  • 数据库的隔离级别
    • 读未提交(read uncommitted,RU)
    • 读已提交(read committed,RC)
    • 可重复读(repeatable read,RR)
    • 可串行化(serializable)

11.2 两阶段提交/XA

两阶段提交协议把分布式事务分为两个阶段,一个是准备阶段,另一个是提交阶段。准备阶段和提交阶段都是由事务管理器发起的,为了接下来讲解方便,我们将事务管理器称为协调者,将资源管理器称为参与者。
  • 准备阶段:协调者向参与者发起指令,参与者评估自己的状态,如果参与者评估指令可以完成,则会写redo或者undo日志(Write-Ahead Log的一种),然后锁定资源,执行操作,但是并不提交。
  • 提交阶段:如果每个参与者明确返回准备成功,也就是预留资源和执行操作成功,则协调者向参与者发起提交指令,参与者提交资源变更的事务,释放锁定的资源;如果任何一个参与者明确返回准备失败,也就是预留资源或者执行操作失败,则协调者向参与者发起中止指令,参与者取消已经变更的事务,执行undo日志,释放锁定的资源。
  • 阻塞:从上面的描述来看,对于任何一次指令都必须收到明确的响应,才会继续进行下一步,否则处于阻塞状态,占用的资源被一直锁定,不会被释放。
  • 单点故障:如果协调者宕机,参与者没有协调者指挥,则会一直阻塞,尽管可以通过选举新的协调者替代原有协调者,但是如果协调者在发送一个提交指令后宕机,而提交指令仅仅被一个参与者接收,并且参与者接收后也宕机,则新上任的协调者无法处理这种情况。
  • 脑裂:协调者发送提交指令,有的参与者接收到并执行了事务,有的参与者没有接收到事务就没有执行事务,多个参与者之间是不一致的。
  • 两阶段提交图示如下:

11.3 三阶段提交

三阶段提交协议是两阶段提交协议的改进版本。它通过超时机制解决了阻塞的问题,并且把两个阶段增加为以下三个阶段(增加了询问阶段,准备阶段、提交阶段基本和两阶段提交一致)。
title:三阶段提交相比两阶段提交优势
1. 增加了一个询问阶段,询问阶段可以确保尽可能早地发现无法执行操作而需要中止的行为,但是它并不能发现所有这种行为,只会减少这种情况的发生。
2. 在准备阶段以后,协调者和参与者执行的任务中都增加了超时,一旦超时,则协调者和参与者都会继续提交事务,默认为成功,这也是根据概率统计超时后默认为成功的正确性最大。
  • 询问阶段:协调者询问参与者是否可以完成指令,协调者只需要回答是或不是,而不需要做真正的操作,这个阶段超时会导致中止。
  • 准备阶段:如果在询问阶段所有参与者都返回可以执行操作,则协调者向参与者发送预执行请求,然后参与者写redo和undo日志,执行操作但是不提交操作:如果在询问阶段任意参与者返回不能执行操作的结果,则协调者向参与者发送中止请求,这里的逻辑与两阶段提交协议的准备阶段是相似的。
  • 提交阶段:如果每个参与者在准备阶段返回准备成功,也就是说预留资源和执行操作成功,则协调者向参与者发起提交指令,参与者提交资源变更的事务,释放锁定的资源:如果任何参与者返回准备失败,也就是说预留资源或者执行操作失败,则协调者向参与者发起中止指令,参与者取消己经变更的事务,执行undo日志,释放锁定的资源,这里的逻辑与两阶段提交协议的提交阶段一致。
  • 三阶段提交图示如下:

11.4 SAGA

11.5 TCC

两阶段及三阶段方案中都包含多个参与者、多个阶段实现一个事务,实现复杂,性能也是一个很大的问题,因此,在互联网的高并发系统中,鲜有使用两阶段提交和三阶段提交协议的场景。

TCC协议将一个任务拆分成Try、Confirm、Cancel三个步骤,正常的流程会先执行Try,如果执行没有问题,则再执行Confirm,如果执行过程中出了问题,则执行操作的逆操作Cancel。从正常的流程上讲,这仍然是一个两阶段提交协议,但是在执行出现问题时有一定的自我修复能力,如果任何参与者出现了问题,则协调者通过执行操作的逆操作来Cancel之前的操作,达到最终的一致状态。 - 问题:如果遇到极端情况,则TCC会有很多问题,例如,如果在取消时一些参与者收到指令,而另一些参与者没有收到指令,则整个系统仍然是不一致的。对于这种复杂的情况,系统首先会通过补偿的方式尝试自动修复,如果系统无法修复,则必须由人工参与解决。 - TCC图示如下:

12 主从复制