本文介绍在使用ossfs时遇到的一些问题案例及解决方案。

ossfs 的报错都会有明显的message。排查问题时,需要收集这些message,并根据message判断问题。例如socket建连失败、HTTP响应的状态码4xx、5xx等,使用前先将debug-log功能开启。
  • 403错误是因权限不足,导致访问被拒绝。
  • 400错误是用户的操作方法有误。
  • 5xx错误一般和网络抖动以及客户端业务有关系。
说明 如果使用ossfs不满足业务需求时,可以考虑使用 ossutil
  • ossfs是将远端的OSS挂载到本地磁盘,如果对文件读写性能敏感的业务,不建议使用ossfs 。
  • ossfs的操作不是原子性,存在本地操作成功,但OSS远端操作失败的风险。

案例:使用yum/apt-get安装ossfs时出现“conflicts with file from package fuse-devel”报错

问题分析:这种问题是系统中存在老版本的fuse,与ossfs里的依赖版本冲突了。

解决方案:请先使用相关的包管理器卸载fuse,再重新安装ossfs。

案例:安装ossfs时出现“fuse: warning: library too old, some operations may not work”报错

问题分析:出现错误的原因是ossfs编译时所使用的libfuse版本比运行时链接到的libfuse版本高,这往往是用户自行安装了libfuse导致的。CentOS-5.x和CentOS-6.x系统中,阿里云提供的ossfs安装包里包含了libfuse-2.8.4,如果在运行的时候环境中有libfuse-2.8.3,并且ossfs被链接到了旧版本的fuse上,就会出现上述错误。

您可以通过ldd $(which ossfs) | grep fuse命令确认ossfs运行时链接的fuse版本,如结果是/lib64/libfuse.so.2,那么通过ls -l /lib64/libfuse*命令可以看到fuse的版本。

解决方案:让ossfs链接到正确的版本。
  1. 通过rpm -ql ossfs | grep fuse命令找到libfuse的目录。
  2. 如果结果是/usr/lib/libfuse.so.2,则通过LD_LIBRARY_PATH=/usr/lib ossfs …命令运行ossfs。

案例:安装依赖库fuse报错

问题分析:这种问题是fuse的版本不满足ossfs的要求。

解决方案:手动下载fuse最新版本安装,不要使用yum安装。详情请参见fuse

案例:挂载时出现“ossfs: unable to access MOUNTPOINT /tmp/ossfs: Transport endpoint is not connected”报错

问题分析:未创建该目录导致的。

解决方案:先创建对应的目录,之后再进行挂载操作。

案例:挂载时出现“fusermount: failed to open current directory: Permission denied”报错

问题分析:这是fuse的一个Bug,它要求当前用户对当前目录(非挂载目录)有读权限。

解决方案:通过cd命令切换到到一个有读权限的目录,再运行ossfs命令。

案例:挂载时出现“ossfs: MOUNTPOINT directory /tmp/ossfs is not empty. if you are sure this is safe, can use the 'nonempty' mount option”报错

问题分析:当默认情况下,ossfs只能挂载到空目录下。当试图挂载到非空目录下时,会提示上述错误。

解决方案:切换到一个空目录下重新挂载。如果还是需要挂载到该目录下,挂载时增加 -ononempty 参数。

案例:挂载成功后,ls目录时出现“operation not permitted”报错

问题分析:请检查您的Bucket中,是否存在名称含有不可见字符的Object。文件系统对文件名和目录名有严格的限制,因此会收到上述错误。

解决方案:用其他工具对这些Object重命名后,ls就能正确显示目录内容了。

案例:ossfs 偶尔出现断开的情况

问题分析:
  1. 开启ossfs的debug日志,加上-d -o f2参数,ossfs会把日志写入到系统/var/log/message
  2. 分析日志,发现ossfs在listbucket、listobject申请内存过多,触发了系统的oom。
    说明 listobject是发起http请求到OSS获取文件的meta信息,如果客户的文件很多,ls会消耗系统大量内存来获取文件的meta。
解决方案:
  • 通过-omax_stat_cache_size=xxx参数增大stat cache 的 size,这样第一次ls会较慢,但是后续的ls速度会提高,因为文件的元数据都在本地cache中。这个值默认是1000,约消耗4MB内存,请根据您机器内存大小调整为合适的值。
  • ossfs在读写时会占用磁盘写大量的temp cache ,和Nginx差不多,可能会导致磁盘可用空间不足,需要经常清理。
  • 使用ossutil替代ossfs,非线上敏感业务可以使用ossfs ,要求可靠性、稳定性的建议使用ossutil。

案例:访问出现“THE bucket you are attempting to access must be addressed using the specified endpoint”报错

问题分析:根据Message判断,错误原因是Endpoint指定错误,有以下两种可能性:
  • Bucket和Endpoint不匹配。
  • Bucket所属UID和实际的Accesskey对应的UID不一致。

解决方案:确认正确的配置信息并修改。

案例:通过cp命令拷贝数据时出现“input/output error”报错

问题分析:input/output error都是捕获到系统磁盘的错误而产生的报错,可以查看出现报错时,磁盘读写是否存在高负载的情况。

解决方案:可以增加分片参数,控制文件读写。使用ossfs -h命令可以查看分片参数。

案例:使用rsync同步时出现 “input/output error”报错

问题分析:ossfs与rsync同步使用本身会出现问题。此案例中,用户是对一个141GB的大文件进行cp操作,使磁盘读写处于非常高的负载状态,从而产生此报错。

解决方案:如果想要将oss文件下载到本地ECS ,或者本地上传到ECS ,可以通过ossutil的分片上传、下载进行操作。

案例:上传大文件时出现“there is no enough disk space for used as cache(or temporary)”报错

问题分析:ossfs上传大文件时,是通过分片来上传的。分片大小默认为10MB,分片最大数量为1000个。

ossfs在上传文件时会写一些临时缓存文件到 /tmp目录下,在写这些文件之前需要先判断 /tmp目录所在的磁盘可用空间是否小于用户上传的文件总量,若判断磁盘可用空间小于用户上传文件总量,就会出现本地磁盘可用空间不足的报错。以下场景会导致磁盘可用空间不足的报错:
  • 场景一:磁盘可用空间本身小于用户上传文件总量。例如磁盘可用空间是200GB,上传的文件是300GB。
  • 场景二:分片大小和上传线程数量的参数设置错误。例如磁盘可用空间是300GB,需上传的文件是100GB。因操作错误,multipart_size被设置成了100GB,上传线程数量是5。此时ossfs判断上传的文件就是100GB*5=500GB,超过磁盘安全空间了。
解决方案:
  • 场景一:增大磁盘可用空间。
  • 场景二:分片大小正常单位是MB,最大数量是1000,不要将分片大小设置过大。

案例:挂载成功后,touch文件时出现403报错

问题分析:403错误通常是访问权限问题导致的。以下情况会导致touch一个文件出现403报错。
  • 该文件为归档类型文件,touch时会出现403报错。
  • 使用的Accesskey无该存储空间的操作权限。
解决方案:
  • 归档类型文件问题:将文件解冻后访问。
  • 权限问题:为使用的Accesskey对应的账号配置正确的权限。

案例:使用ossfs上传到OSS的文件的Content-Type全是application/octet-stream

问题分析:上传文件时,ossfs通过查询/etc/mime.types中的内容来设置文件的Content-Type。当该文件不存在时,默认设置为application/octet-stream。

解决方案:请检查这个文件是否存在,如果不存在,则需要添加。
  • 通过命令自动添加mime.types文件
    • Ubuntu系统

      使用sudo apt-get install mime-support命令添加。

    • CentOS系统

      使用sudo yum install mailcap命令添加。

  • 手动添加mime.types文件
    1. 创建mime.types文件
      vi /etc/mime.types
    2. 添加需要的格式,每种格式一行,每行格式为application/javascript js
添加完成后,需要重新挂载OSS。

目录下有非常多的文件时,为什么ls该目录很慢

问题分析:假设一个目录下有N个文件,那么ls该目录至少需要N次OSS http requests。在文件非常多的时候,这可能造成严重的性能问题。

解决方案: 通过-omax_stat_cache_size=xxx参数增大stat cache的size,这样第一次ls会较慢,但是后续的ls就快了,因为文件的元数据都在本地cache中。这个值默认是1000,大约消耗4MB内存,请根据您机器内存大小调整为合适的值。

为什么用ossfs看到的文件信息(例如大小)与其他工具看到的不一致

问题分析:ossfs默认会缓存文件的元信息(包括大小/权限等),这样就不需要每次ls的时候向OSS发送请求,加快速度。 如果用户通过其他程序(例如SDK/官网控制台/ossutil等)对文件进行了修改,由于缓存的关系,ossfs没有及时更新,导致与其他工具看到的文件信息不一致。

解决方案:可以在挂载的时候加上参数-omax_stat_cache_size=0,禁用元数据缓存功能。每次ls时,都会向OSS 发送请求,获取最新的文件信息。

在ECS上挂载OSS,如何避免因后台程序扫描文件而产生费用

问题分析:程序扫描ossfs挂载的目录,会转换成向OSS的请求。如果请求次数很多,会产生费用。

解决方案:可以通过auditd工具查看是哪些进程扫描了OSS挂载的目录。具体步骤如下:
  1. 安装auditd并启动。
    sudo apt-get install auditd
    sudo service auditd start
  2. 将OSS挂载的目录设置为监视目录,例如挂载目录为/mnt/ossfs
    auditctl -w /mnt/ossfs
  3. 在auditlog中查看是哪些进程访问了这个目录。
    ausearch -i | grep /mnt/ossfs
  4. 修改参数,跳过程序扫描。
    例如通过auditlog查到是 updatedb 扫描了所挂载的目录,可以通过修改 /etc/updatedb.conf让它跳过。具体做法是:
    1. RUNEFS =后面加上fuse.ossfs
    2. PRUNEPATHS =后面加上挂载的目录。