将Azure Blob 存储与 Azure 托管 Lustre 配合使用

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

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

Blob 集成概述

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

将数据从 Blob 容器导入 Azure 托管 Lustre 文件系统时,只会将文件名(命名空间)和元数据导入 Lustre 命名空间。 首次由客户端访问时导入 Blob 的实际内容。 首次访问数据时,Lustre 分层存储管理(HSM)功能将 Blob 内容拉取到文件系统中的相应文件时,会稍有延迟。

可以使用 Lustre 的 lfs hsm_restore 命令从具有 sudo 功能的已装载客户端预提取 Blob 的内容。 若要了解详细信息,请参阅 从 Blob 存储还原数据。

Azure 托管 Lustre 适用于启用了分层命名空间的存储帐户,以及具有非分层命名空间或平面命名空间的存储帐户。 以下细微差异适用:

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

从 Blob 存储导入

可以在创建群集期间配置与 Blob 存储的集成,并在创建群集后随时创建导入作业

Blob 容器要求

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

导入前缀

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

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

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

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

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

冲突解决模式

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

“模式” 说明
fail 如果检测到冲突,导入作业将立即失败,并出现错误。
skip 如果检测到冲突,导入作业将跳过该文件。
overwrite-dirty 导入作业将评估冲突的路径,以查看是否应将其删除并重新导入。 若要了解详细信息,请参阅 覆盖脏模式
overwrite-always 导入作业会评估一个冲突的路径,如果它很脏,则始终删除/重新导入;如果它干净,则释放。 若要了解详细信息,请参阅 覆盖始终模式

覆盖脏模式

overwrite-dirty 模式将评估一个冲突的路径,以查看是否应将其删除并重新导入。 在高级别, overwrite-dirty 模式会检查 HSM 状态。 如果 HSM 状态为 Clean and Archived,这意味着其数据与 Blob 容器同步,只要 Lustre 可以判断,则仅更新属性(如果需要)。 否则,将从 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 托管 Lustre 以最大吞吐量速率为约 7.5GiB/秒从 Blob 存储还原数据。

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

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

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

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

  • 导出作业仅复制新文件或其内容被修改的文件。 如果在创建文件系统期间从 Blob 容器导入的文件保持不变,则导出作业不会导出该文件。
  • 仅导出具有元数据更改的文件。 元数据更改包括:所有者、权限、扩展属性和名称更改(已重命名)。
  • 导出作业期间,在 Azure 托管 Lustre 文件系统中删除的文件不会在原始 Blob 容器中删除。 导出作业不会删除 Blob 容器中的文件。

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

在活动文件系统中,导出作业期间对文件的更改可能会导致失败状态。 此失败状态可让你知道,文件系统中的所有数据都无法导出到 Blob 存储。 在这种情况下,可以通过创建新的导出作业来重试导出。 新作业仅复制上一个作业中未复制的文件。

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

如果准备解除群集授权并想要执行到 Blob 存储的最终导出,则应确保在启动导出作业之前停止所有 I/O 活动。 此方法有助于通过避免文件系统活动导致的错误来保证导出所有数据。

导出文件的元数据

将文件从 Azure 托管 Lustre 文件系统导出到 Blob 容器时,会保存其他元数据,以简化将内容重新导入文件系统。

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

POSIX 属性 类型
owner int
group int
permissions octal 或 rwxrwxrwx 格式;支持粘滞位

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

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

导出作业的注意事项

使用导出作业导出数据时,必须考虑以下事项:

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

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

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

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

--include-directory-stub

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

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

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

后续步骤