全部产品
Search
文档中心

文件存储 NAS:挂载NFS协议文件系统

更新时间:Jun 07, 2024

创建NAS NFS协议文件系统后,您需要使用云服务器来挂载该文件系统,以实现多个云服务器共享访问文件系统的目的。本文介绍如何通过阿里云Linux ECS实例挂载NAS NFS协议文件系统。

前提条件

  • 在创建文件系统的地域,已有可用的云服务器ECS(Linux)且该ECS实例已配置公网IP或弹性公网IP。具体操作,请参见创建ECS实例

  • 已创建NFS协议文件系统并获取到文件系统的挂载点地址,且与ECS属于同一VPC。具体操作,请参见创建文件系统

说明
  • 推荐您通过NFS v3协议挂载文件系统,以获得最佳访问性能。

  • NFS v4.0支持文件锁(包括range lock),如果您需要使用多台Linux ECS实例同时修改一个文件,请使用NFS v4.0协议挂载文件系统。

  • 文件存储NAS支持控制台一键挂载文件系统,提供更加方便、快捷的使用体验。推荐您使用控制台一键挂载功能。具体操作,请参见一键挂载NAS NFS协议文件系统

步骤一:安装NFS客户端

在Linux系统挂载NFS协议文件系统时,需要先安装NFS客户端。确保每台Linux服务器执行一次配置即可,不需要在每次挂载时都执行。

  1. 连接ECS实例。具体连接方式,请参见连接ECS实例

  2. 安装NFS客户端。

    操作系统

    安装命令

    Alibaba Cloud Linux

    sudo yum install nfs-utils

    CentOS

    Redhat

    Ubuntu

    依次执行以下安装命令:

    1. sudo apt-get update
    2. sudo apt-get install nfs-common

    Debian

  3. 增加同时发起的NFS请求的数量。

    请执行以下命令,将同时发起的NFS请求数量修改为128。更多信息,请参见如何修改同时发起NFS请求的数量

    if (lsmod | grep sunrpc); then
    (modinfo sunrpc | grep tcp_max_slot_table_entries) && sysctl -w sunrpc.tcp_max_slot_table_entries=128
    (modinfo sunrpc | grep tcp_slot_table_entries) && sysctl -w sunrpc.tcp_slot_table_entries=128
    fi
    (modinfo sunrpc | grep tcp_max_slot_table_entries) && echo "options sunrpc tcp_max_slot_table_entries=128" >> /etc/modprobe.d/sunrpc.conf
    (modinfo sunrpc | grep tcp_slot_table_entries) && echo "options sunrpc tcp_slot_table_entries=128" >> /etc/modprobe.d/sunrpc.conf

步骤二:挂载NFS协议文件系统

在Linux操作系统中,NAS NFS协议文件系统支持通过手动挂载和自动挂载两种方式进行挂载。为避免已挂载文件系统的云服务器ECS重启后,挂载信息丢失,建议您在手动挂载NAS NFS协议文件系统成功后,配置自动挂载NAS NFS协议文件系统,实现在云服务器ECS设置重启时NAS NFS协议文件系统自动挂载。

手动挂载NFS协议文件系统

您需要使用文件系统的挂载点地址,将NAS NFS协议文件系统挂载至Linux ECS实例。

  1. 挂载NFS协议文件系统。

    • 如果您使用的是通用型NAS,请执行以下命令。

      说明
      • 推荐您通过NFS v3协议挂载文件系统,以获得最佳访问性能。

      • NFS v4.0支持文件锁(包括range lock),如果您需要使用多台Linux ECS实例同时修改一个文件,请使用NFS v4.0协议挂载文件系统。

      使用NFS v3协议挂载文件系统:

      sudo mount -t nfs -o vers=3,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport file-system-id.region.nas.aliyuncs.com:/ /mnt

      使用NFS v4协议挂载文件系统:

      sudo mount -t nfs -o vers=4,minorversion=0,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport file-system-id.region.nas.aliyuncs.com:/ /mnt                                
    • 如果您使用的是极速型NAS,请执行以下命令。

      sudo mount -t nfs -o vers=3,nolock,noacl,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport file-system-id.region.extreme.nas.aliyuncs.com:/share /mnt

    挂载命令参数说明如下表所示。

    参数

    描述

    通用型NAS:file-system-id.region.nas.aliyuncs.com:/ /mnt

    极速型NAS:file-system-id.region.extreme.nas.aliyuncs.com:/share /mnt

    表示<挂载地址>:<NAS文件系统目录> <当前服务器上待挂载的本地路径>,请根据实际情况替换。

    • 挂载地址:您可以在文件存储NAS控制台文件系统列表页面,单击目标文件系统后的管理,进入挂载使用页面获取挂载地址。更多信息,请参见查看挂载点地址

    • NAS文件系统目录:NAS的根目录(/)或任意子目录(例如:/share),如果是子目录,请您确保子目录是NAS文件系统中实际已存在的目录。

      说明

      极速型NAS的共享目录必须以/share开头,例如:/share/share/subdir

    • 当前服务器上待挂载的本地路径:Linux ECS实例的根目录(/)或任意子目录(例如:/mnt),如果是子目录,请您确保子目录已存在。

    vers

    文件系统版本。

    • vers=3:使用NFS v3协议挂载文件系统。

    • vers=4:使用NFS v4协议挂载文件系统。

      其中,minorversion为协议次版本号,NAS支持的NFS v4协议版本为4.0,因此使用NFS v4协议挂载文件系统时,次版本号为0。

    说明
    • 通用型NAS:支持NFS v3和NFS v4.0。

    • 极速型NAS:只支持NFS v3,不支持NFS v4。

    挂载选项

    挂载文件系统时,可选择多种挂载选项,挂载选项使用半角逗号(,)分隔,说明如下:

    • rsize:定义数据块的大小,用于客户端与文件系统之间读取数据。建议值:1048576。

    • wsize:定义数据块的大小,用于客户端与文件系统之间写入数据。建议值:1048576。

      说明

      如果您需要更改IO大小参数(rsize和wsize),建议您尽可能使用最大值(1048576),以避免性能下降。

    • hard:在文件存储NAS暂时不可用的情况下,使用文件系统上某个文件的本地应用程序时会停止并等待至该文件系统恢复在线状态。建议启用该参数。

    • timeo:指定时长,单位为0.1秒,即NFS客户端在重试向文件系统发送请求之前等待响应的时间。建议值:600(60秒)。

      说明

      如果您必须更改超时参数(timeo),建议您使用150或更大的值。该timeo参数的单位为0.1秒,因此150表示的时间为15秒。

    • retrans:NFS客户端重试请求的次数。建议值:2。

    • noresvport:在网络重连时使用新的TCP端口,保障在网络发生故障恢复时不会中断连接。建议启用该参数。

    重要
    • 不建议使用soft选项,有数据一致性风险。如果您要使用soft选项,相关风险需由您自行承担。

    • 避免设置不同于默认值的任何其他挂载选项。如果更改读或写缓冲区大小或禁用属性缓存,可能会导致性能下降。

  2. 验证挂载结果。

    • 执行命令

      mount -l
    • 返回示例

      如果返回信息包含如下类似信息,说明挂载成功。查看挂载结果

      挂载成功后,您还可以执行df -h命令,查看当前文件系统的容量信息。df-h

    如果挂载失败,请进行错误排查。具体操作,请参见挂载文件系统失败故障排查

  3. 挂载成功后,您可以在Linux ECS上访问NAS文件系统,执行读取或写入操作。

    您可以把NAS文件系统当作一个普通的目录来访问和使用,示例如下:读写操作

自动挂载NFS协议文件系统

为防止服务器重启后,导致无法查看NAS中的文件,建议您在手动挂载成功后,配置自动挂载文件系统。

  1. 如果您使用的是极速型NAS,请执行以下命令。

    如果您使用的是通用型NAS,请跳过此步骤,直接执行步骤2

    vi /etc/systemd/system/sockets.target.wants/rpcbind.socket

    打开/etc/systemd/system/sockets.target.wants/rpcbind.socket文件后,需要注释IPv6相关的rpcbind参数(如下图所示),否则NFS的rpcbind服务自动启动会失败。注释rpcbind参数

    如果您是在CentOS 6.x系统中配置自动挂载,您还需执行以下操作。

    1. 执行chkconfig netfs on命令,确保netfs服务开机自启动。

    2. 打开/etc/netconfig配置文件,注释掉inet6相关的内容(如下图所示)。注释inet6相关内容

  2. 打开/etc/fstab配置文件,添加挂载配置。

    通用型NAS

    • 使用NFS v3协议挂载文件系统:

      file-system-id.region.nas.aliyuncs.com:/ /mnt nfs vers=3,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,_netdev,noresvport 0 0
    • 使用NFS v4协议挂载文件系统:

      file-system-id.region.nas.aliyuncs.com:/ /mnt nfs vers=4,minorversion=0,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,_netdev,noresvport 0 0

    极速型NAS

    file-system-id.region.extreme.nas.aliyuncs.com:/share /mnt nfs vers=3,nolock,noacl,proto=tcp,noresvport,_netdev 0 0
    说明

    如果您是在CentOS 6.x系统中配置自动挂载,您需先执行chkconfig netfs on命令,确保netfs服务开机自启动。

    示例中主要参数说明,请参见挂载命令参数说明表。其余参数说明如下。

    参数

    说明

    _netdev

    防止客户端在网络就绪之前开始挂载文件系统。

    0(noresvport后第一项)

    非零值表示文件系统应由dump备份。对于NAS文件系统而言,此值默认为0。

    0(noresvport后第二项)

    该值表示fsck在启动时检查文件系统的顺序。对于NAS文件系统而言,此值默认为0,表示fsck不应在启动时运行。

  3. 执行以下命令,配置开机启动文件/etc/rc.local。

    [ ! -f /etc/rc.local ] && echo '#!/bin/bash' > /etc/rc.local; echo "sleep 3; mount -a -t nfs" >> /etc/rc.local; chmod +x /etc/rc.local
  4. 执行reboot命令,重启云服务器ECS。

  5. 验证自动挂载配置成功。

    在ECS重启后的一分钟内,执行df -h命令,确认挂载的NAS文件系统。

附录: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去读,是不保证能够读取到最新数据的。

典型问题

文件创建“延迟”

  • 问题现象:

    ECS-1创建了文件abc,但是ECS-2需要过一段时间才能看到ECS-1创建的文件abc,有时会延迟1s,有时甚至会到1分钟,这是为什么?

  • 问题原因:

    这是Lookup Cache导致的,符合预期T时间。例如,ECS-2在ECS-1创建文件abc前进行了访问,导致ECS-2发生文件不存在,于是缓存了一条文件abc不存在的记录。在T时间内,由于FileAttr还没有过期,ECS-2再次访问时,仍会访问第一次缓存到文件abc不存在的记录。

  • 解决方案:

    如果要保证ECS-1创建文件后,ECS-2立即就能看到它,可以使用如下方案:

    • 方案一:关闭ECS-2的Negative Lookup Cache,不缓存不存在的文件。该方案开销最小。

      挂载时,添加lookupcache=positive(默认值lookupcache=all)字段,挂载命令如下所示:

      sudo mount -t nfs -o vers=3,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,lookupcache=positive file-system-id.region.nas.aliyuncs.com:/ /mnt
    • 方案二:关闭ECS-2的所有缓存。该方案会导致性能非常差,请根据业务实际情况选择合适的方案。

      挂载时,添加actimeo=0字段,挂载命令如下所示:

      sudo mount -t nfs -o vers=3,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,actimeo=0 file-system-id.region.nas.aliyuncs.com:/ /mnt

文件写入延时

  • 问题现象:

    ECS-1更新了文件abc,但是ECS-2立即去读它,仍然是旧的内容,这是为什么?

  • 问题原因:

    涉及如下两个原因。

    • 第一个原因:ECS-1写了abc后,不会立即flush,会先进行PageCache,依赖应用层调用fsync或者close。

    • 第二个原因:ECS-2存在文件Cache,可能不会立即去服务端取最新的内容。例如,ECS-2在ECS-1更新文件abc之时,就已经缓存了数据,当ECS-2再次去读时,仍然使用了缓存中的内容。

  • 解决方案:

    如果要保证ECS-1创建文件后,ECS-2立即就能看到它,可以使用如下方案:

    • 方案一:CTO一致性,让ECS-1或ECS-2的读写符合CTO模式,则ECS-2一定能读到最新数据。具体来说,ECS-1更新文件后,一定要执行close或者执行fsync。ECS-2读之前,重新open,然后再去读。

    • 方案二:关闭ECS-1和ECS-2的所有缓存。该方案会导致性能非常差,请根据业务实际情况选择合适的方案。

      • 关闭ECS-1的缓存。挂载时,添加noac字段,保证所有写入立即落盘。挂载命令如下所示:

        sudo mount -t nfs -o vers=3,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,noac file-system-id.region.nas.aliyuncs.com:/ /mnt
        说明
        • 如果ECS-1的写操作完成后会调用fsync,或者使用sync写,可以将上面的noac替换为actimeo=0,性能会稍好一点。

        • noac等价于actimeo=0加sync(即,强制所有写入都为sync写)。

      • 关闭ECS-2的缓存。挂载时,添加actimeo=0字段,忽略所有缓存。挂载命令如下所示:

        sudo mount -t nfs -o vers=3,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,actimeo=0 file-system-id.region.nas.aliyuncs.com:/ /mnt

相关文档