# 配置装箱调度策略
在了解装箱调度前，先了解Ray中的两类计算单元：Task与Actor，以及它们所运行的Node。
| 概念         | 说明                                                                                           |
|:---|:---|
| Task（任务）   | Ray中最基本的无状态计算单元。将一段函数逻辑放到远程节点执行一次，执行完即结束，不保留状态。                                            |
| Actor（执行器） | 有状态、长期运行的执行单元。将类实例常驻在远程节点，多次调用共享状态（如加载模型、计数）。                                               |
| 节点（Node）     | 提供计算资源的服务器，是Task、Actor运行的地方。 一个节点可承载多个Task和Actor，共享节点资源。 |
   
装箱调度（Binpack）所调度的，正是将Task和Actor这两类计算单元集中放置到资源使用率最高的可行节点上。
#### 装箱调度（Binpack）功能介绍
装箱调度（Binpack）是一种优化算法，是Ray原生调度框架的扩展，装箱调度所调度的，正是将Task和Actor这两类计算单元。旨在将Task和Actor尽可能集中调度到资源使用率最高的可行节点上，从而提高集群资源利用率。
Ray Binpack装箱调度策略的核心目标是将任务和Actor集中调度到资源利用率最高的可行节点上，通过加权资源利用率打分，选择得分最高的节点承载新任务，从而最大化资源打包密度。
与Ray默认的Hybrid（混合）策略不同，Binpack策略不会将任务均匀分散到所有节点，而是优先填满已有节点，使空闲节点得以释放，降低成本。
图1Hybrid与Binpack调度对比   
![](https://support.huaweicloud.com/usermanual-aidatalake/zh-cn_image_0000002749579642.png "点击放大")
#### 装箱调度（Binpack）算法原理
在对节点打分时，Binpack会遍历节点上的各类资源（CPU、GPU、内存等），结合各资源维度的权重值，计算出节点的Binpack得分。节点Binpack得分的计算流程如下：
1. 对每类资源依次计算利用率。 以CPU为例，CPU资源在待调度节点的利用率计算如下：
   ```
   util_cpu = 1 -（available - normal_task）/ total，其中：
   ```
   - util_cpu：CPU资源利用率，利用率越高表示节点越满。
   
   - available：当前节点CPU可用量（逻辑资源账户余额）。
   
   - normal_task：已分配但尚未实际运行的正常任务占用的CPU。
   
   - total：当前节点CPU总量。
    
2. 将利用率乘以对应权重，得到该资源的加权得分。
   ```
   score_cpu = util_cpu × CPU.weight
   ```
   即CPU权重值越高，该资源在打分时的占比越大；节点资源使用量越满，得分越高。GPU、Memory、ObjectStoreMemory等资源原理类似。
   
3. 通过取所有资源加权得分的最大值作为节点最终得分。得分最高的节点承载新的Task或Actor。
   ```
   Score = max(score_cpu, score_gpu, score_mem, score_obj_mem)
   Score = max(util_r × weight_r)
   ```
   
 
#### 配置装箱调度策略
您可以在编写作业脚本时通过指定**scheduling_strategy="BINPACK"**来配置装箱调度策略，例如文本处理脚本"ray-job-code.py"，内容示例如下：
```
import ray
import random
import time
import sys
# 连接Ray集群
ray.init()
@ray.remote(scheduling_strategy="BINPACK")
def compute_points_in_circle(num_points: int) -> int:
    inside = 0
    for _ in range(num_points):
        x, y = random.random(), random.random()
        if x*x + y*y <= 1:
            inside += 1
    return inside
def estimate_pi(total_points: int, num_workers: int = 4) -> float:
    start = time.time()
    points_per_worker = total_points // num_workers
    # 分布式执行任务
    tasks = [compute_points_in_circle.remote(points_per_worker) for _ in range(num_workers)]
    total_inside = sum(ray.get(tasks))
    pi = 4.0 * total_inside / total_points
    print(f"估算的圆周率: {pi:.6f}, 耗时: {time.time() - start:.2f}秒")
    return pi
if __name__ == "__main__":
    estimate_pi(total_points=int(sys.argv[1]), num_workers=1)
    ray.shutdown()
```
关于提交作业的完整操作，请参见：
- [基于RayCluster的数据处理](https://support.huaweicloud.com/qs-aidatalake/aidatalake_01_0004.html)
- [基于RayJob的数据处理](https://support.huaweicloud.com/qs-aidatalake/aidatalake_01_0079.html)
 
