8.4.4 基于文件系统的中间件

隐藏在Web背后的基本思想是,使一个分布式系统看起来像一个巨大的、超链接的集合。另一种处理方式则是使一个分布式系统看起来像一个大型文件系统。在这一节中,我们将考察一些与设计一个广域文件系统有关的问题。

分布式系统采用一个文件系统模型意味着只存在一个全局文件系统,全世界的用户都能够读写他们各自具有授权的文件。通过一个进程将数据写入文件而另一个进程把数据读出的办法可以实现通信。由此产生了标准文件系统中的许多问题,但是也有一些与分布性相关的新问题。

1.传输模式

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

第一个问题是,在上传/下载模式(upload/download model)和远程访问模式之间的选择问题。在前一种模式中,如图8-36a所示,通过把远程服务器上的文件复制到本地的方法,实现进程对远程文件的访问。如果只是需要读该文件,考虑到高性能的需要,就在本地读出该文件。如果需要写入该文件,就在本地写入。进程完成工作之后,把更新后的文件送回原来的服务器。在远程访问模式中,文件停留在服务器上,而客户机向服务器发出命令并在服务器上完成工作,如图8-36b所示。

阅读 ‧ 电子书库
图 8-36 a)上传/下载模式;b)远程访问模式

上传/下载模式的优点是简单,而且一次性传送整个文件的方法比用小块传送文件的方法效率更高。其缺点是为了在本地存放整个文件,必须拥有足够的空间,即使只需要文件的一部分也要移动整个文件,这样做显然是一种浪费,而且如果有多个并发用户则会产生一致性问题。

2.目录层次

文件只是所涉及的问题中的一部分。另一部分问题是目录系统。所有的分布式系统都支持有多个文件的目录。接下来的设计问题是,是否所有的用户都拥有该目录层次的相同视图。图8-37中的例子正好表达了我们的意思。在图8-37a中有两个文件服务器,每个服务器有三个目录和一些文件。在图8-37b中有一个系统,其中所有的客户(以及其他机器)对该分布式文件系统拥有相同的视图。如果在某台机器上路径/D/E/x是有效的,则该路径对所有其他的客户也是有效的。

相反,在图8-37c中,不同的机器有该文件系统的不同视图。重复先前的例子,路径/D/E/x可能在客户机1上有效,但是在客户机2上无效。在通过远程安装方式管理多个文件服务器的系统中,图8-37c是一个典型示例。这样既灵活又可直接实现,但是其缺点是,不能使得整个系统行为像单一的、旧式分时系统。在分时系统中,文件系统对任何进程都是一样的,如图8-37b中的模型。这个属性显然使得系统容易编程和理解。

阅读 ‧ 电子书库
图 8-37 a)两个文件服务器。矩形代表目录,圆圈代表文件;b)所有客户机都有相同文件系统视图的系统;c)不同的客户机可能会有不同文件系统视图的系统

一个密切相关的问题是,是否存在一个所有的机器都承认的全局根目录。获得全局根目录的一个方法是,让每个服务器的根目录只包含一个目录项。在这种情况下,路径取/server/path的形式,这种方式有其缺点,但是至少做到了在系统中处处相同。

3.命名透明性

这种命名方式的主要问题是,它不是完全透明的。这里涉及两种类型的透明性(transparency),并且有必要加以区分。第一种,位置透明性(location transparency),其含义是路径名没有隐含文件所在位置的信息。类似于/server1/dir1/dir2/x的路径告诉每个人,x是在服务器1上,但是并没有说明该服务器在哪里。在网络中该服务器可以随意移动,而该路径名却不必改动。所以这个系统具有位置透明性。

但是,假设文件非常大而在服务器1上的空间又很紧张。进而,如果在服务器2上有大量的空间,那么系统也许会自动地将x从1移到服务器2上。不幸地,当整个路径名的第一个分量是服务器时,即使dir1和dir2在两个服务器上都存在,系统也不能将文件自动地移动到其他的服务器上。问题在于,让文件自动移动就得将其路径名从/server1/dir1/dir2/x改变成为/server2/dir1/dir2/x。如果路径改变了,那么在内部拥有前一个路径字符串的程序就会停止工作。如果在一个系统中文件移动时文件的名称不会随之改变,则称为具有位置独立性(location independence)。将机器或服务器名称嵌在路径名中的分布式系统显然不具有位置独立性。一个基于远程安装(挂载)的系统当然也不具有位置独立性,因为在把某个文件从一个文件组(安装单元)移到另一个文件组时,是不可能仍旧使用原来的路径名的。可见位置独立性是不容易实现的,但它是分布式系统所期望的一个属性。

这里把前面讨论过的内容加以简要的总结,在分布式系统中处理文件和目录命名的方式通常有以下三种:

1)机器+路径名,如/machine/path或machine:path。

2)将远程文件系统安装在本地文件层次中。

3)在所有的机器上看来都相同的单一名字空间。

前两种方式很容易实现,特别是作为将原本不是为分布式应用而设计的已有系统连接起来的方式时是这样。而第三种方式的实现则是困难的,并且需要仔细的设计,但是它能够减轻了程序员和用户的负担。

4.文件共享的语义

当两个或多个用户共享同一个文件时,为了避免出现问题有必要精确地定义读和写的语义。在单处理器系统中,通常,语义是如下表述的,在一个read系统调用跟随一个write系统调用时,则read返回刚才写入的值,如图8-38a所示。类似地,当两个write连续出现,后跟随一个read时,则读出的值是后一个写操作所存入的值。实际上,系统强制所有的系统调用有序,并且所有的处理器都看到同样的顺序。我们将这种模型称为顺序一致性(sequential consistency)。

在分布式系统中,只要只有一个文件服务器而且客户机不缓存文件,那么顺序一致性是很容易实现的。所有的read和write直接发送到这个文件服务器上,而该服务器严格地按顺序执行它们。

不过,实际情况中,如果所有的文件请求都必须送到单台文件服务器上处理,那么这个分布式系统的性能往往会很糟糕。这个问题可以用如下方式来解决,即让客户机在其私有的高速缓存中保留经常使用文件的本地副本。但是,如果客户机1修改了在本地高速缓存中的文件,而紧接着客户机2从服务器上读取该文件,那么客户机2就会得到一个已经过时的文件,如图8-38b所示。

阅读 ‧ 电子书库
图 8-38 a)顺序一致性;b)在一个带有高速缓存的分布式系统中,读文件可能会返回一个废弃的值

走出这个困局的一个途径是,将高速缓存文件上的改动立即传送回服务器。尽管概念上很简单,但这个方法却是低效率的。另一个解决方案是放宽文件共享的语义。一般的语义要求一个读操作要看到其之前的所有写操作的效果,我们可以定义一条新规则来取代它:“在一个打开文件上所进行的修改,最初仅对进行这些修改的进程是可见的。只有在该文件关闭之后,这些修改才对其他进程可见。”采用这样一个规则不会改变在图8-38b中发生的事件,但是这条规则确实重新定义了所谓正确的具体操作行为(B得到了文件的原始值)。当客户机1关闭文件时,它将一个副本回送给服务器,因此,正如所期望的,后续的read操作得到了新的值。实际上,这个规则就是图8-36中的上传/下载模式。这种语义已经得到广泛的实现,即所谓的会话语义(session semantic)。

使用会话语义产生了新的问题,即如果两个或更多的客户机同时缓存并修改同一个文件,应该怎么办?一个解决方案是,当每个文件依次关闭时,其值会被送回给服务器,所以最后的结果取决于哪个文件最后关闭。一个不太令人满意的、但是较容易实现的替代方案是,最后的结果是在各种候选中选择一个,但并不指定是哪一个。

对会话语义的另一种处理方式是,使用上传/下载模式,但是自动对已经下载的文件加锁。其他试图下载该文件的客户机将被挂起直到第一个客户机返回。如果对某个文件的操作要求非常多,服务器可以向持有该文件的客户机发送消息,询问是否可以加快速度,不过这样做可能没有作用。总而言之,正确地实现共享文件的语义是一件棘手的事情,并不存在一个优雅和有效的解决方案。