Files
MIT6.824/lecture-11-cache-consistency-frangipani/1.3-huan-cun-yi-zhi-xing-cache-coherence.md
2022-01-25 02:41:31 +00:00

5.3 KiB
Raw Blame History

11.3 Frangipani的锁服务Lock Server

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状态。

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

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

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

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

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

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