# 超节点拓扑亲和调度（待下线）
![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
本文使用的是HyperJob方式，即将下线。推荐您使用[Volcano Job方式](https://support.huaweicloud.com/usermanual-cce/cce_10_1131.html)。
在AI大规模训练和推理场景中，随着计算资源的分布式扩展，Pod间网络通信常面临带宽瓶颈和高延迟问题，尤其是关联度高的Pod之间频繁的跨节点通信，会显著降低系统性能和响应速度。为此，Volcano调度器支持使用超节点拓扑亲和调度能力。超节点由48个节点组成，其内部NPU采用特定网络连接方式形成一种超平面网络，可以提供更快的网络传输速率。超节点拓扑亲和调度可以将关联度高的Pod调度至同一超节点内，从而有效减少跨节点通信，降低网络延迟，并提高数据传输速度。
#### 超节点拓扑亲和调度简介
针对该场景，Volcano调度器支持使用新的工作负载API HyperJob。您可以通过HyperJob，对相关任务进行统一调度和管理，具体示例请参见[超节点拓扑亲和调度使用示例]。超节点拓扑亲和调度遵循的具体调度原则如下：
- **亲和调度** ：Volcano调度器根据HyperJob模板创建Volcano Job，且每个Volcano Job为一个亲和组。进行调度时，系统将任务Pod调度至具有"volcano.sh/hypernode"标签的节点中（具有该标签说明其为超节点内的节点）。同时，同一个亲和组内的Pod将被调度至"volcano.sh/hypernode"标签值相同的节点中（标签值相同说明节点位于同一超节点）。
  图1亲和调度流程图   
  ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002281114665.png "点击放大") 
- **组调度**（Gang）：HyperJob支持组调度，即当Volcano Job运行数量满足minAvailable（不指定时为replicatedJobs.replicas之和）时，系统才会调度HyperJob。同时，HyperJob中的每个Volcano Job也支持组调度。
- **装箱调度** （Binpack）：HyperJob支持装箱调度，即在超节点网络等价时，调度器优先将HyperJob的任务分配至资源碎片最少的超节点中，以提高资源利用率。如[图2 装箱调度对比]所示，假设集群内有2个超节点，其中超节点1已经分配8个节点给其他任务。此时用户下发一个HyperJob，其中包含2个Volcano Job，每个Volcano Job包含20个Pod，每Pod请求独占一个节点。
  - 不使用装箱调度时，调度结果可能是VcJob-0调度至超节点1，VcJob-1调度至超节点2。此时，超节点1的使用率为28/48=58%，超节点2的使用率为20/48=41%。
  
  - 使用装箱调度时，VcJob-0和VcJob-1都会优先调度到超节点1，超节点1使用率为100%，超节点2使用率为0%。此时，超节点2可作为一个完整的空闲超节点供其他任务使用。
    图2装箱调度对比   
    ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002281423381.png "点击放大") 
   
 
#### 前提条件
- 已创建v1.23及以上版本的CCE Standard/Turbo集群，具体步骤请参见[购买Standard/Turbo集群](https://support.huaweicloud.com/usermanual-cce/cce_10_0028.html)。
- 集群中已有超节点。CCE Standard/Turbo集群暂不支持购买超节点，您可以在ModelArts中提前购买超节点（Ascend规格实例），购买后CCE集群将自动纳管，具体步骤请参见[创建Standard专属资源池](https://support.huaweicloud.com/resmgmt-modelarts/resmgmt-modelarts_0004.html)。
  在CCE Standard/Turbo集群中，您可以通过"volcano.sh/hypernode"标签确定该节点是否属于超节点，以及属于哪个超节点。
  
- 集群中已安装Volcano插件，且插件版本在1.15.8及以上，具体步骤请参见[Volcano调度器](https://support.huaweicloud.com/usermanual-cce/cce_10_0193.html)。
- 集群中已安装CCE AI套件（Ascend NPU）插件，且版本在2.1.23及以上，具体步骤请参见[CCE AI套件（Ascend NPU）](https://support.huaweicloud.com/usermanual-cce/cce_10_0239.html)。
 
#### 约束与限制
在单个Pod内，仅支持1个容器申请NPU资源，且不允许init容器申请NPU资源，否则Pod将无法被调度。
#### 开启超节点拓扑亲和调度功能
开启"超节点拓扑亲和调度"功能后，您可以根据训练任务间的数据传输需求手动划分亲和组，系统会将同一亲和组的任务调度至同一超节点，从而有效提升网络传输效率。
1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)，单击集群名称，进入集群概览页。在左侧导航栏中选择"配置中心"，在右侧切换至"调度配置"页签。
2. 在Volcano调度器配置中，"超节点拓扑亲和调度"默认关闭，需进一步修改调度器配置参数以开启该功能。 
   1. 在设置"设置集群默认调度器"中选择Volcano调度器，在"专家模式"中单击"开始使用"。
      图3"专家模式 \> 开始使用"   
      ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002281366969.png "点击放大")
      
      
   
   2. 在YAML配置文件中，添加如下参数，开启"超节点拓扑亲和调度"，以实现同一亲和组不同任务间数据的高效传输。
      ```
      ...
      tiers:
          - plugins:
              - name: priority
              - enableJobStarving: false
                enablePreemptable: false
                name: gang
              - name: conformance
          - plugins:
              - enablePreemptable: false
                name: drf
              - name: predicates
              - name: nodeorder
          - plugins:
              - name: cce-gpu-topology-predicate
              - name: cce-gpu-topology-priority
              - name: xgpu
          - plugins:
              - name: nodelocalvolume
              - name: nodeemptydirvolume
              - name: nodeCSIscheduling
              - name: networkresource
          - plugins:  # 开启超节点拓扑亲和调度
              - name: hypernode-topology-aware
      ...
      ```
      
   
   3. 参数填写完成后，在右下角单击"保存"。
   
   
   
   
3. 在右下角单击"确认配置"。在"确认配置"弹窗中，确认修改信息，无误后单击"保存"。
 
 #### 超节点拓扑亲和调度使用示例
1. 依次执行以下命令，创建一个HyperJob，并在该HyperJob内定义2个亲和组（Volcano Job）用于执行任务。 
   1. 执行以下命令，创建HyperJob的YAML文件。
      ```
      vim hyper-job.yaml
      ```
      文件内容如下，**在单个Pod内，仅支持1个容器申请NPU资源，且不允许init容器申请NPU资源，否则Pod将无法被调度** 。
      ```
      apiVersion: batch.volcano.sh/v1alpha1
      kind: HyperJob 
      metadata: 
        name: hyperjob-test
      spec:
        replicatedJobs:
         - replicas: 2       # Volcano job的副本数
           name: vcjob-test  # Volcano job的名称
           template:
             tasks: 
             - replicas: 2   # Pod的副本数
               name: worker  # Pod的名称
               template: 
                 spec: 
                   containers: # 定义容器
                     - name: test 
                       image: busybox 
                       command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']   
                       imagePullPolicy: IfNotPresent 
                       resources:
                         requests: 
                           cpu: 1  
                           "huawei.com/ascend-1980": 8  # 申请的NPU数量，需与limits值需要保持一致，系统将根据申请NPU的数量决定Pod是否独占节点
                         limits: 
                           cpu: 1 
                           "huawei.com/ascend-1980": 8
      ```
      - requests."huawei.com/ascend-1980"表示业务Pod申请的NPU芯片数量，需与limits值需要保持一致，系统将根据该参数值以及节点中NPU芯片的数量决定Pod是否独占节点。
       
   
   2. 执行以下命令，创建上述HyperJob。
      ```
      kubectl apply -f hyper-job.yaml
      ```
      回显结果如下：
      ```
      hyperjob.batch.volcano.sh/hyperjob-test created
      ```
      
   
   3. 执行以下命令，查看HyperJob是否已创建。
      ```
      kubectl get hyperjob
      ```
      回显如下，则说明HyperJob资源已创建。
      ```
      NAME            MINAVAILABLE   AGE
      hyperjob-test   2               68s
      ```
      
   
   4. 执行以下命令，查看Volcano Job是否运行成功。
      ```
      kubectl get vcjob
      ```
      回显结果如下，则说明2个Volcano Job已成功运行，且Pod全部调度成功。
      ```
      NAME                         STATUS    MINAVAILABLE   RUNNINGS   AGE 
      hyperjob-test-vcjob-test-0   Running   2              2          2m30s 
      hyperjob-test-vcjob-test-1   Running   2              2          2m30s
      ```
      
   
   
   
   
2. 执行以下命令，查看每个Pod所在的节点IP。 
   ```
   kubectl get pod -o wide
   ```
   回显内容如下，其中NODE列表示当前Pod所在节点的IP地址。
   ```
   NAME                                  READY       STATUS    RESTARTS  AGE        IP               NODE            NOMINATED NODE   READINESS GATES 
   hyperjob-test-vcjob-test-0-worker-0   1/1         Running   0         2m56s      192.168.9.35     192.168.9.104   <none>           <none>
   hyperjob-test-vcjob-test-0-worker-1   1/1         Running   0         2m55s      192.168.9.105    192.168.9.37    <none>           <none>
   hyperjob-test-vcjob-test-1-worker-0   1/1         Running   0         2m56s      192.168.9.32     192.168.9.100   <none>           <none>
   hyperjob-test-vcjob-test-1-worker-1   1/1         Running   0         2m55s      192.168.9.202    192.168.9.75    <none>           <none>
   ```
   
   
3. 执行以下命令，查看每个Pod所在节点的"volcano.sh/hypernode"标签值，以确认同一亲和组（Volcano Job）中的Pod是否调度至同一超节点。仅超节点中的节点存在"volcano.sh/hypernode"标签值，且标签值相同则说明这些节点属于同一超节点。 
   ```
   kubectl describe node 192.168.9.104 | grep volcano.sh/hypernode
   kubectl describe node 192.168.9.37 | grep volcano.sh/hypernode
   kubectl describe node 192.168.9.100 | grep volcano.sh/hypernode
   kubectl describe node 192.168.9.75 | grep volcano.sh/hypernode
   ```
   回显结果依次如下：
   ```
   volcano.sh/hypernode=hypernode-1
   volcano.sh/hypernode=hypernode-1
   volcano.sh/hypernode=hypernode-2
   volcano.sh/hypernode=hypernode-2
   ```
   由此可知，hyperjob-test-vcjob-test-0的Pod皆已调度至hypernode-1超节点， hyperjob-test-vcjob-test-1的Pod皆已调度至hypernode-2超节点，调度结果符合超节点拓扑亲和。
   
   
