大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE稳定放心使用
Cloudsim 3.0.3中VM调度策略系列类解析(带迁移的策略)
注:本文为旧文的markdown重制版
Cloudsim中VM调度策略类在DataCenter(或PowerDataCenter)创建时需要制定,更是我们在Cloudsim上试验我们的调度算法的核心所在。
CloudSim中给出了VmAllocationPolicy抽象类,还有提供了一个VmAllocationPolicySimple简单调度策略类,其介绍见前一篇关于“无迁移”VM放置策略的blog。
另外,Cloudsim3.0.3中提供了Power系列包(在之前几篇blog中提到的诸如PowerHost, PowerDataCenter等),自然也有对应的Policy类,并且丰富得多。Power系列包里面有三种Policy:
第一种是PowerVmAllocationPolicyAbstract(继承VmAllocationPolicy)及其子类:是没有迁移的调度策略;提供的接口基本与父类VmAllocationPolicy一致,实现并增加了一些方法。
第二种是PowerVmAllocationPolicyMigrationAbstract(本身继承第一种)及其子类:带有VM迁移的调度策略。
第三种是PowerVmSelectionPolicy及其子类:这个selection是指选择“需要迁移”的VM,所以这些类用来在执行VM migration时选择VM。
第一种策略不支持迁移,与与父类VmAllocationPolicy基本上一致,在上一篇blog中介绍了。
本文要介绍带有迁移行为的策略,即第二种;而带迁移的VM调度策略的实现需要vm selection策略的支持(即第三种),所以先介绍第三种——VM selection策略。
(编号续上一篇博客)
3、public abstract class PowerVmSelectionPolicy
继承:无
成员:无
重要方法:
-
public abstract Vm getVmToMigrate(PowerHost host):在host主机上找一个合适的VM准备迁移,是抽象方法,在该抽象类中无实现;
-
protected List getMigratableVms(PowerHost host):有实现,用来在host上获取可迁移的Vm(必须是PowerVm),可迁移=不处在迁移状态
本文选择一个有代表性的VM selection策略的实现——PowerVmSelectionPolicyMinimumUtilization来介绍
3-a、public class PowerVmSelectionPolicyMinimumUtilization
继承:public abstract class PowerVmSelectionPolicy
增加的成员:无
重要方法:
- @Override
public Vm getVmToMigrate(PowerHost host):首先获取host上可迁移的vm列表,在该列表中遍历vm,最终返回CPU利用率最低的那个vm。
选择完该迁移的VM后,就是要选择目标主机并完成迁移操作,这些内容包含在PowerVmAllocationPolicyMigrationAbstract及其子类中。
4、public abstract class PowerVmAllocationPolicyMigrationAbstract
继承:PowerVmAllocationPolicyAbstract,也就是说分配策略也有所实现
增加的成员:
-
private PowerVmSelectionPolicy vmSelectionPolicy:采用的VM selection策略
-
private final List< Map< String, Object>> savedAllocation:存储vm -> host的映射列表
-
private final Map< Integer, List< Double>> utilizationHistory:
-
private final Map< Integer, List< Double>> metricHistory:
-
private final Map< Integer, List< Double>> timeHistory:
-
private final List< Double> executionTimeHistoryVmSelection:记录vm selection操作的用时
-
private final List< Double> executionTimeHistoryHostSelection:记录host selection操作的用时
增加的重要方法:
-
@Override
public List< Map< String, Object>> optimizeAllocation(List< ? extends Vm> vmList):重载了父类方法,实现VM迁移计划的制定(PowerDC.updateCloudletProcess(…)根据其返回的migrationMap进行实质性的VM迁移操作)。该方法的过程大致是:先调用getOverUtilizedHosts()获取过载的主机,再调用getVmsToMigrateFromHosts(overhosts)从这些过载主机上获取适合被迁出的VM列表,然后调用getNewVmPlacement(vmsToMigrate, overUtilizedHosts)来进行过载主机上上的VM迁移(填写迁移列表migrationMap),再接着调用getMigrationMapFromUnderUtilizedHosts()来进行“过闲”主机上的VM迁移(补充迁移列表migrationMap);该函数中没有实际迁移VM,没有修改全局的savedAllocation,最终该函数返回迁移列表migrationMap。 -
protected List< Map< String, Object>> getMigrationMapFromUnderUtilizedHosts(
overUtilizedHosts):该方法的功能是返回一个migrationMap,是制定从“过闲”主机上迁移VM到其它主机的迁移方案。传入参数是过载主机列表(有点奇怪),但其作用是作为“被排除元素”,即VM不会从上面被迁出(因为该函数只处理“过闲”主机)和迁入(这是自然)。 该方法的过程大致是:先建立两个excluded列表(不可迁出列表、不可迁入列表),两个列表都初始化为过载主机+关闭的主机;接下来该方法循环调用getUnderUtilizedHost()方法来获得“过闲”主机对象,并调用getVmsToMigrateFromUnderUtilizedHost(underUtilHost)方法获得该主机上适合迁移的VM对象,再调用getNewVmPlacementFromUnderUtilizedHost(vm, 不可迁入列表)来获得最终的调度方案并加入migrationMap中。值得一提的是,每个“过闲”主机只被处理一次就被放进不可迁出列表,即一台主机只能最多迁出一台VM。 -
protected abstract boolean isHostOverUtilized(PowerHost host):看样子是用来判断主机是否过载,是个抽象方法,没有实现
-
public PowerHost findHostForVm( Vm vm, Set< ? extends Host> excludedHosts):为vm寻找一个最佳主机,最佳=vm在其上功耗最小=放置vm前后功耗差最小。遍历主机列表时,首先跳过在excludedHosts里的主机以及放置vm会导致过载的主机(利用getPowerAfterAllocation(vm, PowerHost)来判断),遍历完后找到最佳主机并返回。
-
@Override
public PowerHost findHostForVm(Vm vm)
:通过调用上面的方法来寻找最佳主机。vm现在无主时,等同于上面那个方法;有主时,自然要exclude掉现在的宿主机。 -
protected boolean isHostOverUtilizedAfterAllocation(PowerHost host, Vm vm):用来判断vm放置到目标主机是否会导致过载。过程:调用host.vmCreate(vm)在host上创建vm(只创建,无事件),判断是否过载(利用isHostOverUtilized(host)),再调用host.vmDestroy(vm)销毁vm。
-
protected List extractHostListFromMigrationMap(List< Map< String, Object>> migrationMap):从传入的migrationMap中提取主机列表;
-
protected List< Map< String, Object>> getNewVmPlacement( vmsToMigrate,
excludedHosts) :为传入的VM列表制定放置计划。该方法的大致过程是:先按CPU利用率(in MIPS)降序排列vm列表,然后遍历该vm列表,调用findHostForVm(vm,excludedHosts)获得分配方案。 -
protected List< Map< String, Object>> getNewVmPlacementFromUnderUtilizedHost( vmsToMigrate,excludedHosts) :名不副实,该方法与“过闲”主机无关,该方法基本等同于上面那个方法,不过更加科学,增加了一个判断:如果vmsToMigrate中有一个vm放置失败,则取消当前整个放置方案,即不会有副作用。
-
protectedList< ? extends Vm>
getVmsToMigrateFromHosts(Hosts) :从指定的hosts列表中获取适合迁出的VM列表,主要就是借助PowerVmSelectionPolicy类。过程是:遍历传入的Hosts列表,调用getVmSelectionPolicy().getVmToMigrate(host)来逐个主机的寻找适合迁出的VM。 -
protected List< ? extends Vm> getVmsToMigrateFromUnderUtilizedHost(host):从目标主机(针对过闲的,该想办法关机的)中获取适合迁出的VM,该方法返回host上所有的VM,除了已经在迁移的。
-
protected List< PowerHostUtilizationHistory> getOverUtilizedHosts():获取过载主机列表,自然是借助isHostOverUtilized(host)方法(该方法要在子类中实现),这里返回的是PowerHostUtilizationHistory对象列表(其实PowerHost, PowerHostUtilizationHistory都没有增加关于利用率的成员,是HostDynamicWorkload中提供的)。
-
protected PowerHost getUnderUtilizedHost(Set< ? extends Host> excludedHosts):返回最闲的那台的主机,排除掉excludedHosts和其上所有VM都处于迁移态的主机。
-
protected List< PowerHost> getSwitchedOffHosts():获取关机的主机,判定方法是host.getUtilizationOfCpu() == 0。
-
protected double getPowerAfterAllocation(PowerHost host, Vm vm):预估将vm分配给host之后,该host的功耗,是通过调用getMaxUtilizationAfterAllocation(host, vm)先预估利用率,再用powerModel成员来估算得到。
-
protected double getMaxUtilizationAfterAllocation(PowerHost host, Vm vm):预估将vm分配给host之后,该host的CPU利用率(%)
-
protected double getUtilizationOfCpuMips(PowerHost host):以特殊对待正在迁移的VM的方式计算一台host的CPU占用。先获取host上的VM列表,如果vm是在迁入状态,则它的mips*9,否则mips*1。累加得host的CPU占用(in MIPS)。这里似乎认为迁入十分耗资源,算出来的结果应会远大于host对象调用host.getUtilizationMips()方法。
-
protected void saveAllocation():保存当前所有VM->host的映射关系到成员savedAllocation,VM->host的映射信息从各个host对象处读取,正在迁入的VM会被跳过。这个方法在optimizeAllocation()中被调用,用于在getVmsToMigrateFromHosts(overUtilHosts)(该方法会在相应主机销毁vm)之前保存映射。
-
protected void restoreAllocation():从成员savedAllocation中提取所有VM->host的映射关系。所以该方法先遍历所有主机销毁所有VM(无事件),为正在迁入的VM分配资源,然后按savedAllocation记录的映射逐条创建VM(无事件)。这个方法在optimizeAllocation()中被调用,用于在getNewVmPlacement(…)(该方法会在相应主机创建VM)之后恢复映射。 配合上面那个save函数,两个函数的结合使得optimizeAllocation()对数据中心内的VM分配的修改是无效的(应该是仅用于统计效率),真正完成VM迁移的是optimizeAllocation()函数返回migrationMap之后,PowerDC.updateCloudletProcessing()发送一个包含migrationMap的事件, 然后根据Cloudsim的那套事件机制最终交由PowerDC.processVmMigrate()方法完成。
Note: 我们在编写VM迁移方面的自定义逻辑时,就是修改optimizeAllocation()方法的内容,而该方法由相关方法组合而成,包括:
**寻找迁出主机相关方法:**isHostOverUtilized()、getOverUtilizedHosts()、getUnderUtilizedHost()等;
**从迁出主机上选择VM:**getVmsToMigrateFromHosts()、getVmsToMigrateFromUnderUtilizedHost(),同时涉及到PowerVmSelectionPolicy类的二次开发。
**为迁出的VM选择迁入主机:**getNewVmPlacement(vmsToMigrate, excludedHosts)、getMigrationMapFromUnderUtilizedHosts()以及最核心的findHostForVm(vm, excludedHosts)
现在来看PowerVmAllocationPolicyMigrationAbstract的一些子类,这些子类增加内容都较少,因为父类虽然是Abstract,但实现了绝大多数逻辑。有心的同学就会发现,在查找适合迁出的主机时,有个重要的判定方法在父类未实现——isHostOverUtilized()。
所有的子类(比如static_threshold迁移策略、localRegression迁移策略)基本都是重载了 isHostOverUtilized()方法,其它改动很少,这说明CloudSim给出的几个迁移策略主要关注迁出。
下面以static_threshold迁移策略为例:
4-a、public class PowerVmAllocationPolicyMigrationStaticThreshold
继承:PowerVmAllocationPolicyMigrationAbstract
增加成员:private double utilizationThreshold = 0.9; 过载阈值
增加的重要方法:
- @Override
protected boolean isHostOverUtilized(PowerHost host):判定这个host有没有过载。实现方法是遍历host.getVmList(),累加mips然后除以host.getTotalMips()得到主机利用率(其实应该可以直接调用PowerHost的计算CPU利用率的方法),若该值>utilizationThreshold ,则判定超载。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/183319.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...