分布式之基础理论

分布式系统

何为分布式系统,曾经被这个问题困惑很久,还好看到一句话适时地 解答了我的疑惑:分布式系统是一个硬件或软件组件分布在不同的网络 计算机上,bici之间仅仅通过消息传递进行通信和协调的系统。

分布式系统通常存在的三种问题:

  • 通信异常:单机内存访问的延时通常在10ns左右,而正常一次网络 通信的延迟在0.1~1ms左右,差距达到百千倍,所以消息丢失和消息延迟 变的非常普遍。

  • 三态:分布式系统的每一次请求与响应,存在特有的“三态”概念, 即:成功、失败与超时。这个现象和第一条中的通信异常有很大关系, 通常有以下两种情况:

      1. 在发送过程中发生了消息丢失现象
    
      2. 请求被成功处理后,但是将响应反馈给发送方的过程中出现了消息丢失现象
    

    发生以上两种情况时,发起方是无法确定当前请求是否被成功处理的。

  • 节点故障:即服务器出现宕机或者“僵死”现象。

分布式事务

当系统从集中式向分布式系统架构变迁的过程中会碰到分布式系统事物 处理与数据一致性上遇到的种种挑战。说起事物,狭义上特指数据库 事务,就不得不提起ACID。

  • Atomicity(原子性):事务中包含的各项操作在一次执行过程中,只允许 出现以下两种状态之一:全部成功执行或者全部不执行。
  • Consistency(一致性):一个事务在执行之前和执行之后数据库必须处于 一致性状态。也就是说事务执行的结果只能使数据库从一个一致性状态 转变到另一个一致性状态。
  • Isolation (隔离性):并发环境中,事务之间是相互隔离的,一个事务 不能被其他事务干扰。
  • Durability(持久性):一个事务一旦提交,它对数据库中对应数据的状态 变更应该是永久性的,即使是发生崩溃或是宕机,也能恢复到正确状态。

分布式事务即是事务在分布式计算领域的应用,在分布式系统环境中 对数据进行分布式的事务处理具有非常大的挑战。当我们在系统的可用性和 一致性之间权衡不定时,两个理论给了我们很好地指导:

  • CAP理论: 一个系统不可能同时满足一致性(Consistency)、可用性 (Avalability)和分区容错性(P:Partition tolerance)这三个基本需求, 最多只能同时满足其中两项。
  • BASE理论:基本可用(Basically Available,分布式系统在出现不可 预知故障的时候,允许损失部分可用性-响应时间和功能),弱状态( Soft state,允许系统中的数据出现中间状态,允许系统在不同节点的 数据副本之间进行数据同步的过程存在延时),最终一致性(Eventually consistent,最终一致性强调的是系统中所有的数据副本,在经过一段时间 的同步后,最终能达到一个一致的状态)。

BASE理论实际上是对CAP中一致性和可用性权衡的结果。所以大多数分布式 系统都是基于CP或者AP的。

一致性协议

为了解决分布式一致性问题,有几个经典的一致性协议和算法,比如 二阶段提交、三阶段提交和Paxos算法等,我们下面就来分析一下二阶 段提交。

  • 二阶段提交 目前绝大部分关系型数据库都是采用二阶段提交协议来完成分布式数 据处理的,它能够用来保证分布式系统数据的一致性。

    阶段一:提交事务请求

     1. 事务询问:协调者向所有的参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各参与者的响应。
     2. 执行事务:各参与节点执行事务操作,并Undo和Redo日志。
     3. 各参与者向协调者反馈事务询问的响应:如果参与者成功执行了事务操作,反馈协调者Yes,如果失败,反馈No。
    

    通常阶段一也被称为投票阶段,即各参与者投票表明是否要继续 执行接下去的事务提交操作。

    阶段二:执行事务提交

     1. 发送提交请求:协调者向所有参与节点发出Commit请求。
     2. 事务提交:执行commit,并释放事务资源。
     3. 反馈事务提交结果:事务提交后,向协调者发送ACK消息。
     4. 完成事务:协调者接收到所有的ack后,完成事务。
    

    中断事务:如果任何一个消费者向协调者反馈了No响应,或者在 等待超时之后,协调者无法接收到所有参与者的反馈响应,就会中断事务。

     1. 发送回滚请求:协调者向所有参与者节点发出Rollback请求。
     2. 事务回滚:参与者收到RollBack请求后,利用Undo信息来执行事务回滚操作,并释放资源。
     3. 反馈事务回滚结果:参与者在完成事务回滚之后,向协调者发送ack消息。
     4. 中断事务:协调者收到所有反馈消息后,完成事务中断。
    

    二阶段提交原理很简单,但是有很多缺点:

     1. 同步阻塞:二阶段提交最大的问题,极大地限制了系统性能。各个参与者在等待其他参与者响应过程中,无法进行其他任何操作。
     2. 单点问题:如果协调者出现问题,整个流程将无法完成,更为严重的是如果协调者在阶段二出现问题,那么其他参与者将会一直处于锁定事务资源的状态中,无法继续完成事务操作。
     3. 数据不一致:在阶段二中如果只有部分参与者收到了commit请求,将会导致数据不一致现象。
     4. 过于保守:任意一个节点的失败都会导致整个事务的失败。
    
  • 三阶段提交 三阶段提交是对二阶段提交的改进,它形成了canCommit、preCommit和 doCommit三个阶段组成。

    1. canCommit:协调者询问是否提交,这时候回答Yes的参与者进入预备状态。
    2. preCommit:协调者发出事务欲提交命令,参与者执行事务,并反馈结果。此过程中协调者自然会在收到一个No响应或者超时后中断事务,但是参与者也会在等待preCommit命令超时后中断事务。
    3. doCommit:协调者发出执行提交命令。在此阶段中,如果协调者或者网络出现故障,都会导致参与者无法收到doCommit请求或abort请求,这时,参与者都会在等待超时之后,继续执行事务提交。
    

    现在我们来分析一下三阶段提交比起二阶段提交的优势:在二阶段 提交的阶段二如果只有部分参与者收到了commit请求,那些没有收到 commit请求的参与者无法完成事务的更新,而且也无法释放自己的资源, 那么后续的事务也会失败,所以三阶段提交过程中给二阶段添加了超时 选项,没有收到commit的参与者会在超时后直接提交事务。

    三阶段提交降低了参与者的阻塞范围,而且能够在出现单点(协调者) 故障后继续达成数据一致。所以两个协议的显著区别就是三阶段将二阶段 中的阶段一一分为二,并且为参与者添加了两次超时选择,保证系统在 超时之后达到确定状态。

事务与并发

事务必须具备ACID的特性,才能称之为事务。为了简单起见,我们即 以数据库事务为例来说明吧。事务的原子性要求如果一个操作失败,则 撤销所有操作,这可以通过日志来解决,如果碰上并发,问题就变得 很棘手了。多个事务并发会出现以下问题:

1.第一类丢失更新
2.脏读
3.虚读(幻象读)
4.不可重复读

数据库系统提供了四种隔离级别来控制事务的并发。由于关于数据库 的事务并发稍显复杂,这里就不具体展开了,主要分清楚事务的特征ACID, 事务并发会带来的问题,数据库是如何解决的就可以了。

未完待续



Previous     Next
zhing /
Published under (CC) BY-NC-SA in categories 分布式  tagged with 分布式