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 11 - Cache Consistency: Frangipani

11.3 Frangipani的锁服务(Lock Server)

上一页11.2 Frangipani的挑战(Challenges)下一页11.4 缓存一致性(Cache Coherence)

最后更新于4年前

这有帮助吗?

Frangipani的第一个挑战是缓存一致性。在这里我们想要的是线性一致性和缓存带来的好处。对于线性一致性来说,当我查看文件系统中任何内容时,我总是能看到最新的数据。对于缓存来说,我们想要缓存带来的性能提升。某种程度上,我们想要同时拥有这两种特性的优点。

人们通常使用缓存一致性协议(Cache Coherence Protocol)来实现缓存一致性。这些协议在很多不同的场景都有使用,不只在分布式文件系统,在多核处理器每个核的缓存的同步中也有使用。只是不同场景中,使用的协议是不一样的。

Frangipani的缓存一致性核心是由锁保证的,我们之后在原子性和故障恢复中将会再次看到锁。但是现在,我们只讨论用锁来保证缓存一致,用锁来帮助工作站确定当它们缓存了数据时,它们缓存的是最新的数据。

除了Frangipani服务器(也就是工作站),Petal存储服务器,在Frangipani系统中还有第三类服务器,锁服务器。尽管你可以通过分片将锁分布到多个服务器上,但是我接下来会假设只有一个锁服务器。逻辑上,锁服务器是独立的服务器,但是实际上我认为它与Petal服务器运行在一起。在锁服务器里面,有一个表单,就叫做locks。我们假设每一个锁以文件名来命名,所以对于每一个文件,我们都有一个锁,而这个锁,可能会被某个工作站所持有。

在这个例子中,我们假设锁是排他锁(Exclusive Lock),尽管实际上Frangipani中的锁更加复杂可以支持两种模式:要么允许一个写入者持有锁,要么允许多个读取者持有锁。

假设文件X最近被工作站WS1使用了,所以WS1对于文件X持有锁。同时文件Y最近被工作站WS2使用,所以WS2对于文件Y持有锁。锁服务器会记住每个文件的锁被谁所持有。当然一个文件的锁也有可能不被任何人持有。

在每个工作站,会记录跟踪它所持有的锁,和锁对应的文件内容。所以在每个工作站中,Frangipani模块也会有一个lock表单,表单会记录文件名、对应的锁的状态和文件的缓存内容。这里的文件内容可能是大量的数据块,也可能是目录的列表。

当一个Frangipani服务器决定要读取文件,比如读取目录 /、读取文件A、查看一个inode,首先,它会向一个锁服务器请求文件对应的锁,之后才会向Petal服务器请求文件或者目录的数据。收到数据之后,工作站会记住,本地有一个文件X的拷贝,对应的锁的状态,和相应的文件内容。

每一个工作站的锁至少有两种模式。工作站可以读或者写相应的文件或者目录的最新数据,可以在创建,删除,重命名文件的过程中,如果这样的话,我们认为锁在Busy状态。

在工作站完成了一些操作之后,比如创建文件,或者读取文件,它会随着相应的系统调用(例如rename,write,create,read)释放锁。只要系统调用结束了,工作站会在内部释放锁,现在工作站不再使用那个文件。但是从锁服务器的角度来看,工作站仍然持有锁。工作站内部会标明,这是锁时Idle状态,它不再使用这个锁。所以这个锁仍然被这个工作站持有,但是工作站并不再使用它。这在稍后的介绍中比较重要。

现在这里的配置是一致的,锁服务器知道文件X和Y的锁存在,并且都被WS1所持有。工作站WS1也有同等的信息,它内部的表单知道它持有了这两个锁,并且它记住了这两个锁对应的文件或者目录。

这里Frangipani应用了很多的规则,这些规则使得Frangipani以一种提供缓存一致性的方式来使用锁,并确保没有工作站会使用缓存中的旧数据。这些规则、锁、缓存数据需要配合使用。这里的规则包括了:

  • 工作站不允许持有缓存的数据,除非同时也持有了与数据相关的锁。所以基本上来说,不允许在没有锁保护的前提下缓存数据。从操作意义上来说,这意味着对于一个工作站来说,在它使用一个数据之前,它首先要从锁服务器获取数据的锁。只有当工作站持有锁了,工作站才会从Petal读取数据,并将数据放在缓存中。所以这里的顺序是,获得锁,之后再从Petal读取数据。所以,直到获取了锁,工作站是不能缓存数据的,要想缓存数据,工作站必须先持有锁,之后,才能从Petal读取数据。

  • 如果你在释放锁之前,修改了锁保护的数据,那你必须将修改了的数据写回到Petal,只有在Petal确认收到了数据,你才可以释放锁,也就是将锁归还给锁服务器。所以这里的顺序是,先向Petal存储系统写数据,之后再释放锁。

最后再从工作站的lock表单中删除关文件的锁的记录和缓存的数据。