分布式架构

此文来自于:《从Paxos到Zookeeper分布式一致性原理与实践》第一章
集中式->分布式演变基础知识


1. 从集中式到分布式

1.1 集中式的特点

所谓的集中式系统就是指由一台或多台主计算机组成中心节点,数据集中存储于这个中心节点,并且整个系统的所有业务单元都部署在这个中心节点上,
系统的所有功能均由其集中处理。也就是说,在集中式系统中,每个终端或客户端机器仅仅负责数据的录入和输出,而数据的存储与控制处理完全
交由主机来完成。

最大的特点就是部署结构简单。由于集中式系统往往基于底层性能卓越的大型主机,因此无须考虑如何对服务进行多个节点的部署,也就不用考虑多个
节点之间的分布式协作问题。

1.2 分布式的特点

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

一个标准的分布式系统在没有任何特定业务逻辑约束的情况下,都会有如下几个特征:

  • 分布性:分布式系统中的多台计算机在空间上随意分布。
  • 对等性:分布式系统中的计算机没有主/从之分,既没有控制整个系统的主机,也没有被控制的从机,组成分布式系统的所有计算机节点都是对等的。
    副本(Replica)是分布式系统最常见的概念之一,指的是分布式系统对数据和服务提供一种冗余方式。在常见的分布式系统中,为了对外提供高可用的服务,
    我们往往会对数据和服务进行副本处理。不同的节点上持久化同一份数据,当某一个节点上存储的数据丢失时,可以从副本上读取到该数据,另一类副本是
    服务副本,指多个节点提供同样的服务,每个节点都有能力接收来自外部的请求并进行相应的处理。
  • 并发性:同一个分布式系统中的多个节点,可能会并发地操作一些共享的资源,诸如数据库或分布式存储等,如何准确并高效地协调分布式并发操作也成为了分布式
    系统架构与设计中最大的挑战之一。
  • 缺乏全局时钟:一个典型的分布式系统是由一系列在空间上随意分布的多个进程组成的,具有明显的分布性,这些进程之间通过交换下次来进行相互通信。
    因此,在分布式系统中,很难定义两个时间的顺序,原因就是因为分布式系统缺乏一个全局的时钟序列控制。
  • 故障总是会发生:组成分布式系统的所有计算机,都有可能发生任何形式的故障。任何在设计阶段考虑到的异常情况,一定会在系统实际运行中发生!

1.3 分布式环境的各种问题

1.3.1 通信异常

分布式引入了网络因素,而由于网络本身的不可靠性,因此每次网络通信都会伴随网络不可用的风险,网络光纤、路由器和DNS等。因此消息丢失和消息延迟变得非常普遍。

1.3.2 网络分区

当网络由于发生异常情况,导致分布式系统中部分节点之间的网络延时不断增大,最终导致组成分布式系统的所有节点中,只有部分节点之间能够正常通信,
而另一些节点则不能——我们将这个现象称为网络分区。网络分区出现时,分布式系统会出现局部小集群,在极端情况下,这些局部小集群会独立完成原本
需要整个分布式系统才能完成的功能,包括对数据的事务处理,这就对分布式一致性提出了非常大的挑战(某个复杂业务原本需要多个机器完成,现在被一个机器
执行)。

1.3.3 三态

分布式系统的每一次请求与响应,存在特有的“三态”概念,即成功、失败与超时。超时的现象,通常有以下两种情况:

  • 由于网络原因,请求并没有被成功地发送到接收方,在发送过程就发生了消息丢失现象。
  • 请求成功的被接收方接收后,并进行了处理,但是在将响应反馈给发送方的过程中,发生了消息丢失现象。(rabitMQ的解决方案是,消费者(接收方)开始处理消息前发送响应A,
    消费者(接收方)处理完成消息后发送响应B,生产者(发送方)必须得到AB两个响应才能确定消息成功被处理了)

2. 从ACID到CAP/BASE

2.1 ACID

事务(Transaction)是由一系列对系统中数据进行访问与更新的操作所组成的一个程序执行逻辑单元(Unit)。

2.1.1 原子性(Atomicity)

要么全部成功执行,要么全部不执行。

2.1.2 一致性(Consistency)

事务的运行被迫中断时,这些未完成的事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于不一致的状态。

2.1.3 隔离性(Isolation)

并发的事务是相互隔离的,一个事务的执行不能被其他事务干扰。SQL规范定义了4个事务隔离级别:

  • 读未提交(Read Uncommitted):A事务更新过程中,从1更新到10,B事务能获取过程中间值,获取到2,3等值。(脏读)
  • 读已提交(Read Committed):A事务更新过程中,从1更新到10,B事务只能获取最终的值10。
  • 可重复读(Repeatable Read):A事务更新过程中,从1更新到10,B事务先获取了1,后来B事务中有个操作重新获取了一次值为10。(幻影读)
  • 串行化(Serializable):事务只能串行执行,不能并发。

2.1.4 持久性(Durability)

事务一旦提交,对数据库对应数据的状态变更就应该被永久保存下来。

2.1 分布式事务

设想一个最典型的分布式事务场景:一个跨银行的转账操作涉及调用两个异地的银行服务,其中一个是本地银行提供的取款服务,另一个则是目标银行提供的存款
服务,这两个服务本身是无状态并且是互相独立的,共同构成了一个完整的分布式事务。如果从本地银行取款成功,但是因为某种原因存款服务失败了,那么
就必须回滚到取款前的状态,否则用户可能会发现自己的钱不翼而飞了。

我们可以看到,一个分布式事务可以看作是由多个分布式的操作序列组成的,例如上面例子中的取款服务和存款服务,通常可以把这一系列分布式的操作序列称为
子事务。因为,分布式事务也可以被定义为一种嵌套型的事务,同时也就具有了ACID事务特性。但由于在分布式事务中,各个子事务的执行时分布式的,
因此要实现一种能够保证ACID特性的分布式事务处理系统就显得格外复杂。

2.3 CAP和BASE理论

ACID是属于单机系统的理论,分布式有属于自己的理论,即CAP和BASE。

2.3.1 CAP定理

一个分布式系统不可能同时满足一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)这三个基本需求,最多只能同时
满足其中的两项。

.1 Consistency

在分布式环境下,数据在多个副本之间是否能够保持一致性,当某个副本执行更新操作后,应该保证系统的数据仍然处于一致的状态。如果做到一个数据项的更新
操作执行成功后,所有的用户都可以读取到最新的值,那么这样的系统就被认为具有强一致性。

.2 Availability

对于用户的每一个操作请求总是能够在有限的时间内返回结果。划重点:有限的时间内、返回结果

  • 有限的时间内:对于用户的一个艹做请求,系统必须能够在指定的时间内返回对应的处理结果,如果超过了这个时间范围,那么系统就被认为是不可用的。
    比如,对于一个在线搜索引擎来说,通常在0.5秒内需要给出用户搜索关键词对应的检索结果,而对于一个面向HIVE的海量数据查询平台来说,正常一次数据
    检索时间可能在20秒,这是正常的,系统必须存在一个合理的响应时间。
  • 返回结果:要求系统在完成堆用户请求的处理后,返回一个正常的结果,而不是返回系统错误。

.3 Partition tolerance

分布式系统在遇到任何网络分区故障的时候(节点间的故障),仍然需要保证对外提供满足一致性和可用性的服务,除非整个网络环境发生了故障。

.4 总结

  • AC:所有的数据都放在一个分布式节点上。(谈什么分布式?)
  • PC:系统正在维修,请等待。(要么可用,要么直接不能访问)
  • AP:放弃数据的强一致性,保留数据额最终一致性。(双11xx商品正在被5126人浏览,可能每个人看到的数字都不一样,但是系统最终会让所有人看到一样的数字)

2.3.2 BASE理论

基于CAP定理结合实际演化而来,即Basically Available(基本可用)、Soft state(软状态)、Eventually consistency(最终一致性)。

.1 Basically Available

分布式在出现不可预知故障的时候,允许损失部分可用性:

  • 响应时间上的损失:搜索正常是0.5秒返回用户,出现故障变成2秒。
  • 功能上的损失:网上购物在双11时选择购买可能会跳转到排队页面。

.2 Soft state

允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。

.3 Eventually consistency

强调数据最终数据能够达到一致,而不需要实时保证系统数据的强一致性。
在实际工程实践中,最终一致性存在以下五类主要变种。

.3.1 因果一致性(Causal consistency)

进程A更新完某个数据项后通知了进程B,那么进程B之后对该数据的访问都应该能够获取到进程A更新后的最新纸,并且如果进程B要对该数据项进行更新操作的话,
务必基于进程A更新后的最新值。而进程C的数据访问则没有这样的限制。

.3.2 读己之所写(Read your writes)

进程A更新了一个数据项,它自己总是能够访问到更新过的最新值。特殊的因果一致性(A进程通知了A进程)。

.3.3 会话一致性(Session consistency)

系统能保证在同一个有效的会话中实现“读己之所写”的一致性,即客户端能够在同一绘画中始终读取到该数据项的最新值。

.3.4 单调读一致性(Monotonic read consistency)

如果一个进程从系统读取出一个数据项的某个值后,那么系统对于该进程后续的任何数据访问都不应该返回更旧的值。

.3.5 单调写一致性(Monotonic write consistency)

系统保证来自同一个进程的写操作被顺序地执行。

.3.6 总结

最终一致性并不是只有那些大型分布式系统才涉及的特性,许多关系型数据库都采用了最终一致性模型,采用同步和异步方式来实现主备数据复制技术。

  • 在同步方式中,数据的复制过程通常是更新事务的一部分,因此在书屋完成后,主备数据库的数据就会达到一致。
  • 在异步方式中,备库的更新往往会存在延时,这取决于事务日志在主备数据库之间传输的时间长达,如果传输时间过长或者甚至在日志传输过程中出现异常导致
    无法及时将事务应用到备库上,那么很显然,从备库读取的数据将是旧的,就出现了数据不一致的情况。

但是,无论采用重试、人为修正,关系型数据库还是能够保证最终数据达到一致性——这就是系统提供最终一致性保证的经典案例。

总的来说,BASE理论面向大型高可用可扩展的分布式系统,和传统事务的ACID特性是相反的,不同于ACID的强一致性模型,而是通过强一致性和高可用性的
平衡,最终达到一致性。因此在具体的分布式系统架构设计过程中,ACID和BASE理论往往会结合一起使用用来面对不同的业务场景的要求。

3. 小结

分布式架构发展过程中的ACID->CAP->BASE等分布式事务与一致性方面的经典理论。

推荐阅读更多精彩内容