CloudSimPy 基于离散事件仿真框架 SimPy,利用 Python 语言进行实现; Python 语言的科学计算、深度学习、机器学习生态相较于其他编程语言更加完善,CloudSimPy 可以与具有 Python 支持的深度学习框架(比如 TensorFlow,PyTorch)很好的结合,有助于研究基于机器学习或者深度学习的资源管理方法。
在 CloudSimPy/playground/Non_DAG/algorithm/DeepJS/DRL.py
中的基于深度强化学习的数据中心作业调度算法由 TensorFlow 进行实现,并在其 eager 模式下进行推断和训练。
作为数据中心作业调度仿真框架 CloudSimPy 包含两个 Python 包 core
和 playground
。
core
对数据中心作业调度问题中的各个实体(entity)进行了抽象和建模,core
包中含有以下模块:
config
中TaskInstanceConfig
、TaskConfig
、JobConfig
分别给出任务实例、任务、作业的配置(资源需求,持续时间等)job
中TaskInstance
、Task
、Job
分别是对于任务实例、任务、作业的建模machine
是对机器的建模cluster
是对于计算集群的建模,类Cluster
维护着集群的机器列表alogrithm
中定义了调度算法的接口,用户自定义的调度算法必须实现这一接口,是实现策略模式的关键scheduler
是对于调度器的建模,通过策略模式这一设计模式,不同的Scheduler
实例可以使用不同的调度算法进行调度broker
实现了类Broker
,Broker
代替用户对计算集群提交作业monitor
实现了类Monitor
,Monitor
用于在仿真过程中对仿真的状态进行监测和记录simulation
是对一次仿真的建模,一次仿真必须构造一个集群Cluster
实例;构造一系列作业配置JobConfig
实例,利用这些作业配置实例构造一个Broker
实例; 构造一个调度器Scheduler
实例。在一次仿真可以选择开是否使用一个Monitor
实例进行仿真过程的监测
playground
包设计用于方便软件包用户进行试验,主要包含 DAG
包、Non_DAG
包(分别支持考虑任务间依赖关系和不考虑任务间依赖关系情况下的仿真实验)、auxiliary
包。
DAG
与 Non_DAG
均分别预先实现了一些启发式作业调度算法及基于深度强化学习的作业调度算法。
例如在 Non_DAG/algorithm/DeepJS
中实现的基于深度强化学习的数据中心作业调度算法:
- agent 智能体,实现了强化学习中的策略梯度
- brain TensorFlow 实现的神经网络结构
- DRL 基于深度强化学习的数据中心作业调度算法
- reward_giver 强化学习奖励函数
auxiliary
包提供了一些辅助类和函数:
episode
中的Episode
类用于 episodic 方式的仿真实验tools
中的multiprocessing_run
用于多进程模式的训练;average_slowdown
和average_completion
用于从一个Episode
类的对象中抽取计算统计信息
由于在数据中心中任务实例 TaskInstance
是实际的资源消耗者也是实际业务逻辑的执行者,因此在概念上将 core
包 job
模块中的 TaskInstance
设计为一个 SimPy 中的进程(Process
),
而类 Task
设计为 TaskInstance
的集合,类 Job
设计为 Task
的集合。Job
,Task
的运行状态利用 Python 下的 property
特性实现,
并采用如下图所示的信息传递机制实现 Task
,Job
状态的合成。
当我们询问一个 Job
的状态是,Job
实例会询问它的 Task
实例们的状态,Task
实例则会去询问它们各自的 TaskInstance
实例们的状态,
Task
实例根据各自的 TaskInstance
实例们的状态合成自己的状态,然后 Job
实例根据它的 Task
实例们的状态合成自己的状态,即状态信息反向传播最终回到 Job
实例。
这样的设计不仅可以保证 Job
和 Task
状态信息的准确性和一致性,更重要的是没有在每个仿真时间步主动维护 Job
和 Task
的状态信息,
而是将 Job
和 Task
状态的获得推迟到 Job
和 Task
状态的被动询问时,这允许我们在关闭监测功能(也就是不询问 Job
和 Task
的状态)时让仿真快速高效的进行。
被动询问取代主动维护,实现了仿真过程中 hotpath 的优化,让 hotpath 上的执行的操作尽可能的少尽可能的快。
除了 TaskInstance
在概念上设计为一个 SimPy 进程,Broker
、Scheduler
、Monitor
也被设计为 SimPy 进程。
Broker
进程不断地按照作业的提交时间将作业配置列表所描述的作业提交至集群 Cluster
实例,直至所有的作业提交完毕,Broker
停止提交并销毁。
Scheduler
按照调度时间步不断地进行调度,直到仿真 Simulation
被标记为结束(当 Broker
被销毁(即不会有新的作业到达)且所有已提交的作业都执行完毕时,
Simulation
被标记为结束)。Monitor
按照监测时间步不断地进行仿真状态的监测和记录,直到仿真 Simulation
被标记为结束。
另外的数据中心作业调度问题中的实体 Simulation
,Cluster
,Machine
,Task
,Job
就是普通的类的概念,仅仅作为相关信息的管理器。
策略模式是一种行为设计模式,在策略模式中定义一系列算法,将每个算法放入一个单独的类中,并使这些类的对象可相互互换。
在策略模式中,我们有一个类,它可以以不同方式执行特定操作,比如此处的调度器 Scheduker
类它可以以不同的调度算法(调度策略)执行调度,我们可以将所有这些算法提取到一个个称为策略的单独的类中。原始类(称为上下文)持有一个对策略的引用,并将工作委托给该策略,而不是自己去直接执行工作。原始类不负责选择适当的算法,相反,用户将所需的策略传递给它。事实上,原始类对策略知之甚少,它通过相同的通用的接口调用所有的策略。
这样,上下文就变得独立于具体策略,我们可以添加新算法或修改现有算法,而无需更改原始类或其他策略的代码。
通过使用策略设计模式,在 CloudSimPy 中将 Scheduler
的实现和 Scheduler
所使用的调度算法的实现独立开来,
并分别放在了 core
包中和 playground/DAG/algorithm
、playground/Non_DAG/algorithm
包中。
在layground/DAG/algorithm/DeepJS/reward_giver.py
中也使用了策略模式为具有不同优化目标的基于深度强化学习的作业调度模型提供不同的奖励计算方法:
- MakespanRewardGiver 给出用于优化完工时间(Makespan)的奖励
- AverageSlowDownRewardGiver 给出用于优化平均 SlowDown 的奖励
- AverageCompletionRewardGiver 给出用于优化平均完成时间的奖励
- Python 3.6
- SimPy 3.0.11
- TensorFlow 1.12.0
- Numpy 1.15.3
- Pandas 0.23.4
git clone git@github.com:RobertLexis/CloudSimPy.git
- Add the path to directory cloudsimpy to system environment PYTHONPATH
cd cloudsimpy/playground/Non_DAG/launch_scripts
python main-makespan.py