MIT6.824
  • 简介
  • Lecture 01 - Introduction
    • 1.1 分布式系统的驱动力和挑战(Drivens and Challenges)
    • 1.2 课程结构(Course Structure)
    • 1.3 分布式系统的抽象和实现工具(Abstraction and Implementation)
    • 1.4 可扩展性(Scalability)
    • 1.5 可用性(Availability)
    • 1.6 一致性(Consistency)
    • 1.7 MapReduce基本工作方式
    • 1.8 Map函数和Reduce函数
  • Lecture 03 - GFS
    • 3.1分布式存储系统的难点(Why Hard)
    • 3.2 错误的设计(Bad Design)
    • 3.3 GFS的设计目标
    • 3.4 GFS Master 节点
    • 3.5 GFS读文件(Read File)
    • 3.6 GFS写文件(Write File)(1)
    • 3.7 GFS写文件(Write File)(2)
    • 3.8 GFS的一致性
  • Lecture 04 - VMware FT
    • 4.1 复制(Replication)
    • 4.2 状态转移和复制状态机(State Transfer and Replicated State Machine)
    • 4.3 VMware FT 工作原理
    • 4.4 非确定性事件(Non-Deterministic Events)
    • 4.5 输出控制(Output Rule)
    • 4.6 重复输出(Duplicated Output)
    • 4.7 Test-and-Set 服务
  • Lecture 06 - Raft1
    • 6.1 脑裂(Split Brain)
    • 6.2 过半票决(Majority Vote)
    • 6.3 Raft 初探
    • 6.4 Log 同步时序
    • 6.5 日志(Raft Log)
    • 6.6 应用层接口
    • 6.7 Leader选举(Leader Election)
    • 6.8 选举定时器(Election Timer)
    • 6.9 可能的异常情况
  • Lecture 07 - Raft2
    • 7.1 日志恢复(Log Backup)
    • 7.2 选举约束(Election Restriction)
    • 7.3 快速恢复(Fast Backup)
    • 7.4 持久化(Persistence)
    • 7.5 日志快照(Log Snapshot)
    • 7.6 线性一致(Linearizability)
  • Lecture 08 - Zookeeper
    • 8.1 线性一致(Linearizability)(1)
    • 8.2 线性一致(Linearizability)(2)
    • 8.3 线性一致(Linearizability)(3)
    • 8.4 Zookeeper
    • 8.5 一致保证(Consistency Guarantees)
    • 8.6 同步操作(sync)
    • 8.7 就绪文件(Ready file/znode)
  • Lecture 09 - More Replication, CRAQ
    • 9.1 Zookeeper API
    • 9.2 使用Zookeeper实现计数器
    • 9.3 使用Zookeeper实现非扩展锁
    • 9.4 使用Zookeeper实现可扩展锁
    • 9.5 链复制(Chain Replication)
    • 9.6 链复制的故障恢复(Fail Recover)
    • 9.7 链复制的配置管理器(Configuration Manager)
  • Lecture 10 - Cloud Replicated DB, Aurora
    • 10.1 Aurora 背景历史
    • 10.2 故障可恢复事务(Crash Recoverable Transaction)
    • 10.3 关系型数据库(Amazon RDS)
    • 10.4 Aurora 初探
    • 10.5 Aurora存储服务器的容错目标(Fault-Tolerant Goals)
    • 10.6 Quorum 复制机制(Quorum Replication)
    • 10.7 Aurora读写存储服务器
    • 10.8 数据分片(Protection Group)
    • 10.9 只读数据库(Read-only Database)
  • Lecture 11 - Cache Consistency: Frangipani
    • 11.1 Frangipani 初探
    • 11.2 Frangipani的挑战(Challenges)
    • 11.3 Frangipani的锁服务(Lock Server)
    • 11.4 缓存一致性(Cache Coherence)
    • 11.5 原子性(Atomicity)
    • 11.6 Frangipani Log
    • 11.7 故障恢复(Crash Recovery)
    • 11.8 Frangipani总结
  • Lecture 12 - Distributed Transaction
    • 12.1 分布式事务初探(Distributed Transaction)
    • 12.2 并发控制(Concurrency Control)
    • 12.3 两阶段提交(Two-Phase Commit)
    • 12.4 故障恢复(Crash Recovery)
    • 12.5 总结
由 GitBook 提供支持
在本页

这有帮助吗?

  1. Lecture 09 - More Replication, CRAQ

9.7 链复制的配置管理器(Configuration Manager)

上一页9.6 链复制的故障恢复(Fail Recover)下一页Lecture 10 - Cloud Replicated DB, Aurora

最后更新于4年前

这有帮助吗?

(接上一节最后)

所以,Chain Replication并不能抵御网络分区,也不能抵御脑裂。在实际场景中,这意味它不能单独使用。Chain Replication是一个有用的方案,但是它不是一个完整的复制方案。它在很多场景都有使用,但是会以一种特殊的方式来使用。总是会有一个外部的权威(External Authority)来决定谁是活的,谁挂了,并确保所有参与者都认可由哪些节点组成一条链,这样在链的组成上就不会有分歧。这个外部的权威通常称为Configuration Manager。

Configuration Manager的工作就是监测节点存活性,一旦Configuration Manager认为一个节点挂了,它会生成并送出一个新的配置,在这个新的配置中,描述了链的新的定义,包含了链中所有的节点,HEAD和TAIL。Configuration Manager认为挂了的节点,或许真的挂了也或许没有,但是我们并不关心。因为所有节点都会遵从新的配置内容,所以现在不存在分歧了。

现在只有一个角色(Configuration Manager)在做决定,它不可能否认自己,所以可以解决脑裂的问题。

当然,你是如何使得一个服务是容错的,不否认自己,同时当有网络分区时不会出现脑裂呢?答案是,Configuration Manager通常会基于Raft或者Paxos。在CRAQ的场景下,它会基于Zookeeper。而Zookeeper本身又是基于类似Raft的方案。

所以,你的数据中心内的设置通常是,你有一个基于Raft或者Paxos的Configuration Manager,它是容错的,也不会受脑裂的影响。之后,通过一系列的配置更新通知,Configuration Manager将数据中心内的服务器分成多个链。比如说,Configuration Manager决定链A由服务器S1,S2,S3组成,链B由服务器S4,S5,S6组成。

Configuration Manager通告给所有参与者整个链的信息,所以所有的客户端都知道HEAD在哪,TAIL在哪,所有的服务器也知道自己在链中的前一个节点和后一个节点是什么。现在,单个服务器对于其他服务器状态的判断,完全不重要。假如第二个节点真的挂了,在收到新的配置之前,HEAD需要不停的尝试重发请求。节点自己不允许决定谁是活着的,谁挂了。

这种架构极其常见,这是正确使用Chain Replication和CRAQ的方式。在这种架构下,像Chain Replication一样的系统不用担心网络分区和脑裂,进而可以使用类似于Chain Replication的方案来构建非常高速且有效的复制系统。比如在上图中,我们可以对数据分片(Sharding),每一个分片都是一个链。其中的每一个链都可以构建成极其高效的结构来存储你的数据,进而可以同时处理大量的读写请求。同时,我们也不用太担心网络分区的问题,因为它被一个可靠的,非脑裂的Configuration Manager所管理。

学生提问:为什么存储具体数据的时候用Chain Replication,而不是Raft?

Robert教授:这是一个非常合理的问题。其实数据用什么存并不重要。因为就算我们这里用了Raft,我们还是需要一个组件在产生冲突的时候来做决策。比如说数据如何在我们数百个复制系统中进行划分。如果我需要一个大的系统,我需要对数据进行分片,需要有个组件来决定数据是如何分配到不同的分区。随着时间推移,这里的划分可能会变化,因为硬件可能会有增减,数据可能会变多等等。Configuration Manager会决定以A或者B开头的key在第一个分区,以C或者D开头的key在第二个分区。至于在每一个分区,我们该使用什么样的复制方法,Chain Replication,Paxos,还是Raft,不同的人有不同的选择,有些人会使用Paxos,比如说Spanner,我们之后也会介绍。在这里,不使用Paxos或者Raft,是因为Chain Replication更加的高效,因为它减轻了Leader的负担,这或许是一个非常关键的问题。

某些场合可能更适合用Raft或者Paxos,因为它们不用等待一个慢的副本。而当有一个慢的副本时,Chain Replication会有性能的问题,因为每一个写请求需要经过每一个副本,只要有一个副本变慢了,就会使得所有的写请求处理变慢。这个可能非常严重,比如说你有1000个服务器,因为某人正在安装软件或者其他的原因,任意时间都有几个服务器响应比较慢。每个写请求都受限于当前最慢的服务器,这个影响还是挺大的。然而对于Raft,如果有一个副本响应速度较慢,Leader只需要等待过半服务器,而不用等待所有的副本。最终,所有的副本都能追上Leader的进度。所以,Raft在抵御短暂的慢响应方面表现的更好。一些基于Paxos的系统,也比较擅长处理副本相距较远的情况。对于Raft和Paxos,你只需要过半服务器确认,所以不用等待一个远距离数据中心的副本确认你的操作。这些原因也使得人们倾向于使用类似于Raft和Paxos这样的选举系统,而不是Chain Replication。这里的选择取决于系统的负担和系统要实现的目标。

不管怎样,配合一个外部的权威机构这种架构,我不确定是不是万能的,但的确是非常的通用。

学生提问:如果Configuration Manger认为两个服务器都活着,但是两个服务器之间的网络实际中断了会怎样?

Robert教授:对于没有网络故障的环境,总是可以假设计算机可以通过网络互通。对于出现网络故障的环境,可能是某人踢到了网线,一些路由器被错误配置了或者任何疯狂的事情都可能发生。所以,因为错误的配置你可能陷入到这样一个情况中,Chain Replication中的部分节点可以与Configuration Manager通信,并且Configuration Manager认为它们是活着的,但是它们彼此之间不能互相通信。

这是这种架构所不能处理的情况。如果你希望你的系统能抵御这样的故障。你的Configuration Manager需要更加小心的设计,它需要选出不仅是它能通信的服务器,同时这些服务器之间也能相互通信。在实际中,任意两个节点都有可能网络不通。