Azure Batch 最佳做法

本文介绍有关有效使用 Azure Batch 服务的最佳做法和有用技巧。 这些技巧有助于增强性能,并避免 Azure Batch 解决方案中出现设计缺陷。

是用于在 Batch 服务上执行作业的计算资源。 以下各部分提供了有关使用 Batch 池的建议。

池配置和命名

  • 池分配模式: 创建 Batch 帐户时,可以在两种池分配模式之间进行选择:Batch 服务用户订阅。 在大部分情况下,应使用默认的 Batch 服务模式,使用此模式时,池在幕后在 Batch 托管的订阅中分配。 在备用的“用户订阅”模式下,会在创建池后直接在订阅中创建 Batch VM 和其他资源。 用户订阅帐户主要用于实现一小部分但又非常重要的方案。 有关详细信息,请参阅用户订阅模式的配置

  • “virtualMachineConfiguration”或“cloudServiceConfiguration”: 虽然目前可以使用任一配置来创建池,但应使用“virtualMachineConfiguration”而不是“cloudServiceConfiguration”来配置新池。 虚拟机配置池将支持所有当前和新的 Batch 功能。 云服务配置池不支持所有功能,也没有计划任何新功能。 2024 年 2 月 29 日之后,无法创建新的“cloudServiceConfiguration”池,也无法向现有池添加新节点。 有关详细信息,请参阅将 Batch 池配置从云服务迁移到虚拟机

  • 作业和任务运行时间注意事项:如果作业主要包括短时间运行的任务,且预期的任务总数较少,即作业的总预期运行时间不长,则请勿为每个作业分配新池。 节点的分配时间会缩减作业运行时间。

  • 多个计算节点:不保证各个节点始终可用。 硬件故障、操作系统更新和其他许多问题虽然不太常见,但它们可能会导致个别节点脱机。 如果 Batch 工作负荷需要具有确定性且有保证的进度,则你应该分配包含多个节点的池。

  • 生命周期结束 (EOL) 日期临近的映像:强烈建议避免使用 Batch 支持生命周期结束 (EOL) 日期临近的映像。 可以通过 ListSupportedImages APIPowerShellAzure CLI 发现这些日期。 你负责定期刷新与池相关的 EOL 日期视图,并在 EOL 日期到来之前迁移工作负载。 如果要在指定的节点代理中使用自定义映像,请确保在从某个映像派生自定义映像后,或者根据某个映像创建自定义映像后,沿用该映像的 Batch 支持生命周期结束日期。

  • 唯一的资源名称:我们往往会不断地分配和解除 Batch 资源(作业、池等)。 例如,你可能会在星期一创建一个池,在星期二将它删除,然后在星期四又创建一个类似的池。 应为创建的每个新资源指定一个以前从未用过的唯一名称。 可以使用 GUID(作为整个资源名称或其中的一部分),或者通过在资源名称中嵌入资源的创建日期和时间来建立唯一性。 Batch 支持 DisplayName,此属性可为资源指定一个更易读的名称(即使实际资源 ID 不够易读)。 使用唯一名称可以更方便地区分哪个特定资源在日志和指标中产生了影响。 如果需要针对某个资源提交支持案例,唯一名称还可以消除不明确性。

  • 池维护和故障期间的连续性: 最好是让作业动态使用池。 如果作业将同一个池用于所有用途,在该池出现问题时,作业有可能无法运行。 此原则对于时间敏感型工作负载尤其重要。 例如,在计划每个作业时动态选择或创建池,或通过某种方式替代池名称,以便可以绕过不正常的池。

  • 池维护和故障期间的业务连续性:有许多原因(例如内部错误或容量约束)会导致池无法增长到所需的大小。 确保可以在必要时将作业目标重新定为不同的池(也许可以通过 UpdateJob 使用不同的 VM 大小)。 避免依赖于预计永远不会删除或更改的静态池 ID。

池安全性

隔离边界

出于隔离目的,如果你的场景需要将作业或任务相互隔离,请通过将这些内容放入不同的池中进行隔离。 池是 Batch 中的安全隔离边界,默认情况下,两个池之间相互不可见或不可通信。 避免使用单独的 Batch 帐户作为安全隔离手段,除非运行 Batch 帐户的环境较大,需要隔离。

Batch 节点代理更新

对于具有非零计算节点的池,不会自动升级 Batch 节点代理。 为了确保 Batch 池接收 Batch 节点代理的最新安全修补程序和更新,需要将池大小调整为零计算节点或重新创建池。 建议留意 Batch 节点代理发行说明,以了解新 Batch 节点代理版本 发生的更改。 定期检查发布的更新可以规划升级到最新代理版本。

如果遇到 Batch 池或计算节点问题,那么在重新创建池或调整池大小之前,应下载任何节点代理日志来进行调试。 节点部分进一步介绍了此过程。

池生存期和计费

池生存期可能根据分配方法和应用于池配置的选项而有所不同。 池可以具有任意生存期,并且在任意时间点,计算节点数可能会变化。 你需要负责显式管理池中的计算节点,或者通过服务提供的功能(自动缩放自动池)进行管理。

  • 重新创建池:避免每天删除再重新创建池。 应该创建新池,然后将现有作业更新为指向新池。 将所有任务移到新池后删除旧池。

  • 池效率和计费:Batch 本身不会产生额外的费用。 但是,你需要为使用的 Azure 资源付费,例如计算、存储、网络以及 Batch 工作负载可能需要的任何其他资源。 你需要为池中的每个计算节点付费,不管这些节点处于何种状态。

  • 临时 OS 磁盘:虚拟机配置池可使用临时 OS 磁盘来避免产生与托管磁盘相关的额外费用,临时磁盘会在 VM 缓存或临时 SSD 上创建 OS 磁盘。

池分配失败

在首次分配或后续的调整大小期间,可能会发生池分配失败。 发生这种失败的可能原因是区域中出现了暂时性的容量耗尽,或 Batch 所依赖的其他 Azure 服务发生故障。 核心配额没有保障,而且存在限制。

计划外停机

Azure 中的 Batch 池可能会遇到停机事件。 了解这些问题可能发生后,应该制定在重新执行后可复原的工作流。 如果节点发生故障,Batch 会代表你自动尝试恢复这些计算节点。 这种恢复可能会触发在已还原节点或其他可用节点上重新计划任何正在运行的任务。 若要详细了解中断的任务,请参阅重试设计

自定义映像池

使用虚拟机配置创建 Azure Batch 池时,需指定一个虚拟机 (VM) 映像,为池中每个计算节点提供操作系统。 可以使用受支持的映像创建 Azure 市场池,也可以使用 Azure Compute Gallery 映像创建自定义映像。 虽然也可使用托管映像创建自定义映像池,但建议尽可能使用 Azure Compute Gallery 创建自定义映像。 使用 Azure Compute Gallery 可帮助你更快地预配池、缩放更大数量的 VM,以及提高预配 VM 时的可靠性。

第三方映像

可以使用发布到 Azure 市场的第三方映像创建池。 对于用户订阅模式 Batch 帐户,在使用某些第三方映像创建池时,你可能会看到错误“由于市场购买资格检查造成分配失败”。 若要解决此错误,请接受映像发布者设置的术语。 可以通过 Azure PowerShellAzure CLI 来实现此目的。

Azure 区域依赖项

如果你有时间敏感型工作负载或生产工作负载,则你不应依赖单个 Azure 区域。 有些问题虽然极少出现,但可能会影响整个区域。 例如,如果处理需要在特定的时间开始,请考虑在开始之前的相当长一段时间纵向扩展主要区域中的池。 如果扩展该池失败,可以回退并在一个或多个备份区域中纵向扩展池。

如果另一个池出现问题,跨不同区域中多个帐户的池可提供一个现成的且易于访问的备份。

作业

作业是可以包含数百、数千甚至数百万个任务的容器。 创建作业时,请遵循这些指导原则。

更少作业,更多任务

使用一个作业运行单个任务是低效的做法。 例如,使用包含 1000 个任务的单个作业,比创建 100 个作业并在每个作业中包含 10 个任务更高效。 如果使用了 1000 个作业,在每个作业中包含单个任务是最低效、速度最慢且成本最高的做法。

请确保避免设计同时需要数千个活动作业的 Batch 解决方案。 不存在针对任务的配额,因此,通过尽量少的作业执行尽量多的任务可以有效利用作业和作业计划配额

作业生存期

在从系统中删除之前,Batch 作业生存期是无限的。 其状态会指示该作业是否可以接受更多任务来进行计划。

除非显式终止作业,否则作业不会自动转换为已完成状态。 可以通过 onAllTasksComplete 属性或 maxWallClockTime 自动触发此操作。

存在默认的活动作业和作业计划配额。 处于已完成状态的作业和作业计划不会计入此配额。

任务

任务是构成作业的单个工作单位。 任务由用户提交,并由 Batch 在计算节点上进行计划。 以下部分提供了有关设计任务以处理问题并保持高效性能的建议。

保存任务数据

计算节点具有瞬态性。 自动汇集自动缩放等 Batch 功能很容易使节点消失。 当节点离开池时(由于调整大小或删除池),这些节点上的所有文件也会一并删除。 由于此行为,在某个任务完成之前,它应将其自身的输出从运行它的节点移到持久存储。 同样,如果任务失败,则应将诊断失败问题所需的日志移到持久存储。

Batch 中集成了用于通过 OutputFiles 上传数据的支持 Azure 存储以及各种共享文件系统,你也可以在任务中自行执行上传。

管理任务生存期

当不再需要这些任务时将其删除,或者设置 retentionTime 任务约束。 如果设置了 retentionTime,当 retentionTime 过期时,Batch 会自动清理该任务占用的磁盘空间。

删除任务可以实现两种目的:

  • 确保作业中不会存在积累的任务。 此操作有助于避免难以查找你感兴趣的任务的情况(因为必须通过“已完成”任务进行筛选)。
  • 清理节点上的相应任务数据(假设尚未达到 retentionTime)。 此操作有助于确保节点中不会填满任务数据且不会耗尽磁盘空间。

注意

对于刚刚提交到 Batch 的任务,DeleteTask API 调用最多需要 10 分钟才能生效。 在它生效之前,可能会阻止计划其他任务。 这是因为 Batch 计划程序仍会尝试计划刚刚删除的任务。 如果想在提交不久后删除一个任务,请改为终止该任务(因为终止任务会立即生效)。 然后在 10 分钟后删除任务。

以集合形式提交大量任务

可以逐个提交或以集合形式提交任务。 执行批量任务提交时,每次以最多包含 100 个任务的集合形式提交任务可以减少开销并缩短提交时间。

适当地设置每个节点的最大任务数

Batch 在节点上支持超额订阅的任务(运行的任务数超过节点所具有的核心数)。 你需要确保任务数适合池中的节点。 例如,如果你尝试计划 8 个任务,其中每个任务消耗 25% 的 CPU 使用率(在设置了 taskSlotsPerNode = 8 的池中),则体验可能会下降。

设计重试和重新执行

Batch 可以自动重试任务。 有两种类型的重试:用户控制的重试和内部重试。 用户控制的重试由任务的 maxTaskRetryCount 指定。 如果任务中指定的程序退出并出现非零退出代码,则会将该任务重试最多 maxTaskRetryCount 次。

可能会由于计算节点上发生故障(例如,在运行任务时无法更新内部状态或节点上发生故障)而在内部重试任务,不过,这种情况很罕见。 将尽可能地在同一计算节点上重试任务,直到达到内部限制,重试失败后将放弃该任务,并推迟任务以让 Batch 重新对其进行计划(可能会将其安排在不同的计算节点上)。

生成持久任务

在设计任务时应当使其能够承受故障并提供重试机制。 对于长时间运行的任务,此原则尤其重要。 确保任务即使多次运行也能生成相同的单一结果。 实现此结果的一种方法是使任务“搜寻目标”。另一种方法是确保任务具有幂等性(无论任务运行多少次,都将具有相同的结果)。

一个常见示例是通过某个任务将文件复制到计算节点。 简单的方法是每次运行任务时复制所有指定的文件,但这种方法非常低效,且不能承受故障。 替代方法是创建一个任务来确保文件位于计算节点上,该任务不会重新复制已存在的文件。 通过这种方式,在该任务中断时,它会从上次中断的位置继续运行。

避免短执行时间

仅运行一两秒的任务并不理想。 尝试在单个任务(最少运行 10 秒,最多运行几小时甚至几天)中执行大量的工作。 如果每个任务执行一分钟(或更长时间),则调度开销将仅占总体计算时间的很少一部分。

将池范围用于 Windows 节点上的短任务

在 Batch 节点上计划任务时,可以选择是否使用任务范围或池范围运行任务。 如果任务只运行很短的时间,由于为该任务创建自动用户帐户所需的资源,任务范围可能效率不高。 为了提高效率,请考虑将这些任务设置为池范围。 有关详细信息,请参阅以具有池范围的自动用户身份运行任务.

Nodes

计算节点是专门用于处理一部分应用程序工作负载的 Azure 虚拟机 (VM) 或云服务 VM。 使用节点时,请遵循以下指导原则。

幂等启动任务

与其他任务一样,节点启动任务应该是幂等的,因为每次节点启动时,都要重新运行该任务。 幂等任务就是在多次运行时生成一致结果的任务。

独立节点

请考虑对具有符合性或法规要求的工作负荷使用独立的 VM 大小。 虚拟机配置模式下支持的独立大小包括 Standard_M128msStandard_F72s_v2Standard_E64i_v3。 有关独立 VM 大小的详细信息,请参阅 Azure 中的虚拟机隔离

通过操作系统服务接口管理长时间运行的服务

有时,需要在节点中将 Batch 代理与另一代理一起运行。 例如,你可能想要从节点收集数据并生成相关报告。 建议将这些代理部署为 OS 服务,例如 Windows 服务或 Linux systemd 服务。

这些服务不得对节点上 Batch 托管目录中的任何文件创建文件锁,否则 Batch 会由于存在文件锁而无法删除这些目录。 例如,如果在启动任务中安装 Windows 服务,而不是直接从启动任务工作目录启动该服务,请将文件复制到其他位置(或者,如果文件已存在,则直接跳过该复制操作)。 然后从该位置安装服务。 当 Batch 重新运行启动任务时,它会删除然后重新创建启动任务工作目录。

避免在 Windows 中创建目录联接

在清理任务和作业时,很难处理目录联接(有时称为目录硬链接)。 请使用符号链接(软链接),而不要使用硬链接。

临时磁盘和 AZ_BATCH_NODE_ROOT_DIR

Batch 依赖于使用 VM 临时磁盘(对于与 Batch 兼容的 VM 大小而言)来存储与任务执行相关的元数据以及此临时磁盘上的每个任务执行的任何项目。 这些临时磁盘装载点或目录的示例:/mnt/batch/mnt/resource/batchD:\batch\tasks。 不支持替换、重新装载、接合、符号链接或以其他方式重定向这些装载点和目录或任何父目录,此类操作可能导致不稳定。 如果需要更多磁盘空间,请考虑使用具有满足要求的临时磁盘空间的 VM 大小或系列,或附加数据磁盘。 有关详细信息,请参阅下一部分,其中介绍了如何为计算节点附加和准备数据磁盘。

附加和准备数据磁盘

如果将每个计算节点指定为 Batch 池实例的一部分,则为其附加的数据磁盘规格将完全相同。 只能将新的数据磁盘附加到 Batch 池。 这些附加到计算节点的数据磁盘不会自动分区、格式化或装载。 你需要负责将这些操作作为启动任务的一部分来执行。 这些启动任务必须采用幂等设计。 可以在计算节点上重新执行启动任务。 如果启动任务不是幂等的,则数据磁盘上可能会发生数据丢失。

提示

在 Linux 中装载数据磁盘时,如果将磁盘装入点嵌套在 Azure 临时装入点(例如 /mnt/mnt/resource)下,应注意不引入依赖项争用。 例如,如果这些装载由 OS 自动执行,则装载的临时磁盘与在父目录下装载的数据磁盘之间可能存在争用。 应当采取措施来确保通过可用的工具(例如 systemd)强制实施适当的依赖关系,或者在幂等数据磁盘准备脚本中将数据磁盘的装载推迟到启动任务。

在 Linux Batch 池中准备数据磁盘

Linux 中的 Azure 数据磁盘显示为块设备,并为其分配了典型的 sd[X] 标识符。 请不要依赖于静态 sd[X] 分配,因为这些标签是在启动时动态分配的,不能保证在完成首次启动和任何后续启动之间保持一致。 应该通过 /dev/disk/azure/scsi1/ 中提供的映射来识别附加的磁盘。 例如,如果在AddPool API 中为数据磁盘指定了 LUN 0,则此磁盘将显示为 /dev/disk/azure/scsi1/lun0。 例如,如果你列出此目录,则可能会看到:

user@host:~$ ls -l /dev/disk/azure/scsi1/
total 0
lrwxrwxrwx 1 root root 12 Oct 31 15:16 lun0 -> ../../../sdc

无需将引用转换回准备脚本中的 sd[X] 映射,而可以直接引用设备。 在此示例中,此设备为 /dev/disk/azure/scsi1/lun0。 可以将此 ID 直接提供给 fdiskmkfs 以及工作流所需的任何其他工具。 或者,可以将 lsblkblkid 结合使用来映射磁盘的 UUID。

若要详细了解 Linux 中的 Azure 数据磁盘(包括查找数据磁盘和 /etc/fstab 选项的备用方法),请查看此文章。 在将方法提升到生产使用之前,请确保没有提示备注中描述的依赖关系或争用。

在 Windows Batch 池中准备数据磁盘

附加到 Batch Windows 计算节点的 Azure 数据磁盘将显示为未分区且未格式化。 需要在启动任务中枚举包含 RAW 分区的磁盘进行处理。 可以使用 Get-Disk PowerShell cmdlet 检索此信息。 例如,你可能会看到:

PS C:\Windows\system32> Get-Disk

Number Friendly Name Serial Number                    HealthStatus         OperationalStatus      Total Size Partition
                                                                                                             Style
------ ------------- ------------- ------------         ----------------- ---------- ----------
0      Virtual HD                                     Healthy              Online                      30 GB MBR
1      Virtual HD                                     Healthy              Online                      32 GB MBR
2      Msft Virtu...                                  Healthy              Online                      64 GB RAW

其中磁盘编号 2 是附加到此计算节点的未初始化数据磁盘。 然后可以根据工作流的需要对这些磁盘进行初始化、分区和格式化。

若要详细了解 Windows 中的 Azure 数据磁盘(包括示例 PowerShell 脚本),请查看此文章。 在提升到生产使用之前,请确保验证任何示例脚本是否具有幂等性。

收集 Batch 代理日志

如果发现节点的行为或节点上运行的任务出现问题,请在解除分配有问题的节点之前收集 Batch 代理日志。 可以使用“上传 Batch 服务日志”API 收集 Batch 代理日志。 这些日志可以作为 Azure 支持工单的一部分提供,并将有助于问题的故障排除和解决。

管理 OS 升级

对于用户订阅模式 Batch 帐户,自动 OS 升级可能会中断任务进程,尤其是在任务长时间运行的情况下。 生成幂等任务有助于减少由这些中断导致的错误。 我们还建议将 OS 映像升级安排在任务不需要运行时

对于 Windows 池,默认情况下 enableAutomaticUpdates 设置为 true。 建议允许自动更新,但如果需要确保不会意外进行 OS 更新,则可以将此值设置为 false

连接

查看以下有关 Batch 解决方案中的连接性的指导。

网络安全组 (NSG) 和用户定义的路由 (UDR)

在虚拟网络中预配 Batch 池时,请确保严格遵守有关使用 BatchNodeManagement.region 服务标记、端口、协议和规则方向的指导原则。 强烈建议使用服务标记,不要使用基础 Batch 服务 IP 地址,因为这些地址可能会随着时间的推移而变化。 直接使用 Batch 服务 IP 地址可能会导致 Batch 池不稳定、受干扰或中断。

对于用户定义的路由 (UDR),建议使用 BatchNodeManagement.region服务标记而不是 Batch 服务 IP 地址,因为这些地址可能会随时间变化。

遵守 DNS

确保系统遵守 Batch 帐户服务 URL 的 DNS 生存时间 (TTL)。 此外,请确保 Batch 服务客户端以及 Batch 服务的其他连接机制不依赖于 IP 地址。

任何具有 5xx 级别状态代码的 HTTP 请求以及响应中的“Connection: close”标头都需要调整 Batch 服务客户端行为。 你的 Batch 服务客户端应遵循建议关闭现有连接,重新解析 Batch 帐户服务 URL 的 DNS,然后在新的连接上尝试后续请求。

自动重试请求

确保 Batch 服务客户端实施了适当的重试策略来自动重试请求,即使在正常操作期间也要实施重试机制,而不仅仅是在任何服务维护时段实施。 这些重试策略的间隔时间应该至少为 5 分钟。 各种 Batch SDK(例如 .NET RetryPolicyProvider 类)都附带了自动重试功能。

静态公共 IP 地址

通常,Batch 池中的虚拟机是通过公共 IP 地址访问的,这些地址在池的生命周期中会发生更改。 这种动态性会使与数据库或其他限制访问某些 IP 地址的外部服务交互变得困难。 若要解决这种忧虑,可以使用由你控制的一组静态公共 IP 地址创建一个池。 有关详细信息,请参阅使用指定的公用 IP 地址创建 Azure Batch 池

测试与云服务配置的连接

无法将正常的“ping”/ICMP 协议与云服务结合使用,因为不允许通过 Azure 负载均衡器使用 ICMP 协议。 有关详细信息,请参阅 Azure 云服务的连接和网络

Batch 节点的基本依赖项

设计 Batch 解决方案时,请考虑以下依赖项和限制。

系统创建的资源

Azure Batch 在 VM 上创建和管理一组用户和组,这些不应受到更改:

Windows:

  • 名为“PoolNonAdmin”的用户
  • 名为“WATaskCommon”的用户组

Linux:

  • 名为“_azbatch”的用户

提示

这些用户或组的命名是实现项目,随时可能会更改。

文件清理

当任务的保留期到期后,Batch 会主动尝试清理运行任务的工作目录。 你应负责清理在此目录之外写入的所有文件,以避免占用磁盘空间。

如果在 Windows 上从启动任务工作目录运行服务,则会阻止对工作目录的自动清理,因为文件夹仍在使用中。 此操作将导致性能下降。 若要解决此问题,请将该服务的目录更改为不受 Batch 管理的单独目录。

后续步骤