다음을 통해 공유

BlobFuse 的限制和已知问题

本文介绍 BlobFuse 的限制和已知问题。

具备高级性能的块 Blob 帐户中的权限设置操作

高级性能块 Blob 帐户不支持访问控制列表(ACL)。 但是,即使这些操作在这些帐户中没有效果,BlobFuse 也会返回操作成功 chmod

与 fuse 驱动程序交互所需的管理员权限

在容器上装载 BlobFuse 时,需要SYS_ADMIN特权才能与 fuse 驱动程序交互。 如果创建没有此权限的容器,装载作将失败。 下面是一个示例命令,用于生成具有所需权限的 Docker 容器:

docker run -it --rm --cap-add=SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined <environment variables> <docker image>

可并行装载的容器数限制

使用 mount all 此命令时,系统可能会限制可以并行装载的容器数(通常超过 100 个容器时)。 若要增加此系统限制,请使用以下命令:

echo 256 | sudo tee /proc/sys/fs/inotify/max_user_instances

Syslog 和保护敏感信息

默认情况下,BlobFuse 会将日志发送到 syslog。 在某些情况下,默认设置可能会将文件路径记录到 syslog。 如果此信息很敏感,请关闭日志记录或将日志级别设置为 log_err

不支持的文件系统操作

BlobFuse 不支持以下文件系统操作。

  • mknod
  • link (硬链接 API)
  • setxattr
  • getxattr
  • listxattr
  • removexattr
  • access
  • lock
  • bmap
  • ioctl
  • poll
  • write_buf
  • read_buf
  • flock
  • fallocate
  • copyfilerange
  • lseek

不支持的文件系统工作流

BlobFuse 不支持以下文件系统工作流:

  • 创建管道、FIFO 队列和设备文件
  • 文件或目录的扩展属性 (XAttrs)
  • 文件或目录的硬链接
  • 任何文件或目录的上次访问时间和上次更改时间
  • 扩展属性(x-attrs)操作
  • lseek() 对目录句柄执行操作(未引发错误,但无法按预期工作)

特定命令限制

  • mkfifo:BlobFuse 不支持 FIFO 创建,并返回“未实现的函数”错误。
  • chown:Azure 存储不支持更改所有权,因此 BlobFuse 不支持此作。

某些文件系统操作的行为更改

以下文件系统操作在 BlobFuse 中行为发生了变化:

  • fsync():强制从本地缓存中删除文件并使属性缓存失效。 此操作强制 BlobFuse 在下一次打开调用该文件时刷新文件的元数据和内容。
  • fsyncdir():以递归方式使该目录的元数据失效。 此作强制 BlobFuse 在内核的下一个元数据查询中刷新该目录的任何子项的元数据。

不支持的方案

  • 重叠装载路径:BlobFuse 不支持重叠装载路径。 运行 BlobFuse 的多个实例时,请确保每个实例都有唯一且不重叠的装入点。

  • 与 NFS 共存:BlobFuse 不支持在同一装载路径上与 NFS 共存。 在这种情况下,行为是未定义的。

  • 平面命名空间存储帐户:对于具有平面命名空间的存储帐户,通过其他方式上传数据时,BlobFuse 需要容器中存在特殊的目录标记文件。 例如,如果你有一个 Blob A/B/c.txt,则应该存在用于 AA/B 的特殊标记文件。 为了克服这一要求,BlobFuse 使用 ListBlob API 而不是 GetBlobProperties API 进行 ls 操作,尽管 ListBlob 的费用更高。

  • 虚拟目录配置:对于具有平面命名空间的存储帐户,可以使用 --virtual-directory=false CLI 标志或 virtual-directory=false 节下 azstorage 的选项从 ListBlob API 切换到 GetBlobProperties API。 但是,如果没有特殊的目录标记,BlobFuse 无法标识目录。 一种可能的解决方法是通过门户手动创建目录标记文件,或从 BlobFuse 运行 mkdirAA/B 命令。 有关详细信息,请参阅此 GitHub 问题

  • 非 HNS 帐户:在非 HNS(分层命名空间)帐户上,不允许进行 chmod 操作,且 BlobFuse 在这种情况下返回成功,而无需实际执行操作。

重大变化

直接输入/输出和缓存行为

为了提高从文件中重复读取的性能,BlobFuse 利用内核缓存。 内核页缓存只能打开或关闭,但不能由基于超时的到期时间控制。 此限制在要将最新文件从容器同步到本地装载的环境中会产生问题。 只要内核缓存有效,内核就不会从基础文件系统(BlobFuse)请求新内容。

若要禁用内核数据缓存,请使用 direct_io 此选项。 除了数据缓存,内核还维护元数据缓存。 此元数据缓存由使用attribute_timeoutentry_timeoutnegative_timeout配置的超时驱动。 如果需要立即刷新内容,请将所有这些超时设置为 0 以及使用 direct_io。 使用这些配置参数,将禁用内核级缓存。 此外,还必须禁用 BlobFuse 级缓存(file_cacheattr_cache),其超时设置为 0。

若要禁用所有缓存,需要配置大约七个参数。 为了简化此过程,版本 2.4.0 中的自动配置功能将在使用 direct_io 此选项时禁用所有内容。 此更改简化了客户体验,以往因配置过于复杂而导致的问题和投诉得到了改进。

但是,此更改会禁用内核和 BlobFuse 缓存,因此 BlobFuse 开始对存储进行更多调用。 此更改对客户产生成本影响,其中调用次数越高不仅会降低性能,而且会增加成本。 为了解决此问题,版本 2.5.0 引入了一个名为的新 CLI 参数,该参数 disable-kernel-cache仅禁用内核级数据和元数据缓存。 然后,可以通过设置文件缓存超时和属性缓存超时值来控制 BlobFuse 级缓存。 此配置允许根据应用程序需求刷新内容。 例如,如果你的应用程序对每 5 秒刷新一次内容没有问题,那么将文件和属性缓存超时时间设置为 5 秒,并使用这个新的 CLI 标志。 使用此配置,应用程序每隔 5 秒刷新一次内容,同时控制成本。

与其他 API 写入的数据同步

BlobFuse 支持读取和写入操作。 但是,使用其他 API 或通过其他 BlobFuse 挂载写入存储的数据,无法保证进行持续同步。 为了数据完整性,请勿从多处修改同一个 Blob,尤其不要同时进行。 如果一个或多个应用程序同时尝试写入同一文件,则结果可能意外。 根据多个写入作的时间以及每个作缓存的新鲜度,结果可能是最后一个写入器获胜且以前的写入丢失,或者更新的文件未处于预期状态。

另请参阅