分布式理论1 | 青训营笔记

93 阅读10分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第14天

概述

1. 什么是分布式?

    1. 分布式系统定义:跨多个节点的计算机程序的集合
    2. 使用分布式系统的五大优势
      1. 去中心化
      2. 低成本:买更多的性能较低的服务器
      3. 弹性:在线离线弹性处理,自动扩容缩容
      4. 资源共享:将数据集中起来构建一个大的存储池
      5. 可靠性高:使用别的副本代替,增加容错
    3. 分布式系统的挑战
      1. 普遍的节点故障:单个节点发生故障是小概率事件,但是很多的节点每年发生故障的概率是必然事件
      2. 不可靠网络:网络存在未知状态,处理起来比较难
      3. 异构的机器与硬件环境:性能不可预测,与硬件环境有关
      4. 安全

1. Why-How-What

    1. 使用者视角:大规模计算存储的述求
    2. 学习者视角:后端开发必备技能

1. 常见的分布式系统

    1. 分布式存储:
      1. GFS:谷歌的分布式文件系统
      2. Ceph:统一的分布式存储系统
      3. HDFS:基于GFS架构的开源分布式文件系统
      4. Zookeeper:高可用的分布式数据管理与系统协调框架
    2. 分布式数据库:
      1. Spanner:谷歌可拓展的、全球分布式数据库
      2. TiDB:开源分布式关系型数据库
      3. HBase:开源Nosql数据库
      4. MangoDB:文档数据库
    3. 分布式计算:
      1. Hadoop:基于MapReduce分布式计算框架
      2. YARN:分布式资源调度
      3. Spark:在Hadoop基础之上,使用内存来存储数据

系统模型

故障模型

  • 六种故障模型,从处理的难易程度分类
    • Byzantine failure(拜占庭故障):节点可以任意篡改发送给其他节点的数据,是最难处理的故障
    • Authentication detectable byzantine failure (ADB):节点可以篡改本节点数据,但不能伪造其他节点的数据
    • Performance failure:节点未在特定时间段内收到数据,即时间太早或太晚(处理慢了,与其慢了不如死掉)
    • Omission failure:节点收到数据的时间无限晚,即收不到数据
    • Crash failure:节点停止响应,持续性的故障(宕机、进程退出)
    • Fail-stop failure:错误可检测,是最容易处理的故障(错误码明确,既知道状态又知道原因)
  • 故障模型举例,按照模型分类
    • 磁盘、主板、交换机、网络分区、cpu、内存、线缆、电源等故障详细说明 image.png

拜占庭将军问题

- 两将军问题

    • 定义:
      • 两支军队的将军只能派信使穿越敌方领土互相通信,以此约定进攻时间。该问题希望求解如何在两名将军派出的任何信使都可能被俘虏(丢包)的情况下,就进攻时间达成共识
    • 结论:
      • 两将军问题是被证实无解的电脑通信问题,两支军队理论上永远无法达成共识
      • 只是确认次数越多,概率越接近于1
    • TCP是两将军问题的一个工程解
    • 方案一:同时发送N个信使,任何一个到达对方军队都算成功
    • 方案二:设置超时时间,发送后未在一定时间返回,则加派信使(TCP)

- 三将军问题:

    • 两个“忠将”A和B,一个“叛徒”C,互相传递消息,消息可能丢失,也可能被篡改,当有一个将军是“叛徒”(即出现拜占庭故障)时,整个系统无法达成一致。
    • 由于“叛徒”C的存在,将军A和将军B获得不同的信息。这样将军A获得2票进攻1票撤退的信息,将军B获得1票进攻2票撤退的信息,产生了不一致
    • 解法:再加入一个将军D,他只作为消息传递的中枢目标不参与投票,见四将军问题

- 四将军问题:

    • 将军D作为消息分发中枢,约定如果没收到消息则执行撤退
    • 步骤:
      • 如果D为“叛徒”,ABC无论收到任何消息,总能达成一致
      • D为“忠将”,ABC有2人将D的消息进行正确的传递,同样能保证最终决策符合大多数。
    • 进而能够证明,当有3m+1个将军,m个“叛徒”时,可以进行m轮协商,最终达成一致

共识和一致性

最终一致性

  • 不同客户端A和B看到客户端C写入,因为时机的不同,产生数据读取的偏差。引导出最终一致性的详细说明
  • 当C正在写时,AB去读,可能会产生数据的不一致
  • 只有当C写完了,再去读,则之后数据都是一致的了,这就叫做最终一致性 image.png

线性一致性

  • 要保证所有客户端看到相同的值,需要多节点进行“协商”,达成共识,来保证线性一致性
  • 即当一个客户端读到一个新的值时,就应该将其同步给其他客户端,但这样回加重服务器负担,减少可用性
  • 一致性和可用性是对矛盾 image.png

理论基础

CAP理论

  • CAP的定义,分别代表一致性、可用性、分区容错性。三者无法同时达到
    • C:数据在多个副本之间能够保持一致的特性
    • A:系统提供的服务必须一致处于可用的状态,每次请求都能获得非错的响应,但是不保证是最新的数据
    • P:分布式系统在遇到任何网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务,除非整个网络环境都发生了故障
  • CAP诞生了三类系统:
    • CA系统:传统数据库的代表,放弃分区容错性,只考虑单机的强一致性与可用性
    • AP系统:放弃强一致性,保证高可用,不少nosql存储系统采用,eg:注重用户体验的系统
    • CP系统:放弃可用性,保证数据一致性和分区容错性,eg:与钱财相关的系统
  • 举例说明两个分布式进程之间同步数据,当出现故障的时候,如何选择不同的CAP系统,以及带来的影响
    • CP系统:故障发生时,为了避免读到不一致的数据,可能拒绝访问(下右)
    • AP系统:故障发生时,为了保证可用性,允许不同进程读到不同的数据(下左) image.png
  • 针对故障场景,可以通过故障转移的方式,做一个相对较优的解决方式:
    • 允许一个进程作为Master,其他进程作为Backup,当故障时将请求转移给Backup进行处理 image.png

ACID理论

  • ACID理论是针对CA系统而言的,通常在数据库中具有广泛意义
  • 事务是数据库系统中非常重要的概念,它是数据库管理系统执行过程中的一个逻辑单元,它能够保证一个事务中的所有操作要么全部执行,要么全都不执行
  • 数据库事务拥有四个特性ACID
    • 原子性(Atomicity):要么全部成功,要么全部回滚
    • 一致性(Consistency):事务的一致性,事务执行之前和执行之后必须处于一致性状态
    • 隔离性(Isolation):多个并发事务之间要相互隔离,数据库为每一个用户开启的事务不能被其他事务的操作所干扰
    • 持久性(Durability):事务一旦被提交了,那么对数据
  • 数据库一定具有CA特性,但不一定有ID

BASE理论

  • BASE理论是针对AP系统而言的,其来源于对大型互联网分布式实践的总结(游戏系统)
    • Basically Available(基本可用):假设系统,出现了不可预知的故障,但还是能用,优先可用
    • Soft state(软状态):允许系统中的数据存在中间状态,并认为该状态不影响系统的整体可用性
    • Eventually consistent(最终一致性):数据最终一定能够达到一致的状态

分布式事务

二阶段提交

定义:

  • 二阶段提交(Two-phase Commit):为了使基于分布式系统架构下的所有节点在进行事务提交时保持一致性而设计的一种演算法 image.png

三个假设:

  • 协调者和参与者进行通信
  • 预写式日志被保持在可靠的存储设备上
  • 所有节点不会永久性损坏,即使损坏后仍然可以恢复

正常流程:

  • Prepare阶段Commit阶段

异常流程:

  • C不宕机,P宕机:Prepare阶段失败 -> 回滚;因为没有真正commit
  • C宕机,P不宕机:协调者宕机 ->** 重新启用新的协调者**;
  • C宕机,P宕机:双故障重启 -> 数据库管理员介入

两阶段提交需解决的问题:

  • 性能问题:需要多次网络通信,资源需要等待并锁定
  • 新协调者:如何确定状态选出新协调者
  • Commit阶段网络分区带来的数据不一致:非所有节点都收到Commit请求,整个事务进行回滚

两个思考:

  • 日志被保存在「可靠」的存储设备上。如何保证这一点?
    • 通过高可用的硬件保证:单机时代:IOE(EMC存储);
    • 分布式时代:建立分布式文件系统
  • 参与者Commit了,但Ack信息协调者没收到。怎么办?
    • 也是需要回滚整个事务,类似于TCP fin报文没收到,需要重新建立连接

三阶段提交

针对两阶段提交的补充,将两阶段提交中的Prepare阶段,拆成两部分:CanCommit和PreCommit机制

  • CanCommit阶段:询问是否可以执行:避免阻塞与单点故障问题
  • PreCommit阶段:重新确认是否可以执行
  • DoCommit阶段:向所有人提交事务 引入超时机制,在等待超时之后,会继续事务的提交 思考:
  • 三阶段缓和了两阶段面临的问题,但依然没有解决:
    • 性能问题
    • 网络分区引起数据一致性问题

MVCC

MVCC:多版本并发控制的方法。维持一个数据的多个版本使读写操作没有冲突。所以既不会阻塞写,也不阻塞读。提高并发性能的同时也解决了脏读的问题。

悲观锁和乐观锁

  • 悲观锁操作数据时直接把数据锁住,直到操作完成后才会释放锁;上锁期间其他人不能修改数据
  • 乐观锁不会上锁,只是在执行更新时判断别人是否修改数据,只有冲突时才放弃操作 image.png

版本的选取

使用物理时钟或逻辑时钟

  • 物理时钟:提供TrueTime API,有Master节点维持一个绝对时间,保证各个服务器之间时钟误差控制在ϵ内,通常ϵ<7ms。
  • 逻辑时钟:中心化授时的方式--时间戳预言机(TSO),好处是无需硬件的支持,每个事务提交之前都需要先与TSO获取一个时间戳名单时会增加网络通信成本,并需要考虑低延迟,高性能等问题