卷,服务器,服务器间的复制
大多数的网络文件系统是在服务器上的一个可以被远程调用的本地文件结构。这种可以被远程客户端挂载的文件系统,在windows上称作网络共享 (network share),在unix上称作网络文件系统(network file system)。大多数这样的系统都是远程挂载一个已经在分布的服务器上的挂载好的卷。这样的系统关心的是服务器的分区、目录以及相应的共享。Coda和 AFS文件系统从本质上与这些是不一样的。
Coda服务器上的文件并不是存放在通常的文件系统上的。对于这些文件的组织如下所示。Coda 服务器以及工作站的分区作为对文件服务器可用的部分。这些分区将存放按照卷的方式来管理的文件。每一个卷带有一个和文件系统一样的目录结构,也就是说一个卷的根目录以及根目录下的目录树。相对于分区来说,卷要小,但是相对于单一个目录或者单一的文件的逻辑单位来说,卷要大。举例来说,某个用户的home目 录可能就是一个单独的coda卷,coda相关的资源就存放在这个卷里面。通常情况下一个单独的服务器可能包含数百个卷,每个卷的平均大小可能是10兆。 从系统管理员的角度来看,卷是一个易于管理的很灵活的普通的文件数据。
Coda将卷、目录、访问控制列表以及文件的属性保存在一个raw分区中。通过一种基于日志的可恢复的虚拟内存系统 (log based recoverable virtual memory package, RVM)来实现快速并且确保一致性的访问。只有文件的数据保存在服务器的分区上。通过RVM可以实现对事务的支持,也就是说当服务器崩溃后,不用花费太多 的力气就可以恢复整个系统。
卷带有一个名称和他自己的编号,卷可以被挂载到/coda下的任何一个位置。比如要使一个叫做u.braam的卷挂载到 /coda/usr/braam,只需要执行"cfs makemount u.bramm /coda/usr/braam"。Coda不允许挂载点是一个已经存在的目录。他会把建立一个新的目录作为挂载的过程之一。这样做避免了将unix文件 系统挂载到已经存在的目录下。这个操作和Macintosh以及Windows的网络驱动器及共享很类似。但是最明显的区别是挂载点对于客户端是不可见 的。他看起来只是一个/coda下的很普通的目录。系统中有一个单独的卷具有作为根卷的权限,这个卷在启动的时候就被挂载。
Coda通过三组32位的整数来标示一个文件。这组整数被称为Fid。Fid包含卷编号(VolumeID)、V结点编号(VnodeID)以及一 个全局唯一标识符 (Uniquifier)。通过卷编号来确定文件存储的卷。V结点编号就是文件的i结点编号。全局唯一标识符来是为保持文件一致性处理准备的。Fid在 Coda服务器集群中是唯一的。
在coda服务器之间是有读写复制的。也就是说一组服务器向客户端发送文件数据,对文件的更新也会在这组服务器中执行。这样做的好处是提高了数据的可用性,假如一个服务器出现了问题,其他的服务器会自动接替,客户端不会受到任何影响。卷可以存放在一组服务器中,我们把这样的一组服务器叫做VSG (Volume Storage Group)。
这些复制的卷的卷编号也是被复制的。复制后的卷编号将本地的卷结合在一起成为VSG。
VSG是一个保存复制后卷的服务器列表。
每个服务器的本地卷定义了一个分区和本地的卷编号来保存文件和元数据。
当Venus 要访问服务器上的对象,他首先需要找到卷信息以便确定保存该文件的卷。这个卷信息包含服务器列表和存放该文件的服务器上的卷编号。在VSG中的服务器之间 关于文件的通信是读一次写多次的操作,即读取VSG中某一个服务器上的文件然后向所有的可用的VSG成员传播更新的消息。我们把可用的VSG成员叫做 AVSG(Available VSG members)。Coda可以使用多点传送RPC来向很多服务器提交更新操作,这样做不会对整体的性能有太大的影响。
前面讲到的必须首先获得卷信息有时候会给人带来误解。一旦获取卷信息之后,接下来的文件访问因为路径遍历的减少而受益。这是因为卷的根相对通常的挂载了很大的目录来说要近很多。(译者注:前文中提到每个卷都有自己根以及目录树,而卷可能会挂载在很深的目录中。直接从相应卷的根来找文件显然要比从 /coda找文件要快。)
服务器之间的复制就像是离线操作一样有两点需要介绍:决定是否复制以及如何修复错误。某些在VSG中的服务器可能因为服务器或者网络的故障和其他的 服务器隔离开了。在这样的情况下AVSG保存的对象一定会比VSG少。更新无法传递到所有的服务器上,只能传送到AVSG,从而会导致全局(服务器与服务器之间)冲突。
Fig 6: AVSG vs. VSG (原图例作者: Gaich Muramatsu)
在获取某个对象或者某个对象的属性之前,Venus首先从所有可用的服务器上获取该对象的版本戳。如果她发现某些服务器没有这个文件的最新版,她就 会启动一个处理进程来自动解决不一致的情况。如果无法解决,就需要用户手动来进行修复。这个进程由客户端发起,然后完全由服务器来执行。
服务期间的复制和解决不一致的情况看起来是不可思议的操作。我们的服务器经常出现磁盘故障。为了修复服务器所需做的工作只是替换新的磁盘然后告诉coda:去解决他吧。系统会自动向磁盘写入从别的服务器上获取的最新的数据。