你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
Azure Batch 最佳做法
本文介绍有关有效使用 Azure Batch 服务的最佳做法和有用技巧。 这些技巧有助于增强性能,并避免 Azure Batch 解决方案中出现设计缺陷。
提示
有关 Azure Batch 安全性的指南,请参阅 Batch 安全性与合规资最佳做法。
池是用于在 Batch 服务上执行作业的计算资源。 以下各部分提供了有关使用 Batch 池的建议。
池分配模式: 创建 Batch 帐户时,可以在两种池分配模式之间进行选择:Batch 服务或用户订阅。 在大部分情况下,应使用默认的 Batch 服务模式,使用此模式时,池在幕后在 Batch 托管的订阅中分配。 在备用的“用户订阅”模式下,会在创建池后直接在订阅中创建 Batch VM 和其他资源。 用户订阅帐户主要用于实现一小部分但又非常重要的方案。 有关详细信息,请参阅用户订阅模式的配置。
classic
或simplified
节点通信模式:可以在两种节点通信模式之一(经典或简化)中配置池。 在经典节点通信模型中,Batch 服务启动与计算节点的通信,并且计算节点还需要与 Azure 存储通信。 在简化的节点通信模型中,计算节点启动与 Batch 服务的通信。 由于所需的入站/出站连接范围缩小,并且基线操作不需要 Azure 存储出站访问,因此建议使用简化的节点通信模型。 Batch 服务的一些未来改进也需要简化的节点通信模型。 经典节点通信模型将于 2026 年 3 月 31 日停用。作业和任务运行时间注意事项:如果作业主要包括短时间运行的任务,且预期的任务总数较少,即作业的总预期运行时间不长,则请勿为每个作业分配新池。 节点的分配时间会缩减作业运行时间。
多个计算节点:不保证各个节点始终可用。 硬件故障、操作系统更新和其他许多问题虽然不太常见,但它们可能会导致个别节点脱机。 如果 Batch 工作负荷需要具有确定性且有保证的进度,则你应该分配包含多个节点的池。
生命周期结束 (EOL) 日期临近的映像:强烈建议避免使用 Batch 支持生命周期结束 (EOL) 日期临近的映像。 可以通过
ListSupportedImages
API、PowerShell 或 Azure CLI 发现这些日期。 你负责定期刷新与池相关的 EOL 日期视图,并在 EOL 日期到来之前迁移工作负载。 如果要在指定的节点代理中使用自定义映像,请确保在从某个映像派生自定义映像后,或者根据某个映像创建自定义映像后,沿用该映像的 Batch 支持生命周期结束日期。 没有指定batchSupportEndOfLife
日期的映像表示 Batch 服务尚未确定该日期。 缺少日期并不表示将无限期地支持相应的映像。 将来随时可以添加或更新 EOL 日期。即将达到生命周期结束 (EOL) 日期的 VM SKU: 与 VM 映像一样,VM SKU 或系列也可能达到 Batch 支持生命周期结束日期 (EOL)。 可以通过
ListSupportedVirtualMachineSkus
API、PowerShell 或 Azure CLI 发现这些日期。 通过创建具有适当支持的 VM SKU 的新池,规划将工作负荷迁移到非 EOL VM SKU。 VM SKU 没有关联的batchSupportEndOfLife
日期不指示将无限期支持该特定 VM SKU。 将来随时可以添加或更新 EOL 日期。唯一的资源名称:我们往往会不断地分配和解除 Batch 资源(作业、池等)。 例如,你可能会在星期一创建一个池,在星期二将它删除,然后在星期四又创建一个类似的池。 应为创建的每个新资源指定一个以前从未用过的唯一名称。 可以使用 GUID(作为整个资源名称或其中的一部分),或者通过在资源名称中嵌入资源的创建日期和时间来建立唯一性。 Batch 支持 DisplayName,此属性可为资源指定一个更易读的名称(即使实际资源 ID 不够易读)。 使用唯一名称可以更方便地区分哪个特定资源在日志和指标中产生了影响。 如果需要针对某个资源提交支持案例,唯一名称还可以消除不明确性。
池维护和故障期间的连续性: 最好是让作业动态使用池。 如果作业将同一个池用于所有用途,在该池出现问题时,作业有可能无法运行。 此原则对于时间敏感型工作负载尤其重要。 例如,在计划每个作业时动态选择或创建池,或通过某种方式替代池名称,以便可以绕过不正常的池。
池维护和故障期间的业务连续性:有许多原因(例如内部错误或容量约束)会导致池无法增长到所需的大小。 确保可以在必要时将作业目标重新定为不同的池(也许可以通过 UpdateJob 使用不同的 VM 大小)。 避免依赖于预计永远不会删除或更改的静态池 ID。
出于隔离目的,如果你的场景需要将作业或任务相互隔离,请通过将这些内容放入不同的池中进行隔离。 池是 Batch 中的安全隔离边界,默认情况下,两个池之间相互不可见或不可通信。 避免使用单独的 Batch 帐户作为安全隔离手段,除非运行 Batch 帐户的环境较大,需要隔离。
对于具有非零计算节点的池,不会自动升级 Batch 节点代理。 为了确保 Batch 池接收 Batch 节点代理的最新安全修补程序和更新,需要将池大小调整为零计算节点或重新创建池。 建议留意 Batch 节点代理发行说明,以了解新 Batch 节点代理版本 发生的更改。 定期检查发布的更新可以规划升级到最新代理版本。
如果遇到 Batch 池或计算节点问题,那么在重新创建池或调整池大小之前,应下载任何节点代理日志来进行调试。 节点部分进一步介绍了此过程。
备注
有关 Azure Batch 安全性的一般性指南,请参阅 Batch 安全性与合规性最佳做法。
建议为 Batch 池选择的 VM 映像应与发布者提供的最新安全更新同步更新。
某些映像可能会在启动时(或之后不久)执行自动包更新,这可能会干扰某些用户定向操作,例如检索包存储库更新(例如 apt update
),或在 StartTask 等操作期间安装包。
建议启用“Batch 池自动 OS 升级”,这样底层 Azure 基础结构就可以协调池中的更新。 可以将此选项配置为不干扰任务执行。 自动 OS 升级并不支持 Batch 支持的所有操作系统。 有关详细信息,请参阅虚拟机规模集自动 OS 升级支持矩阵。
对于 Windows 操作系统,请确保在 Batch 池上使用自动 OS 升级时未启用属性 virtualMachineConfiguration.windowsConfiguration.enableAutomaticUpdates
。
Azure Batch 不会验证允许与服务一起使用的映像是否具有最新的安全更新,也不保证其具有最新安全更新。
对映像的更新由映像发布者负责,不由 Azure Batch 负责。 对于在 microsoft-azure-batch
下发布的某些映像,不保证这些映像与其上游派生的映像保持最新。
池生存期可能根据分配方法和应用于池配置的选项而有所不同。 池可以具有任意生存期,并且在任意时间点,计算节点数可能会变化。 你需要负责显式管理池中的计算节点,或者通过服务提供的功能(自动缩放或自动池)进行管理。
重新创建池:避免每天删除再重新创建池。 应该创建新池,然后将现有作业更新为指向新池。 将所有任务移到新池后删除旧池。
池效率和计费:Batch 本身不会产生额外的费用。 但是,你需要为使用的 Azure 资源付费,例如计算、存储、网络以及 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 PowerShell 或 Azure CLI 来实现此目的。
使用虚拟网络创建 Batch 池时,指定的虚拟网络和默认 Docker 网桥之间可能存在交互副作用。 Docker 默认会创建一个网络网桥,其子网规范为 172.17.0.0/16
。 请确保 Docker 网桥和虚拟网络之间没有冲突的 IP 范围。
Docker Hub 限制了映像拉取的数量。 请确保工作负载不会超出为基于 Docker Hub 的映像发布的速率限制。 建议直接使用 Azure 容器注册表或利用 ACR 中的工件缓存。
如果你有时间敏感型工作负载或生产工作负载,则你不应依赖单个 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 秒,最多运行几小时甚至几天)中执行大量的工作。 如果每个任务执行一分钟(或更长时间),则调度开销将仅占总体计算时间的很少一部分。
在 Batch 节点上计划任务时,可以选择是否使用任务范围或池范围运行任务。 如果任务只运行很短的时间,由于为该任务创建自动用户帐户所需的资源,任务范围可能效率不高。 为了提高效率,请考虑将这些任务设置为池范围。 有关详细信息,请参阅以具有池范围的自动用户身份运行任务。
计算节点是专门用于处理一部分应用程序工作负载的 Azure 虚拟机 (VM) 或云服务 VM。 使用节点时,请遵循以下指导原则。
与其他任务一样,节点启动任务应该是幂等的。 当计算节点或 Batch 代理重启时,将重新运行启动任务。 幂等任务就是在多次运行时生成一致结果的任务。
启动任务不应长时间运行或与计算节点的生存期关联。 如果需要启动本质上是服务或类似服务的程序,请构造一个启动任务,使这些程序能够由操作系统工具(例如 Linux 或 Windows 服务上的 systemd
)启动和管理。 启动任务仍应构造为幂等,以便在这些程序先前作为服务安装的情况下正确处理启动任务的后续执行。
提示
当 Batch 重新运行启动任务时,它会尝试删除然后重新创建启动任务目录。 如果 Batch 无法重新创建启动任务目录,则计算节点将无法启动启动任务。
这些服务不得对节点上 Batch 托管目录中的任何文件创建文件锁,否则 Batch 会由于存在文件锁而无法删除这些目录。 例如,不要配置直接从启动任务工作目录启动服务,而是以幂等方式将文件复制到其他位置。 然后使用操作系统工具从该位置安装服务。
请考虑对具有符合性或法规要求的工作负荷使用独立的 VM 大小。 虚拟机配置模式下支持的独立大小包括 Standard_E80ids_v4
、Standard_M128ms
、Standard_F72s_v2
、Standard_G5
、Standard_GS5
和 Standard_E64i_v3
。 有关独立 VM 大小的详细信息,请参阅 Azure 中的虚拟机隔离。
在清理任务和作业时,很难处理目录联接(有时称为目录硬链接)。 请使用符号链接(软链接),而不要使用硬链接。
Batch 依赖于使用 VM 临时磁盘(对于与 Batch 兼容的 VM 大小而言)来存储与任务执行相关的元数据以及此临时磁盘上的每个任务执行的任何项目。 这些临时磁盘装载点或目录的示例:/mnt/batch
、/mnt/resource/batch
和 D:\batch\tasks
。
不支持替换、重新装载、接合、符号链接或以其他方式重定向这些装载点和目录或任何父目录,此类操作可能导致不稳定。 如果需要更多磁盘空间,请考虑使用具有满足要求的临时磁盘空间的 VM 大小或系列,或附加数据磁盘。 有关详细信息,请参阅下一部分,其中介绍了如何为计算节点附加和准备数据磁盘。
如果将每个计算节点指定为 Batch 池实例的一部分,则为其附加的数据磁盘规格将完全相同。 只能将新的数据磁盘附加到 Batch 池。 这些附加到计算节点的数据磁盘不会自动分区、格式化或装载。 你需要负责将这些操作作为启动任务的一部分来执行。 这些启动任务必须采用幂等设计。 可以在计算节点上重新执行启动任务。 如果启动任务不是幂等的,则数据磁盘上可能会发生数据丢失。
提示
在 Linux 中装载数据磁盘时,如果将磁盘装入点嵌套在 Azure 临时装入点(例如 /mnt
或 /mnt/resource
)下,应注意不引入依赖项争用。 例如,如果这些装载由 OS 自动执行,则装载的临时磁盘与在父目录下装载的数据磁盘之间可能存在争用。 应当采取措施来确保通过可用的工具(例如 systemd
)强制实施适当的依赖关系,或者在幂等数据磁盘准备脚本中将数据磁盘的装载推迟到启动任务。
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 直接提供给 fdisk
、mkfs
以及工作流所需的任何其他工具。 或者,可以将 lsblk
与 blkid
结合使用来映射磁盘的 UUID。
若要详细了解 Linux 中的 Azure 数据磁盘(包括查找数据磁盘和 /etc/fstab
选项的备用方法),请查看此文章。 在将方法提升到生产使用之前,请确保没有提示备注中描述的依赖关系或争用。
附加到 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 服务日志”API 收集 Batch 代理日志。 可将这些日志作为支持票证的一部分提供给 Microsoft,它们将有助于排查和解决问题。
超时失败不一定指示服务未能处理请求。 发生超时失败时,应根据情况重试操作或检索资源的状态,以验证操作的状态是成功还是失败。
查看以下有关 Batch 解决方案中的连接性的指导。
在虚拟网络中预配 Batch 池时,请确保严格遵守有关使用 BatchNodeManagement.region 服务标记、端口、协议和规则方向的指导原则。 强烈建议使用服务标记,不要使用基础 Batch 服务 IP 地址,因为这些地址可能会随着时间的推移而变化。 直接使用 Batch 服务 IP 地址可能会导致 Batch 池不稳定、受干扰或中断。
对于用户定义的路由 (UDR),建议使用 BatchNodeManagement.region 服务标记,而不是 Batch 服务 IP 地址,因为这些地址可能会随发生更改。
确保系统遵守 Batch 帐户服务 URL 的 DNS 生存时间 (TTL)。 此外,请确保 Batch 服务客户端以及 Batch 服务的其他连接机制不依赖于 IP 地址。
任何具有 5xx 级别状态代码的 HTTP 请求以及响应中的“Connection: close”标头都需要调整 Batch 服务客户端行为。 你的 Batch 服务客户端应遵循建议关闭现有连接,重新解析 Batch 帐户服务 URL 的 DNS,然后在新的连接上尝试后续请求。
确保 Batch 服务客户端实施了适当的重试策略来自动重试请求,即使在正常操作期间也要实施重试机制,而不仅仅是在任何服务维护时段实施。 这些重试策略的间隔时间应该至少为 5 分钟。 各种 Batch SDK(例如 .NET RetryPolicyProvider 类)都附带了自动重试功能。
通常,Batch 池中的虚拟机是通过公共 IP 地址访问的,这些地址在池的生命周期中会发生更改。 这种动态性会使与数据库或其他限制访问某些 IP 地址的外部服务交互变得困难。 若要解决这种忧虑,可以使用由你控制的一组静态公共 IP 地址创建一个池。 有关详细信息,请参阅使用指定的公用 IP 地址创建 Azure Batch 池。
设计 Batch 解决方案时,请考虑以下依赖项和限制。
Azure Batch 在 VM 上创建和管理一组用户和组,这些不应受到更改:
Windows:
- 名为“PoolNonAdmin”的用户
- 名为“WATaskCommon”的用户组
Linux:
- 名为“_azbatch”的用户
提示
这些用户或组的命名是实现项目,随时可能会更改。
当任务的保留期到期后,Batch 会主动尝试清理运行任务的工作目录。 你应负责清理在此目录之外写入的所有文件,以避免占用磁盘空间。
如果在 Windows 上从启动任务工作目录运行服务,则会阻止对工作目录的自动清理,因为文件夹仍在使用中。 此操作将导致性能下降。 若要解决此问题,请将该服务的目录更改为不受 Batch 管理的单独目录。
- 了解 Batch 服务工作流和主要资源,例如池、节点、作业和任务。
- 了解默认的 Azure Batch 配额、限制和约束,以及如何请求增加配额。
- 了解如何在池和节点后台操作中检测和避免失败。