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.5 链复制(Chain Replication)

上一页9.4 使用Zookeeper实现可扩展锁下一页9.6 链复制的故障恢复(Fail Recover)

最后更新于4年前

这有帮助吗?

这一部分,我们来讨论另一个论文CRAQ(Chain Replication with Apportioned Queries)。我们选择CRAQ论文有两个原因:第一个是它通过复制实现了容错;第二是它通过以链复制API请求这种有趣的方式,提供了与Raft相比不一样的属性。

CRAQ是对于一个叫链式复制(Chain Replication)的旧方案的改进。Chain Replication实际上用的还挺多的,有许多现实世界的系统使用了它,CRAQ是对它的改进。CRAQ采用的方式与Zookeeper非常相似,它通过将读请求分发到任意副本去执行,来提升读请求的吞吐量,所以副本的数量与读请求性能成正比。CRAQ有意思的地方在于,它在任意副本上执行读请求的前提下,还可以保证线性一致性(Linearizability)。这与Zookeeper不太一样,Zookeeper为了能够从任意副本执行读请求,不得不牺牲数据的实时性,因此也就不是线性一致的。CRAQ却可以从任意副本执行读请求,同时也保留线性一致性,这一点非常有趣。

首先,我想讨论旧的Chain Replication系统。Chain Replication是这样一种方案,你有多个副本,你想确保它们都看到相同顺序的写请求(这样副本的状态才能保持一致),这与Raft的思想是一致的,但是它却采用了与Raft不同的拓扑结构。

首先,在Chain Replication中,有一些服务器按照链排列。第一个服务器称为HEAD,最后一个被称为TAIL。

当客户端想要发送一个写请求,写请求总是发送给HEAD。

HEAD根据写请求更新本地数据,我们假设现在是一个支持PUT/GET的key-value数据库。所有的服务器本地数据都从A开始。

当HEAD收到了写请求,将本地数据更新成了B,之后会再将写请求通过链向下一个服务器传递。

下一个服务器执行完写请求之后,再将写请求向下一个服务器传递,以此类推,所有的服务器都可以看到写请求。

当写请求到达TAIL时,TAIL将回复发送给客户端,表明写请求已经完成了。这是处理写请求的过程。

对于读请求,如果一个客户端想要读数据,它将读请求发往TAIL,

TAIL直接根据自己的当前状态来回复读请求。所以,如果当前状态是B,那么TAIL直接返回B。读请求处理的非常的简单。

这里只是Chain Replication,并不是CRAQ。Chain Replication本身是线性一致的,在没有故障时,从一致性的角度来说,整个系统就像只有TAIL一台服务器一样,TAIL可以看到所有的写请求,也可以看到所有的读请求,它一次只处理一个请求,读请求可以看到最新写入的数据。如果没有出现故障的话,一致性是这么得到保证的,非常的简单。

从一个全局角度来看,除非写请求到达了TAIL,否则一个写请求是不会commit,也不会向客户端回复确认,也不能将数据通过读请求暴露出来。而为了让写请求到达TAIL,它需要经过并被链上的每一个服务器处理。所以我们知道,一旦我们commit一个写请求,一旦向客户端回复确认,一旦将写请求的数据通过读请求暴露出来,那意味着链上的每一个服务器都知道了这个写请求。