YARN 节点标签

概述

节点标签是一种对具有相似特征的节点进行分组的方式,应用程序可以指定运行位置。

现在我们只支持节点分区,即

  • 一个节点只能有一个节点分区,因此一个集群通过节点分区被划分为几个不相交的子集群。默认情况下,节点属于 DEFAULT 分区 (partition="")
  • 用户需要配置每个分区有多少资源可以被不同的队列使用。有关更多详细信息,请参阅下一部分。
  • 有两种类型的节点分区
    • 独占:容器将分配给与节点分区完全匹配的节点。(例如,询问 partition=“x” 将分配给 partition=“x” 的节点,询问 DEFAULT 分区将分配给 DEFAULT 分区节点)。
    • 非独占:如果一个分区是非独占的,它将共享空闲资源给请求 DEFAULT 分区的容器。

用户可以指定每个队列可以访问的节点标签集,一个应用程序只能使用包含该应用程序的队列可以访问的节点标签子集。

功能

节点标签目前支持以下功能

  • 分区集群 - 每个节点可以分配一个标签,因此集群将被划分为几个较小的不相交分区。
  • 队列上的节点标签 ACL - 用户可以在每个队列上设置可访问的节点标签,以便只有某些节点只能被特定队列访问。
  • 指定队列可以访问的分区资源百分比 - 用户可以设置百分比,例如:队列 A 可以访问标签为 hbase 的节点上的 30% 的资源。此类百分比设置将与现有的资源管理器保持一致
  • 在资源请求中指定所需的节点标签,只有当节点具有相同标签时才会分配该资源。如果没有指定节点标签要求,此类资源请求只会分配给属于 DEFAULT 分区的节点。
  • 可操作性
    • 节点标签和节点标签映射可以在 RM 重新启动后恢复
    • 更新节点标签 - 管理员可以在 RM 运行时更新节点上的标签和队列上的标签
  • NM 到节点标签的映射可以通过三种方式完成,但在所有方法中,分区标签都应该是 RM 中配置的有效节点标签列表之一。
    • 集中式:节点到标签的映射可以通过 RM 公开的 CLI、REST 或 RPC 完成。
    • 分布式:节点到标签的映射将由 NM 中配置的节点标签提供程序设置。我们在 YARN 中有两个不同的提供程序:基于脚本的提供程序和基于配置的提供程序。对于脚本,可以为 NM 配置脚本路径,并且脚本可以发出节点的标签。对于配置,节点标签可以直接在 NM 的 yarn-site.xml 中配置。在这两种选项中,都支持标签映射的动态刷新。
    • 委托集中式:节点到标签的映射将由 RM 中配置的节点标签提供程序设置。当由于安全问题而无法由每个节点提供标签映射,并且为了避免与大集群中每个节点的 RM 接口进行交互时,这将非常有用。在 NM 注册期间将从该接口获取标签,并且还支持定期刷新。

配置

设置 ResourceManager 以启用节点标签

yarn-site.xml 中设置以下属性

属性
yarn.node-labels.fs-store.root-dir hdfs://namenode:port/path/to/store/node-labels/
yarn.node-labels.enabled true
yarn.node-labels.configuration-type 设置节点标签的配置类型。管理员可以指定“centralized”、“delegated-centralized”或“distributed”。默认值为“centralized”。

注释

  • 确保已创建 yarn.node-labels.fs-store.root-dir,并且 ResourceManager 有权访问它。(通常是来自“yarn”用户)
  • 如果用户想将节点标签存储到 RM 的本地文件系统(而不是 HDFS),可以使用 file:///home/yarn/node-label 这样的路径

向 YARN 添加/修改节点标签列表

  • 添加集群节点标签列表
    • 执行 yarn rmadmin -addToClusterNodeLabels "label_1(exclusive=true/false),label_2(exclusive=true/false)" 以添加节点标签。
    • 如果用户未指定 “(exclusive=…)”,则 exclusive 将默认设置为 true
    • 运行 yarn cluster --list-node-labels 以检查添加的节点标签是否在集群中可见。

从 YARN 中移除节点标签

  • 移除集群节点标签
    • 要移除一个或多个节点标签,请执行以下命令:yarn rmadmin -removeFromClusterNodeLabels "<label>[,<label>,...]"。命令参数应为要移除的节点标签的逗号分隔列表。
    • 不允许移除已与队列关联的标签,即一个或多个队列有权访问此标签。
    • 要验证指定的节点标签是否已成功移除,请运行 yarn cluster --list-node-labels

向 YARN 添加/修改节点到标签的映射

  • 集中式 NodeLabel 设置中配置节点到标签的映射

    • 执行 yarn rmadmin -replaceLabelsOnNode “node1[:port]=label1 node2=label2” [-failOnUnknownNodes]。将 label1 添加到 node1,将 label2 添加到 node2。如果用户未指定端口,则它会将标签添加到在节点上运行的所有 NodeManagers。如果设置了选项 -failOnUnknownNodes,则如果指定的节点未知,此命令将失败。
  • 分布式 NodeLabel 设置中配置节点到标签的映射

属性
yarn.node-labels.configuration-type 需要在 RM 中将其设置为 “distributed”,以从 NM 中配置的 Node Labels Provider 获取节点到标签的映射。
yarn.nodemanager.node-labels.provider 当 RM 中的 “yarn.node-labels.configuration-type” 配置为 “distributed” 时,管理员可以通过在 NM 中配置此参数来配置节点标签的提供程序。管理员可以配置 “config”“script” 或提供程序的 类名。配置的类需要扩展 org.apache.hadoop.yarn.server.nodemanager.nodelabels.NodeLabelsProvider。如果配置了 “config”,则将使用 “ConfigurationNodeLabelsProvider”,如果配置了 “script”,则将使用 “ScriptNodeLabelsProvider”
yarn.nodemanager.node-labels.resync-interval-ms NM 与 RM 同步其节点标签的时间间隔。NM 将每隔 x 个已配置的时间间隔发送其加载的标签以及心跳至 RM。即使标签未修改,也需要进行此重新同步,因为管理员可能已删除 NM 提供的群集标签。默认值为 2 分钟。
yarn.nodemanager.node-labels.provider.fetch-interval-ms “yarn.nodemanager.node-labels.provider” 配置为 “config”“script”配置的类 扩展 AbstractNodeLabelsProvider 时,将定期从节点标签提供程序检索节点标签。此配置用于定义时间间隔。如果配置为 -1,则仅在初始化期间从提供程序检索节点标签。默认值为 10 分钟。
yarn.nodemanager.node-labels.provider.fetch-timeout-ms “yarn.nodemanager.node-labels.provider” 配置为 “script” 时,此配置提供超时时间,之后它将中断查询节点标签的脚本。默认值为 20 分钟。
yarn.nodemanager.node-labels.provider.script.path 要运行的节点标签脚本。以 “NODE_PARTITION:” 开头的脚本输出行将被视为节点标签分区。如果脚本输出的有多行具有此模式,则将考虑最后一行。
yarn.nodemanager.node-labels.provider.script.opts 传递给节点标签脚本的参数。
yarn.nodemanager.node-labels.provider.configured-node-partition “yarn.nodemanager.node-labels.provider” 配置为 “config” 时,ConfigurationNodeLabelsProvider 从此参数获取分区标签。
  • Delegated-Centralized NodeLabel 设置中配置节点到标签的映射
属性
yarn.node-labels.configuration-type 需要将其设置为 “delegated-centralized”,以便从 RM 中配置的节点标签提供程序获取节点到标签的映射。
yarn.resourcemanager.node-labels.provider “yarn.node-labels.configuration-type” 配置为 “delegated-centralized” 时,管理员应配置 ResourceManager 获取节点标签的类。配置的类需要扩展 org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsMappingProvider
yarn.resourcemanager.node-labels.provider.fetch-interval-ms “yarn.node-labels.configuration-type” 配置为 “delegated-centralized” 时,将定期从节点标签提供程序中检索节点标签。此配置用于定义间隔。如果配置为 -1,则仅在每个节点注册后从提供程序中检索一次节点标签。默认为 30 分钟。

节点标签的调度程序配置

  • 容量调度程序配置
属性
yarn.scheduler.capacity.<queue-path>.capacity 设置队列可以访问属于 DEFAULT 分区的节点的百分比。每个父项下直接子项的 DEFAULT 容量之和必须等于 100。
yarn.scheduler.capacity.<queue-path>.accessible-node-labels 管理员需要指定每个队列可以访问的标签,用逗号分隔,例如“hbase,storm”表示队列可以访问标签 hbase 和 storm。所有队列都可以访问没有标签的节点,用户不必指定这一点。如果用户未指定此字段,它将从其父项继承。如果用户想明确指定一个队列只能访问没有标签的节点,只需将一个空格作为值即可。
yarn.scheduler.capacity.<queue-path>.accessible-node-labels.<label>.capacity 设置队列可以访问属于 <label> 分区的节点的百分比。每个父项下直接子项的 <label> 容量之和必须等于 100。默认情况下,它为 0。
yarn.scheduler.capacity.<queue-path>.accessible-node-labels.<label>.maximum-capacity 类似于 yarn.scheduler.capacity.<queue-path>.maximum-capacity,它是每个队列的标签的最大容量。默认情况下,它为 100。
yarn.scheduler.capacity.<queue-path>.default-node-label-expression 值如“hbase”,表示:如果提交到队列的应用程序在其资源请求中未指定节点标签,它将使用“hbase”作为 default-node-label-expression。默认情况下,这是空的,因此应用程序将从没有标签的节点获取容器。

节点标签配置示例:

假设我们有一个队列结构

                root
            /     |    \
     engineer    sales  marketing

集群中有 5 个节点(主机名=h1..h5),每个节点有 24G 内存,24 个 vcore。5 个节点中有 1 个有 GPU(假设是 h5)。因此,管理员向 h5 添加了 GPU 标签。

假设用户有一个容量调度程序配置,如下所示:(此处使用 key=value 以便于阅读)

yarn.scheduler.capacity.root.queues=engineering,marketing,sales
yarn.scheduler.capacity.root.engineering.capacity=33
yarn.scheduler.capacity.root.marketing.capacity=34
yarn.scheduler.capacity.root.sales.capacity=33

yarn.scheduler.capacity.root.engineering.accessible-node-labels=GPU
yarn.scheduler.capacity.root.marketing.accessible-node-labels=GPU

yarn.scheduler.capacity.root.engineering.accessible-node-labels.GPU.capacity=50
yarn.scheduler.capacity.root.marketing.accessible-node-labels.GPU.capacity=50

yarn.scheduler.capacity.root.engineering.default-node-label-expression=GPU

可以看到 root.engineering/marketing/sales.capacity=33,因此每个队列都可以获得等于 没有分区 资源的 1/3 的保证资源。因此,每个队列都可以使用 h1..h4 的 1/3 资源,即 24 * 4 * (1/3) = (32G 内存,32 个 vcore)。

并且只有 engineering/marketing 队列有权访问 GPU 分区(参见 root.<queue-name>.accessible-node-labels)。

每个 engineering/marketing 队列都有等于 分区=GPU 资源的 1/2 的保证资源。因此,每个队列都可以使用 h5 的 1/2 资源,即 24 * 0.5 = (12G 内存,12 个 vcore)。

注释

  • 完成 CapacityScheduler 配置后,执行 yarn rmadmin -refreshQueues 以应用更改
  • 转到 RM Web UI 的调度程序页面,检查您是否已成功设置配置。

为应用程序指定节点标签

应用程序可以使用以下 Java API 来指定要请求的节点标签

  • ApplicationSubmissionContext.setNodeLabelExpression(..) 为应用程序的所有容器设置节点标签表达式。
  • ResourceRequest.setNodeLabelExpression(..) 为各个资源请求设置节点标签表达式。这可以覆盖 ApplicationSubmissionContext 中设置的节点标签表达式
  • ApplicationSubmissionContext 中指定 setAMContainerResourceRequest.setNodeLabelExpression 来指示应用程序主容器的预期节点标签。

监控

通过 Web UI 监控

可以在 Web UI 上看到以下与标签相关的字段

通过命令行监控

  • 使用 yarn cluster --list-node-labels 获取集群中的标签
  • 使用 yarn node -status <NodeId> 获取节点状态,包括给定节点上的标签

有用的链接