本文主要介绍NAS支持的NFS协议版本、NFSv3和NFSv4协议的功能差异及NFS一致性。

NFS概念

NFS(Network File System),即网络文件系统协议,是一种分布式文件系统协议,通过NFS协议,您可以像访问本地文件一样访问远端系统上的文件。

Linux操作系统和容器建议使用NFS协议类型的文件系统。如果使用SMB协议类型的文件系统,可能会存在一些兼容性的问题。更多信息,请参见交叉挂载兼容性常见问题

协议版本

NFS一共发布了3个版本:NFSv2、NFSv3、NFSv4。其中,NFSv4包含两个次版本NFSv4.0和NFSv4.1。

通用型NAS支持NFSv3和NFSv4.0版本。

极速型NAS支持NFSv3版本。

NFSv3和NFSv4.0差异

  • 功能

    NFSv4.0:是一种有状态的协议,自身实现了文件锁功能和获取文件系统根节点功能。

    NFSv3:对文件锁无感知,同时挂载时可能会覆盖掉v4写入的部分。

  • 安全性

    NFSv4.0增加了安全性,支持RPCSEC-GSS身份认证。

  • 请求

    NFSv4.0只提供了两个请求NULL和COMPOUND,所有的操作都整合到COMPOUND中,客户端可以根据实际请求将多个操作封装到一个COMPOUND请求中,增加了灵活性。

  • 命令空间

    NFSv4.0文件系统的命令空间发生了变化,服务器端必须设置一个根文件系统(fsid=0),其他文件系统挂载在根文件系统上导出。

更多关于NFS文件系统使用限制,请参见协议类型限制

NFS Cache应用

在传统云盘中,所有的数据都会被缓存在PageCache中,修改过的Page会被异步刷回服务端,所以云盘的延时都比较低。但在NFS文件系统中,NFS不会将新创建的文件或者新写入的内容缓存在PageCache中,而是尽快刷回NAS服务端。因此,当多个ECS共享一个NFS协议文件系统时,NAS所有的操作都会比云盘多一次网络调用开销,这个开销一般在100us ~ 1ms之间。其中,尽快刷回NAS服务端,则涉及NAS所提供的如下多节点一致性模型:

基于超时的最终一致性

NFS会缓存目录或者文件的属性(FileAttr),操作系统会根据FileAttr是否发生变化,来判断这个目录或者文件是否在其他ECS被修改过。同时,加载FileAttr后,操作系统在T时间内,会认为Cache(例如,文件的内容、目录下的文件列表)有效;超过T时间后,会去服务端重新获取一次FileAttr,如果FileAttr未发生变化,操作系统会认为与此文件相关的Cache全部还是有效的。
说明
  • T为自适应的值。默认值:1s~60s。
  • 文件内容Cache:指缓存了这个文件的内容。
  • 目录子项Cache:缓存了这个目录下存在哪些文件、不存在哪些文件。
文件内容Cache示例:
  1. ECS-1读取了文件X的0~4K:第一次读,cache不命中,访问服务器,读取数据,并缓存在本地。
  2. ECS-2更新了文件X的0~4K:数据写到服务端,更新FileAttr中的mtime。
  3. ECS-1再次读文件X的0~4K:第二次读,如果时间距离第一次小于T,由于FileAttr还没有过期,因此,直接使用缓存中的0~4K。
  4. ECS-1再次读文件X的0~4K:第三次读,如果时间距离第一次大于T,则去访问服务端,获取新的FileAttr,然后发现mtime变了,因此丢弃cache中的数据,去服务端读。
目录子项Cache示例:
  1. ECS-1尝试查找/a:第一次查找,发现a不存在,于是在目录/下缓存一个a不存在的信息。
  2. ECS-2创建文件/a
  3. ECS-1再次查找/a:第二次查找,由于时间小于T,直接使用cache,然后向用户报错文件不存在。
  4. ECS-1 再次访问/a:第三次查找,由于时间大于T,访问服务端,获取目录/最新的FileAttr,发现mtime有变化,则丢弃cache中的数据,去服务端查询/a

更多有关NFS超时的最终一致性模型内容,请参见NFS

基于文件close/open的CTO一致性

由于超时的最终一致性无法保证ECS-2可以立刻读ECS-1写入的数据。因此,为了提升一致性,NFS还提供了基于文件的CTO(close-to-open)一致性保证,即当两个及以上计算节点同时读写相同的文件时,ECS-1的修改在ECS-2不一定能立即看到。但是,一旦ECS-1打开一个文件,写入若干数据,然后执行了文件关闭操作,之后在任何一个计算节点重新打开该文件都可以保证能访问到新写入的数据。

例如,生产者ECS生产了文件X,生产完毕后执行了close。然后给消息队列发一条消息说,文件X生产完毕。消费者ECS订阅消息队列,读到消息X(文件X生产完毕),此时,消费者ECS再去open这个文件,通过open返回的fd去读取这个文件,则一定能够读到文件X的所有内容。如果消费者ECS在生产者ECS生产完毕之前,就open了文件X,并且持有了fd,当收到消息后,直接用这个fd去读,是不保证能够读取到最新数据的。

关于解决文件创建或写入延迟的解决方案,请参见如何解决在NFS文件系统中创建文件延迟问题?如何解决向NFS文件系统中写入数据延迟问题?