将 Azure Blob 存储与 Azure Managed Lustre 配合使用

Azure Managed Lustre 与 Azure Blob 存储集成,可简化将数据从 Blob 容器导入文件系统的过程。 也可将数据从文件系统导出到 Blob 容器以进行长期存储。 本文介绍将 Blob 集成与 Azure Managed Lustre 文件系统配合使用的概念。

要了解兼容 Blob 容器所需的要求和配置,请参阅 Blob 集成先决条件

Blob 集成概述

可在群集创建期间配置 Blob 集成,且可在群集创建后的任何时间创建导入作业。 数据导入后,可像处理其他文件系统数据一样处理该数据。 当在文件系统中创建新文件或修改现有文件时,可通过在客户端上运行 Lustre CLI 命令或使用导出作业导出数据,将这些文件导回存储帐户。

将数据从 Blob 容器导入 Azure Managed Lustre 文件系统时,仅文件名(命名空间)和元数据会导入到 Lustre 命名空间。 Blob 的实际内容在客户端首次访问时导入。 首次访问数据时会有轻微延迟,因为 Lustre 分层存储管理 (HSM) 功能会将 Blob 内容提取到文件系统中的对应文件。

可使用具有 sudo 权限的已挂载客户端通过 Lustre 的 lfs hsm_restore 命令预取 Blob 内容。 要详细了解,请参阅从 Blob 存储还原数据

Azure Managed Lustre 可与启用了分层命名空间的存储帐户以及具有非分层或扁平命名空间的存储帐户配合使用。 适用以下细微差异:

  • 对于启用了分层命名空间的存储帐户,Azure Managed Lustre 从 Blob 标头读取 POSIX 属性。
  • 对于启用分层命名空间的存储帐户,Azure Managed Lustre 从 Blob 元数据读取 POSIX 属性。 会创建一个与 Blob 容器内容同名的空文件,用于保存元数据。 此文件是 Azure Managed Lustre 文件系统中实际数据目录的同级。

从 Blob 存储导入

可在群集创建期间配置与 Blob 存储的集成,且可在群集创建后的任何时间创建导入作业

Blob 容器要求

在群集创建期间配置 Blob 集成时,必须指定两个单独的 Blob 容器:要导入的容器和日志记录容器。 要导入的容器包含要导入到 Azure Managed Lustre 文件系统的数据。 日志记录容器用于存储导入作业的日志。 这两个容器必须位于同一存储帐户中。 要详细了解 Blob 容器的要求,请参阅 Blob 集成先决条件

导入前缀

从 Blob 容器导入数据时,可选择指定一个或多个前缀,以筛选导入到 Azure Managed Lustre 文件系统的数据。 Blob 容器中与某个前缀匹配的文件名会添加到文件系统的元数据记录中。 当客户端首次访问文件时,其内容会从 Blob 容器检索并存储在文件系统中。

在 Azure 门户中,群集创建期间可在“高级”选项卡上使用“导入前缀”字段指定要从 Blob 容器导入的数据。 这些字段仅适用于初始导入作业。 群集创建后无法更改导入前缀。

对于导入作业,可在创建作业时指定导入前缀。 在 Azure 门户中,可在“导入前缀”字段中指定导入前缀。 使用 REST API 创建导入作业时,也可指定导入前缀。

指定导入前缀时请牢记以下注意事项:

  • 默认导入前缀为 /。 此默认行为会导入整个 Blob 容器的内容。
  • 如果指定多个前缀,则前缀不得重叠。 例如,如果指定 /data/data2,导入作业将失败,因为前缀重叠。
  • 如果 Blob 容器所在的存储帐户启用了分层命名空间,可将前缀视为文件路径。 路径下的项会包含在 Azure Managed Lustre 文件系统中。
  • 如果 Blob 容器位于具有非层次结构(或平面)命名空间的存储帐户中,可以将导入前缀视为与 Blob 名称开头进行比较的搜索字符串。 如果容器中 Blob 的名称以指定为导入前缀的字符串开头,则该文件在文件系统中可访问。 Lustre 是分层文件系统,Blob 名称中的 / 字符在存储到 Lustre 时会成为目录分隔符。

冲突解决模式

从 Blob 容器导入数据时,可指定如何处理 Blob 容器与文件系统之间的冲突。 此选项仅适用于为现有群集运行的导入作业。 下表显示了可用的冲突解决模式及其说明:

模式 说明
fail 如果检测到冲突,导入作业会立即失败并显示错误。
skip 如果检测到冲突,导入作业会跳过该文件。
overwrite-dirty 导入作业会计算冲突路径,以确定是否应删除并重新导入。 要详细了解,请参阅覆盖脏模式
overwrite-always 导入作业会计算冲突路径,若路径为“脏”则始终删除/重新导入,若为“干净”则释放。 要详细了解,请参阅始终覆盖模式

覆盖脏模式

overwrite-dirty 模式会计算冲突路径,以确定是否应删除并重新导入。 概括地说,overwrite-dirty 模式会检查 HSM 状态。 如果 HSM 状态为“干净”和“已存档”,即据 Lustre 判断其数据与 Blob 容器同步,则仅在需要时更新属性。 否则,将删除文件并从 Blob 容器重新导入。

检查 HSM 状态不能保证 Lustre 中的文件与 Blob 容器中的文件匹配。 如果必须确保Lustre中的文件与Blob容器中的文件尽可能接近,请使用 overwrite-always 模式。

始终覆盖模式

overwrite-always 模式会计算冲突路径,若路径为“脏”则始终删除/重新导入,若为“干净”则释放。 当需要确保文件系统始终与 Blob 容器同步时,此模式很有用。 它也是成本最高的选项,因为每个先前还原的文件在首次访问时要么被释放,要么被删除/重新导入。

错误容限

从 Blob 容器导入数据时,可以指定错误容限。 错误容限级别决定导入作业如何处理导入过程中发生的瞬态错误(例如操作系统错误或网络中断)。 需要注意的是,此上下文中的错误不指文件冲突,文件冲突由冲突解决模式处理。

导入作业提供以下错误容限选项:

  • 不允许错误 (默认值):如果导入过程中发生任何错误,导入作业立即失败。 此行为是默认值。
  • 允许错误:发生错误时导入作业继续,并记录错误。 导入作业完成后,可在日志记录容器中查看错误。

Blob 导入作业的注意事项

从 Blob 容器导入数据时,需注意以下重要事项:

  • 一次只能运行一个导入或导出操作。 例如,如果导入作业正在进行,尝试启动另一个导入作业将返回错误。
  • 导入作业可以取消。 可以取消在现有群集上启动的导入作业,或群集创建期间启动的导入作业。
  • 群集部署可能在相应导入作业完成前成功返回。 导入作业继续在后台运行。 可以通过以下方式监控导入作业的进度:
    • Azure 门户:Azure 门户显示导入作业的状态。 导航到文件系统并选择“Blob 集成”以查看导入作业状态。
    • Lustre 根目录中的文件:导入期间会在 Lustre 根目录中创建一个类似 /lustre/IMPORT_<state>.<timestamp_start> 的文件。 <state> 占位符随导入进度而变化。 导入作业成功完成后,该文件将被删除。
  • 要查看已完成导入作业的详细信息,可以检查日志记录容器。 日志记录容器包含导入作业的日志,包括导入期间发生的任何错误或冲突。
  • 如果导入作业因任何原因失败,可能无法获得导入作业的完整统计信息(如导入的文件数或冲突数)。

从 Blob 存储还原数据

默认情况下,Blob 的内容在客户端首次访问对应文件时导入到文件系统。 对于特定工作负荷和场景,可能希望在首次访问前从 Blob 容器还原数据。 可以选择预取 Blob 内容,以避免导入后首次访问 Blob 时的初始延迟。 要预取 Blob 内容,可以使用具有 sudo 权限的已挂载客户端通过 Lustre 的 lfs hsm_restore 命令实现。 以下命令将 Blob 内容预取到文件系统:

nohup find local/directory -type f -print0 | xargs -0 -n 1 sudo lfs hsm_restore &

此命令告知元数据服务器异步处理还原请求。 命令行不会等待还原完成,这意味着命令行有可能在元数据服务器上排队大量要还原的条目。 此方法可能使元数据服务器不堪重负,降低还原性能。

为避免此潜在性能问题,可以创建基本脚本,尝试遍历路径并按指定大小批量发出还原请求。 若要实现合理的性能并避免元数据服务器压倒性,建议使用从 1,000 到 5,000 个请求的批大小。

示例:创建批量还原脚本

以下示例展示如何创建脚本以批量从 Blob 容器还原数据。 创建包含以下内容的名为 file_restorer.bash 的文件:

#!/bin/bash
set -feu
set -o pipefail
main()
{
    if [ $# -lt 2 ]; then
        echo "$0 <path_to_fully_restore> <max_restores_at_a_time>"
        echo "Missing parameters"
        exit 1
    fi
    local RESTORE_PATH=$1
    local MAX_RESTORES=$2
    local FILES_LIST="/tmp/files_to_restore"
    find "$RESTORE_PATH" -type f > "$FILES_LIST"
    local TOTAL_FILES
    TOTAL_FILES=$(wc -l "$FILES_LIST")
    local RESTORE_TOTAL=0
    local RESTORE_COUNT=0
    while IFS="" read -r p || [ -n "$p" ]; do
        printf '%s\n' "$p"
        lfs hsm_restore "$p"
        ((RESTORE_COUNT++)) || true
        ((RESTORE_TOTAL++)) || true
        if (( RESTORE_COUNT >= MAX_RESTORES )); then
            while true; do
                local STATE
                STATE=$(lfs hsm_state "$p")
                RELEASED=') released exists archived'
                if ! [[ $STATE =~ $RELEASED ]]; then
                    echo "Restored $RESTORE_TOTAL / $TOTAL_FILES"
                    break
                fi
                sleep 0.2
            done
            RESTORE_COUNT=0
        fi
    done < "$FILES_LIST"
}
main "$@"

以下示例展示如何运行脚本及示例输出:

root@vm:~# time ~azureuser/file_restorer.bash /lustre/client/ 5000
Finding all files to restore beneath: /lustre/client/
Found 78100 to restore
Initiating restores in batches of 5000...
Restored 5000 / 78100
Restored 10000 / 78100
Restored 15000 / 78100
Restored 20000 / 78100
Restored 25000 / 78100
Restored 30000 / 78100
Restored 35000 / 78100
Restored 40000 / 78100
Restored 45000 / 78100
Restored 50000 / 78100
Restored 55000 / 78100
Restored 60000 / 78100
Restored 65000 / 78100
Restored 70000 / 78100
Restored 75000 / 78100
Restored 78100 / 78100
real	6m59.633s
user	1m20.273s
sys	0m37.960s

注意

目前,Azure Managed Lustre 从 Blob 存储还原数据的最大吞吐量约为 7.5GiB/秒。

使用导出作业将数据导出到 Blob 存储

可以通过创建导出作业,将数据从 Azure Managed Lustre 文件系统复制到 Azure Blob 存储的长期存储中。

导出作业期间会导出哪些文件?

从 Azure Managed Lustre 系统导出文件时,并非所有文件都会复制到创建文件系统时指定的 Blob 容器中。 导出作业适用以下规则:

  • 导出作业仅复制新文件或内容已修改的文件。 如果从 Blob 容器导入的文件在文件系统创建后未更改,导出作业不会导出该文件。
  • 仅元数据更改的文件不会导出。 元数据更改包括:所有者、权限、扩展属性和名称更改(已重命名)。
  • Azure Managed Lustre 文件系统中删除的文件在导出作业期间不会在原始 Blob 容器中删除。 导出作业不会删除 Blob 容器中的文件。
  • Blob 名称必须符合某些 命名规则,这意味着可接受的 blob 名称与可接受的 POSIX 文件名略有不同。 在导出到 blob 时,导出过程将通过正确对文件名中的特殊字符进行转义来保留这些特殊字符。 但是,违反 Blob 命名规则的文件名(例如超过最大 blob 名称长度的文件名)会导致尝试导出该文件时出错。

在活动文件系统中运行导出作业

在活动文件系统中,导出作业期间的文件更改可能导致失败状态。 此失败状态表明文件系统中的并非所有数据都能导出到 Blob 存储。 在这种情况下,可以通过创建新的导出作业来重试导出。 新作业仅复制先前作业未复制的文件。

在具有大量活动的文件系统中,重试可能会多次失败,因为文件经常发生更改。 若要验证文件是否已成功导出到 Blob 存储,请检查相应 Blob 上的时间戳。 作业完成后,还可以查看部署时配置的日志记录容器,以查看导出作业的详细信息。 日志记录容器提供关于哪些文件失败及其失败原因的诊断信息。

如果准备停用群集并希望向 Blob 存储执行最终导出,应确保在启动导出作业前停止所有 I/O 活动。 此方法通过避免文件系统活动导致的错误,帮助确保所有数据都被导出。

导出文件的元数据

将文件从 Azure Managed Lustre 文件系统导出到 Blob 容器时,会保存额外元数据,以简化将内容重新导入文件系统的过程。

下表列出了 Lustre 文件系统中作为键值对保存在 Blob 元数据中的 POSIX 属性:

POSIX 属性 类型
owner 整数 (int)
group 整数 (int)
permissions 八进制或 rwxrwxrwx 格式;支持粘滞位。

目录属性保存在空 Blob 中。 此 Blob 与目录路径同名,并在 Blob 元数据中包含以下键值对:hdi_isfolder : true

在使用容器为新 Lustre 群集水化之前,可以手动修改 POSIX 属性。 使用前述键值对编辑或添加 Blob 元数据。

导出作业的注意事项

使用导出作业导出数据时,需注意以下重要事项:

  • 一次只能运行一个导入或导出操作。 例如,如果导出作业正在进行,尝试启动另一个导出作业将返回错误。

使用 AzCopy 或存储资源管理器复制 Lustre Blob 容器

可以使用 AzCopy 或存储资源管理器移动或复制 Lustre 使用的 Blob 容器。

对于 AzCopy,可以通过添加以下标志包含目录属性:

--include-directory-stub

包含此标志可在传输期间保留目录 POSIX 属性,例如 ownergrouppermissions。 如果在 azcopy 存储容器上使用 但不包含此标志,或标志设置为 false,则传输中将包含数据和目录,但目录不会保留其 POSIX 属性。

在存储资源管理器中,通过选择“传输”并选中“包含目录存根”复选框,可以在“设置”中启用此标志。

显示在存储资源管理器传输期间如何包含目录存根的屏幕截图。

后续步骤