读写访问文件类问题

当您访问文件系统中的文件时,文件系统中的文件会受到某些限制影响,导致文件操作错误、挂载点无响应或访问无响应等。您可以在本文中查找一些常见文件操作错误、文件属主、数据不同步或访问无响应的解决方案。

并发访问同一文件时,服务器端出现无响应35s现象,该如何处理?

原因:当前Linux SMB内核驱动有缺陷,会造成在使用vers=2.1或者3.0挂载时,在某些并发场景不能发出服务器端期待的SMB BreakAck协议包,导致服务器端无响应35s。

解决方案一:挂载文件系统时,使用vers=2.0协议。

解决方案二:执行以下操作。

  1. 在加载CIFS模块时,禁用oplocks,执行以下命令。

    # modprobe cifs enable_oplocks=0

  2. CIFS模块加载完成时,禁用oplocks,执行以下命令。

    # echo 0 > /sys/module/cifs/parameters/enable_oplocks

  3. 检查oplocks的状态,执行以下命令。

    # cat /sys/module/cifs/parameters/enable_oplocks

    输出结果中,Y代表启用(enabled)。N代表禁用(disabled)。

    说明
    • 为了使以上的修改生效,请卸载并重新挂载SMB协议文件系统。

    • 如果您想使以上的修改永久生效,请创建文件/etc/modprobe.d/cifs.conf并添加命令行options cifs enable_oplocks=0

为什么无法创建符号链接文件?

问题原因

Linux挂载SMB协议文件系统时没有选择mfsymlinks选项,或者使用了2.0协议版本挂载。

解决方案

Linux挂载SMB协议文件系统时,使用2.13.0协议版本并添加mfsymlinks选项。挂载命令示例如下,示例中的参数说明,请参见SMB(Linux)挂载命令参数说明

sudo mount -t cifs //file-system-id.region.nas.aliyuncs.com/myshare /mnt -o vers=2.1,guest,uid=0,gid=0,dir_mode=0755,file_mode=0755,mfsymlinks,cache=strict,rsize=1048576,wsize=1048576

为什么SMB协议文件系统挂载点无响应?

问题原因

Linux内核为3.10.0-514之前的Linux分发版中,SMB内核驱动在并发场景有时会crash(内核stack如下所示),导致挂载点无法被访问。内核日志中有如下类似信息:

...
[<ffffffffc03c9bc1>] cifs_oplock_break+0x1f1/0x270 [cifs]
[<ffffffff810a881a>] process_one_work+0x17a/0x440
[<ffffffff810a8d74>] rescuer_thread+0x294/0x3c0
...

解决方案

  • 使用cache=none重新挂载(性能会受影响)。

  • 升级云服务器ECS(Linux)的操作系统。

拷贝大文件时报"cp: error writing '</path/to/file>': Bad file descriptor",该如何处理?

问题原因

网络或者后端有临时小故障发生,某些Linux分发版(如Suse)的SMB客户端功能较弱,不能很好的支持这种故障切换。

解决方案

建议选用NAS SMB推荐的Linux版本,NAS SMB支持的Linux操作系统版本如下表所示:

操作系统类型

操作系统版本

CentOS

CentOS 7.6 64位:3.10.0-957.21.3.el7.x86_64及以上

Alibaba Cloud Linux

Alibaba Cloud Linux 2.1903 64位:4.19.43-13.2.al7.x86_64及以上

Debian

Debian 9.10 64位:4.9.0-9-amd64及以上

Ubuntu

Ubuntu 18.04 64位:4.15.0-52-generic及以上

OpenSUSE

OpenSUSE 42.3 64位:4.4.90-28-default及以上

SUSE Linux

Enterprise Server 12 SP2 64位:4.4.74-92.35-default及以上

CoreOS

CoreOS 2079.4.0 64位:4.19.43-coreos及以上

为什么写入文件系统的中文字符在客户端显示为乱码?

问题现象

LinuxWindows客户端向NAS文件系统写入的中文字符(文件名、内容等)在另一个平台客户端显示为乱码。

问题原因

Windows客户端中文编解码默认使用GBK字符集,Linux客户端中文编解码默认使用UTF-8字符集,写入NAS文件系统的数据为平台对应字符集编码后的内容。在另一平台读取时需要进行解码,因为两个平台字符集并不兼容,故无法正常解码,导致显示内容为不可识别的乱码。

解决方案

建议您使用Windows客户端挂载SMB协议NAS文件系统,Linux客户端挂载NFS协议文件系统,从而规避平台不兼容问题。

为什么Windows挂载NFS协议文件系统创建和打开文件时速度缓慢?

问题原因

Windows上使用NFS协议实例,会存在大小写敏感和大小写不敏感的兼容性问题,在目录里创建文件的性能随着目录规模增大而明显下降,原因是每次创建一个文件都需要对目录进行遍历,当目录规模达到10万级别时,目录遍历一次需要10秒钟以上。

解决方案

修改挂载参数,增加-o casesensitive=yes字段,避免目录遍历。挂载命令如下所示:

mount -o nolock -o mtype=hard -o timeout=60 -o casesensitive=yes \\file-system-id.region.nas.aliyuncs.com\! Z:

请根据实际情况替换盘符Z和挂载点地址file-system-id.region.nas.aliyuncs.com

说明

启用大小写敏感选项和windows的原生语义是冲突的,使用上需要保证NFS目录中不出现因为大小写出现名字冲突(例如,同时出现a.txtA.TXT),修改挂载参数可能会有不确定的影响,建议使用SMB NAS。

如何解决Windows客户端对NFS协议文件系统中的文件重命名时返回的invalid device错误?

如果NFS协议文件系统是挂载在文件系统的子目录上,当执行文件重命名操作时,会返回的invalid device错误,请您将文件系统挂载在文件系统的根目录上。具体操作,请参见步骤二:挂载NFS协议的通用型NAS文件系统

如何解决在NFS协议文件系统中创建文件延迟问题?

  • 问题现象:

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

  • 问题原因:

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

  • 解决方案:

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

    • 方案一:关闭ECS-2Negative 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

如何解决向NFS协议文件系统中写入数据延迟问题?

  • 问题现象:

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

  • 问题原因:

    涉及如下两个原因。

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

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

  • 解决方案:

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

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

    • 方案二:关闭ECS-1ECS-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=0sync(即,强制所有写入都为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

为什么两台ECS实例在查询NAS文件系统中同一文件时,文件的属主不同?

在文件系统中,标识用户身份的不是用户名,而是UIDGID,您在ECS实例查询的属主用户名是由UID信息转换得到的,当同一UID在不同ECS实例中信息转换为不同的用户名,则会被认为是不同的属主。

例如,在ECS实例1中使用admin用户创建文件admin_on_machine1,在ECS实例2中使用admin用户创建文件admin_on_machine2。在ECS实例1中执行ll命令,查看已创建的文件,如下图所示:faq001ECS实例2中执行ll命令,查看已创建的文件,如下图所示:faq002通过两台ECS实例查询可以看到,同一文件的属主用户名不一致。

然后,分别执行id命令,查询admin用户信息。如下图所示ECS实例1admin用户的UID505:faq04如下图所示ECS实例2admin用户的UID2915:faq005如下图所示执行stat admin_on_machine1 admin_on_machine2命令,查询到两个文件属于不同的UID:faq

如何避免多进程或多客户端并发写同一日志文件可能出现的异常?

问题现象

文件存储NAS为多客户端提供了统一命名空间的文件共享读写能力,但在多进程或多客户端并发写同一个文件的场景中(典型的例如并发写同一个日志文件),各进程分别维护了独立的文件描述符及写入位置等上下文信息,而NFS协议本身并没有提供Atomic Append语义的支持,因此可能会出现写覆盖、交叉、串行等异常现象。

解决方案

  • (推荐)不同进程或不同客户端写入同一文件系统的不同文件中,后续分析处理时再进行归并,这个方案能够很好地解决并发写入导致的问题,同时无需使用文件锁,不会对性能造成影响。

  • 对于并发追加写同一个文件(如日志)的场景,可以使用文件锁+seek机制来保证写入的原子性和一致性。但是文件锁+seek是一个比较耗时的操作,可能会对性能产生显著的影响。下面将对这种方式进行一个简单的介绍,以供参考。

flock+seek使用方法

由于NFS协议本身没有提供对Atomic Append语义的支持,因此当并发写入同一文件末尾(如日志)时,很可能会出现相互覆盖的情况。在Linux中,通过使用flock+seek的方式,可以在NFS协议文件系统上做到模拟Atomic Append,对并发追加写入同一文件提供保护和支持。

使用方式如下:

  1. 调用fd=open(filename, O_WRONLY | O_APPEND | O_DIRECT) 以追加写的方式打开文件,并且指定 O_DIRECT(直写,不通过 Page Cache),获得文件描述符fd。

  2. 调用flock(fd, LOCK_EX|LOCK_NB)尝试获取文件锁,如果获取失败(如锁已被占用)则会返回错误,此时可以继续重试或进行错误处理。

  3. 文件锁获取成功后,调用lseek(fd, 0, SEEK_END)将fd当前的写入偏移定位到文件末尾。

  4. 执行正常的write操作,此时写入位置应该是文件的末尾,并且由于有文件锁的保护,不会出现并发写入相互覆盖的问题。

  5. 写操作执行完成后,调用flock(fd, LOCK_UN)释放文件锁。

使用Linux操作系统在NFS协议文件系统中执行ls命令时,为什么会返回523错误?

问题现象

Linux客户端在NFS协议文件系统中执行ls命令时,返回如下报错信息。29

原因分析

对文件系统目录下执行ls时,该目录有并发的rename操作,则会返回523错误。

解决方案

稍等重试即可。如果还出现类似报错,请联系NAS技术支持进行咨询。

为什么SMB协议文件系统挂载有时候连接不上?

问题现象

当您混用NFSSMB协议文件系统,导致第一次通过net use命令挂载NFS协议文件系统连接失败后,挂载正确的SMB协议文件系统也会出现问题。

解决方案

检查确保挂载正确的文件系统后,暂时停止挂载,5分钟后再次挂载。如果还失败,请联系NAS技术支持进行咨询。

为什么Administrator能看见挂载的SMB目录,其他用户看不到?

该现象是由于Windows的用户隔离机制造成的。即一个登录用户的已挂载目录在另一个用户的登录界面中不会显示。

要实现多用户的共享,需要创建一个目录链接。比如C盘下创建一个myshare,命令如下:

mklink /D C:\myshare \\xxxxxxx-xxxx.cn-beijing.nas.aliyuncs.com\myshare\

如何解决Linux挂载SMB协议文件系统性能不佳?

如果SMB协议文件系统性能不佳,您可以从以下方面进行排查。

  • 原因1:SMB单个文件系统的吞吐能力与存储量是相联系的。单文件系统的吞吐(读+写)上限与当前存储量呈线性关系。

    解决方案:使用fio工具来测试SMB协议文件系统性能。具体操作,请参见NAS性能测试

  • 原因2:云服务器ECS(Linux)的单机网络带宽较小。

    解决方案:使用多个云服务器ECS(Linux)达到文件系统的总体预期性能。

  • 原因3:禁用了SMB协议文件系统的客户端缓存。

    解决方案:在挂载SMB协议文件系统时,cache=none表示禁用缓存,默认或者cache=strict表示使用缓存;您可以通过sudo mount | grep cifs命令检查所用的选项是否正确。

  • 原因4:没有设置合适的SMB客户端的I/O大小。

    解决方案:根据业务需求调整rsizewsize,默认值:1048576。

  • 原因5:云服务器ECS(Linux)的CPU或内存的规格过低,或被其它业务占用过多。

    解决方案:选择合适的云服务器ECS(Linux)规格、检查系统其它应用资源,确保系统满足CPU和内存要求。您可以通过top命令检查系统CPU、MEM使用情况。

  • 原因6:挂载时使用了atime选项。

    解决方案:如果您的业务不是对文件的访问时间(atime)极为敏感,请不要在挂载时使用atime选项。

  • 原因7:遇到大量小文件频繁读、少量写但需要写时通知的WebServer场景。

    解决方案:您可以在客户端配置该WebServer(如Apache)产品特定的缓存机制或者联系阿里云NAS团队开通WebServer场景加速功能。

Linux访问SMB协议文件系统时,报Permission denied错误,该怎么解决?

原因:Linux管理员在挂载时使用了不正确的UID、GID、file_mode、dir_mode。

解决方案:检查是否正确设置了UID、GID、file_mode、dir_mode等挂载选项。更多信息,请参见挂载SMB协议文件系统

如何变更SMB协议文件系统中文件名大小写?

SMB协议文件系统对文件名大小写不敏感,和Windows系统保持一致。但在文件名大小写改名这个场景暂时没有支持。

您可以先从大写文件名改成一个其它名字的文件,再改成小写文件名,反之亦然。

为什么不能改变文件owner,文件和目录mode?

现在暂时不支持动态改变,只能在挂载时指定。更多信息,请参见挂载SMB协议文件系统

后缀为.nfs的文件是怎么产生的?如何删除?

在应用程序已经打开某文件时,如果删除该文件,则会产生后缀为.nfs的临时文件。当访问进程关闭后,该临时文件将自动被删除。

访问NAS文件系统目录下的文件时,返回bind conn to session failed on NFSv4 server该如何解决?

  • 问题原因

    由于文件存储NAS不支持NFSv4.1协议,当您使用NFSv4.1协议挂载文件系统时产生该报错。

  • 解决方案

    请您根据业务场景选择使用NFSv3NFSv4.0协议重新挂载文件系统。更多信息,请参见挂载文件系统场景说明

如何处理多个ECS实例挂载同一NFS协议文件系统出现数据不同步的情况?

问题现象

NAS在多挂载点的情况下,不同客户端进行实时同步时存在较长时间延迟的问题。

问题原因

操作系统kernel默认对文件和目录的属性进行维护,将其生成一份metadata缓存,以减少NFSPROC_GETATTR远程过程调用的需求。

解决方案

执行以下挂载命令,禁用文件和目录属性的缓存。

mount -t nfs4 -o noac file-system-id.region.nas.aliyuncs.com:/ /mnt

其中,file-system-id.region.nas.aliyuncs.com为文件系统挂载点地址,请根据实际值替换;/mnt :当前服务器上待挂载的本地路径,请根据实际情况替换路径。

为什么卸载旧NAS并重新挂载新NAS后,容器Pod仍将数据写入旧NAS?

问题原因

NAS挂载到ECS并通过本地存储卷(HostPath)映射的方式将NAS的挂载目录映射到容器时,容器中的挂载信息独立于ECS,ECS后续对NAS挂载目录进行卸载或者挂载新NAS时,已经启动的容器仍然会使用其启动时挂载的旧NAS。

解决方案

ECS上重新挂载新NAS后,重启容器Pod。

服务器重启或停机后,为什么NAS里的文件看不到了?

如果文件系统仍存在,此原因一般是服务器未配置自动挂载NAS。

如何手动再次挂载NAS请参考挂载文件系统场景说明

如需实现重启后NAS自动挂载功能,请参考以下文档:

为什么Linux挂载SMB协议文件系统迁移和复制文件时速度缓慢?

如果已经排除了文件系统本身的性能问题,则可能原因是您没有使用并发式迁移或复制文件。您可以通过以下开源工具进行迁移或复制。

  • GNU Parallel

    根据系统资源,选择合适的线程数。示例:find * -type f | parallel --will-cite -j 10 cp {} /mnt/smb/ &

  • Fpart

  • Fpsync

  • multi

为什么向文件系统写入数据时,返回Disk quota exceeded错误信息?

  • 问题原因

    目标目录的使用量或文件数超过了设定的用户配额限制,因此导致写入操作(包括增加文件长度、创建文件、目录、移动文件到目录等操作)失败,返回类似Disk quota exceeded的错误信息。

  • 解决方案

    1. 建议您尽快清理数据释放空间,或者提升该目录的容量限制。具体操作,请参见编辑单条用户配额

    2. 清理完成后,建议先对配额的目录执行测试性的写操作(例如,创建并写数据到测试文件)来触发配额缓存的异步刷新,判断这些测试性写操作能够成功,然后再重新启动业务。

如何解决访问NFS协议文件系统时,返回无访问权限问题?

您可参照以下操作步骤为系统配置AnonymousGIDAnonymousUID。

  1. 登录挂载文件系统的ECS服务器。

  2. 打开命令提示符,执行regedit命令,进入注册表编辑器页面。

  3. 选择HKEY_LOCAL_MACHINE > SOFTWARE > Microsoft > ClientForNFS > CurrentVersion > Default

  4. 右击空白处,选择新建 > DWORD(32位)值,并创建以下两个注册表项。

    • AnonymousGID,值为0

    • AnonymousUID,值为0Default注册表

  5. 重启ECS实例。

  6. 重新挂载NFS协议的通用型NAS文件系统。

    mount -o nolock -o mtype=hard -o timeout=60 \\file-system-id.region.nas.aliyuncs.com\! Z:

    请根据实际情况替换盘符Z:和挂载点域名file-system-id.region.nas.aliyuncs.com

  7. 执行mount检查是否挂载成功。

    挂载完成后,回显信息必须包括mount=hard、locking=no以及timeout参数>=10,否则说明挂载有问题。

    检查UID和GID

能否通过执行chown修改NAS根目录权限?

当前不允许用户修改NAS根目录权限。

如果您希望控制本地挂载的NAS目录的权限,可以考虑使用子目录挂载的方式。例如,如果将NAS根目录挂载到本地的/data目录,将无法通过chown修改/data目录的属主和属组。如果将NAS子目录(需提前创建)挂载到本地的/data目录,即可以通过chown修改/data目录的属主和属组。需要注意的是,在NAS中创建子目录时,仍需要先挂载NAS根目录后创建。关于如何创建子目录并完成挂载,请参见如何在Linux系统中创建NAS子目录并完成挂载?