> For the complete documentation index, see [llms.txt](https://mit-public-courses-cn-translatio.gitbook.io/mit6-824/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mit-public-courses-cn-translatio.gitbook.io/mit6-824/lecture-11-cache-consistency-frangipani/11.1-frangipani-chu-tan.md).

# 11.1 Frangipani 初探

今天讨论的论文是Frangipani，这是一篇很久之前有关分布式文件系统的论文。尽管如此，我们还要读这篇论文的原因是，它有大量有关缓存一致性，分布式事务和分布式故障恢复有关的有趣的并且优秀的设计，并且它还介绍了这几种功能之间的关联，论文里的这些内容是我们真正想要了解的。

Frangipani论文里面有大量缓存一致性的介绍（Cache Coherence）。缓存一致性是指，如果我缓存了一些数据，之后你修改了实际数据但是并没有考虑我缓存中的数据，必须有一些额外的工作的存在，这样我的缓存才能与实际数据保持一致。论文还介绍了分布式事务（Distributed Transaction），这对于向文件系统的数据结构执行复杂更新来说是必须的。因为文件本质上是分割散落在大量的服务器上，能够从这些服务器实现分布式故障恢复（Distributed Crash Recovery）也是至关重要的。

![](https://2933519158-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAkokVMtbC7djI1pgSw%2F-MFrdH5gMPNrw9hDC97i%2F-MFrnZqLFhmXzo_8gt2u%2Fimage.png?alt=media\&token=43f8f7c2-f705-45ed-91ee-5df2912e0560)

从整体架构上来说，Frangipani就是一个网络文件系统（NFS，Network File System）。它的目标是与已有的应用程序一起工作，比如说一个运行在工作站上的普通UNIX程序。它与Athena的AFS非常类似（没听过）。从一个全局视图来看，它包含了大量的用户（U1，U2，U3）。

![](https://2933519158-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAkokVMtbC7djI1pgSw%2F-MFrdH5gMPNrw9hDC97i%2F-MFrq3qf9_BF_qSc8oS3%2Fimage.png?alt=media\&token=8f2a5d18-ebfa-492d-94b3-1f1ea1c4abe8)

每个用户坐在一个工作站前面，在论文那个年代，笔记本还不流行，大家使用的主要是工作站，不过工作站也就是一个带有键盘鼠标显示器和操作系统的计算机。三个用户对应的工作站（Workstation）分别是WS1，WS2，WS3。

![](https://2933519158-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAkokVMtbC7djI1pgSw%2F-MFrdH5gMPNrw9hDC97i%2F-MFrqAOiGCBeso5Boa87%2Fimage.png?alt=media\&token=f21bc45d-1999-441b-9767-43c3a1964725)

每一个工作站运行了一个Frangipani服务。论文中大部分功能都是在Frangipani软件中实现。所以，用户坐在一个工作站前面，他可能在运行一些普通的应用程序，比如说一个普通的文本编辑（VI）或者说一个编译程序（CC）。当这些普通的应用程序执行文件系统调用时，在系统内核中，有一个Frangipani模块，它实现了文件系统。

![](https://2933519158-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAkokVMtbC7djI1pgSw%2F-MFrdH5gMPNrw9hDC97i%2F-MFrrn11uyrXUuSSayRa%2Fimage.png?alt=media\&token=dcd8434d-bffe-404c-8d66-c90a11e2a61b)

在所有的工作站中，都有类似的结构。

![](https://2933519158-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAkokVMtbC7djI1pgSw%2F-MFrdH5gMPNrw9hDC97i%2F-MFrs4rEr_2P41Cc29X4%2Fimage.png?alt=media\&token=a50e3992-e69d-493e-a0da-33f971ea9a1c)

文件系统的数据结构，例如文件内容、inode、目录、目录的文件列表、inode和块的空闲状态，所有这些数据都存在一个叫做Petal的共享虚拟磁盘服务中。Petal运行在一些不同的服务器上，有可能是机房里面的一些服务器，但是不会是人们桌子上的工作站。Petal会复制数据，所以你可以认为Petal服务器成对的出现，这样就算一个故障了，我们还是能取回我们的数据。当Frangipani需要读写文件时，它会向正确的Petal服务器发送RPC，并说，我需要这个块，请读取这个块，并将数据返回给我。在大部分时候，Petal表现的就像是一个磁盘，你可以把它看做是共享的磁盘，所有的Frangipani都会与之交互。

![](https://2933519158-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAkokVMtbC7djI1pgSw%2F-MFrdH5gMPNrw9hDC97i%2F-MFrxJ_9uAtwwB0wFlUh%2Fimage.png?alt=media\&token=2cbd3bd6-9513-49b7-8552-2f58f5e87213)

从我们的角度来看，大部分的讨论都会假设Petal就是一个被所有Frangipani使用的，基于网络的共享磁盘。你可以通过一个块号或者磁盘上的一个地址来读写数据，就像一个普通的硬盘一样。

论文作者期望使用Frangipani的目的，是驱动设计的一个重要因素。作者想通过Frangipani来支持他们自己的一些活动，作者们是一个研究所的成员，假设研究所有50个人，他们习惯于使用共享的基础设施，例如分时间段使用同一批服务器，工作站。他们还期望通过网络文件系统在相互协作的研究员之间共享文件。所以他们想要这样一个文件系统，它可以用来存放每一个研究员的home目录，同时也可以存放共享的项目文件。这意味着，如果我编辑了一个文件，我希望其他与我一起工作的人可以读到我刚刚编辑的文件。他们期望达成这样的共享的目的。

除此之外，如果我坐在任意一个工作站前面，我都能获取到所有的文件，包括了我的home目录，我环境中所需要的一切文件。所以他们需要的是一个在相对小的组织中，针对普通使用者的共享文件系统。相对小的组织的意思是，每个人在每台工作站前都被信任。本质上来说，Frangipani的设计并没有讨论安全。在一个类似Athena的系统中，是不能随意信任使用者和工作站。所以，Frangipani是针对作者自己环境的一个设计。

至于性能，在他们的环境中也非常重要。实际上，大部分时候，人们使用工作站时，他们基本上只会读写自己的文件。他们或许会读取一些共享文件，比如说项目文件，但是大部分时候，我只会读写我自己的文件，你在你的工作站上只会读写你自己的文件。用户之间频繁的分享文件反而很少见。所以，尽管数据的真实拷贝是在共享的磁盘中，但是如果在本地能有一些缓存，那将是极好的。因为这样的话，我登录之后，我使用了我的一些文件，之后它们在本地缓存了一份，这样它们接下来可以在微秒级别读出来，而不是毫秒级别的从文件服务器获取它们。

除了最基本的缓存之外，Frangipani还支持Write-Back缓存。所以，除了在每个工作站或者说每个Frangipani服务器上要持有缓存之外，我们还需要支持Write-Back缓存。这意味着，如果我想要修改某个数据，比如说我修改了一个文件，或者创建了一个文件，或者删除了一个文件，只要没有其他的工作站需要看到我的改动，Frangipani通过Write-Back缓存方式管理这些数据。这意味着，最开始的时候，我的修改只会在本地的缓存中。如果我创建了一个文件，至少在最开始，有关新创建文件的信息，比如说新创建的inode和初始化的内容，home目录文件列表的更新，文件名等等，所有的这些修改最初只会在本地缓存中存在，因此类似于创建文件的操作可以非常快的完成，因为只需要修改本地的内存中对于磁盘的缓存。而这些修改要过一会才会写回到Petal。所以最开始，我们可以为文件系统做各种各样的修改，至少对于我自己的目录，我自己的文件，这些修改完全是本地的。这对于性能来说有巨大的帮助，因为写本地内存的性能比通过RPC向一个远端服务器写要快1000倍。

在这样的架构下，一个非常重要的后果是，文件系统的逻辑需要存在于每个工作站上。为了让所有的工作站能够只通过操作内存就完成类似创建文件的事情，这意味着所有对于文件系统的逻辑和设计必须存在于工作站内部。

在Frangipani的设计中，Petal作为共享存储系统存在，它不知道文件系统，文件，目录，它只是一个很直观简单的存储系统，所有的复杂的逻辑都在工作站中的Frangipani模块中。所以这是一个非常去中心化的设计，这或许是实际需要的设计，也有可能是作者能想到的能让他们完成目标的设计。这种设计有好的影响。因为主要的复杂度，主要的CPU运算在每个工作站上，这意味着，随着你向系统增加更多的工作站，增加更多的用户，你自动的获得了更多的CPU算力来运行这些新的用户的文件系统操作。因为大部分的文件系统操作只在工作站本地发生，所以大部分CPU消耗的都是本地的，所以这个系统的天然自带扩展性。每个新工作站会接收来自一个新用户更多的负担，但是它同时也带来更多的CPU算力来运行那个用户的文件系统操作。

当然，在某个时间点，瓶颈会在Petal。因为这是一个中心化的存储系统，这时，你需要增加更多的存储服务器。

![](https://2933519158-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAkokVMtbC7djI1pgSw%2F-MFrdH5gMPNrw9hDC97i%2F-MFsAAkV8NWhAJLM5saX%2Fimage.png?alt=media\&token=a91df34b-015f-4bad-8057-db8f9b501680)

所以，我们现在有了一个系统，它在工作站里面做了大量的缓存，并且文件的修改可以在本地缓存完成。这几乎立刻引出了有关设计的几个非常严重的挑战。

![](https://2933519158-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAkokVMtbC7djI1pgSw%2F-MFrdH5gMPNrw9hDC97i%2F-MFsAUr43cZGwQS4P81G%2Fimage.png?alt=media\&token=853560aa-8c18-4ff6-81ee-90a527b49eb2)

Frangipani的设计基本上就是用来解决相应的挑战的，我们接下来看一下会有哪些挑战。
