二、Cloudsim 示例源码阅读笔记 以ThrRs示例
2.1 基本内容
位置:org.cloudbus.cloudsim.examples.power.planetlab中的ThrRs.java
功能:对异构功耗感知数据中心的仿真,该数据中心应用静态阈值THR虚拟机分配策略 + 随机RS虚拟机选择策略

2.2 参数设置 + 云任务/虚机/主机初始化
由于第一个案例的讲解,后面基本差不太多,只要知道核心流程即可,具体代码见源码
public class ThrRs {
/**
* The main method.
*
* @param args the arguments
* @throws IOException Signals that an I/O exception has occurred.
*/
public static void main(String[] args) throws IOException {
boolean enableOutput = true;
boolean outputToFile = false;
String inputFolder = NonPowerAware.class.getClassLoader().getResource("workload/planetlab").getPath();
String outputFolder = "output";
String workload = "20110303"; // PlanetLab workload
String vmAllocationPolicy = "thr"; // 虚拟机分配策略--静态阈值(THR):主机高于某个
String vmSelectionPolicy = "rs"; // VM选择策略--随机选择(RS)
String parameter = "0.8"; // the static utilization threshold
new PlanetLabRunner(
enableOutput,
outputToFile,
inputFolder,
outputFolder,
workload,
vmAllocationPolicy,
vmSelectionPolicy,
parameter);
}
}
2.3 获取虚拟机选择策略
PlanetLabRunner继承了RunnerAbstract, 我们可以在RunnerAbstract 的 getVmSelectionPolicy 看到获取虚拟机选择策略
protected PowerVmSelectionPolicy getVmSelectionPolicy(String vmSelectionPolicyName) {
PowerVmSelectionPolicy vmSelectionPolicy = null;
if (vmSelectionPolicyName.equals("mc")) {
vmSelectionPolicy = new PowerVmSelectionPolicyMaximumCorrelation(
new PowerVmSelectionPolicyMinimumMigrationTime());
} else if (vmSelectionPolicyName.equals("mmt")) {
vmSelectionPolicy = new PowerVmSelectionPolicyMinimumMigrationTime();
} else if (vmSelectionPolicyName.equals("mu")) {
vmSelectionPolicy = new PowerVmSelectionPolicyMinimumUtilization();
} else if (vmSelectionPolicyName.equals("rs")) {
vmSelectionPolicy = new PowerVmSelectionPolicyRandomSelection();
} else {
System.out.println("Unknown VM selection policy: " + vmSelectionPolicyName);
System.exit(0);
}
return vmSelectionPolicy;
- 先获取可迁移虚机列表
- 再从中随机选取一个虚机作为返回值
public class PowerVmSelectionPolicyRandomSelection extends PowerVmSelectionPolicy {
@Override
public Vm getVmToMigrate(PowerHost host) {
// 获取可迁移的VM list
List<PowerVm> migratableVms = getMigratableVms(host);
if (migratableVms.isEmpty()) {
return null;
}
// 从可迁移的VM中随机选取一个VM作为返回值
int index = (new Random()).nextInt(migratableVms.size());
return migratableVms.get(index);
}
}
2.4 设置虚拟机分配策略
同样在在RunnerAbstract 的 getVmAllocationPolicy方法中

PowerVmAllocationPolicyMigrationStaticThreshold继承自 PowerVmAllocationPolicyMigrationAbstract

进一步发现只是设置接口中的vmSelectionPolicy全局参数而已,具体在哪里会用到?以及是怎么用的呢?答案就在该接口对应的optimizeAllocation方法中,由于核心分配逻辑在该函数中,接下来,我们重点剖析optimizeAllocation方法

2.5 optimizeAllocation源码剖析
位置:org.cloudbus.cloudsim.power.PowerVmAllocationPolicyMigrationAbstract
【函数功能】:按CPU利用率检测出过载主机,然后进行过载主机上的虚机重分配(迁移),返回迁移后所有虚机和主机的最新映射
- 获取CPU利用率过载的物理机列表(eg.>80%)——
overUtilizedHosts - 由过载物理机列表和虚机选择策略,返回要迁移的虚机列表
vmsToMigrate(执行后消除迁移虚机和原主机映射,使转为不过载状态) - 根据要迁移的虚机列表,选择除原过载主机以外合适的主机进行迁移,返回迁入后新增的
<迁入虚机, 目标主机>映射容器 - 将其他
<虚机, 非过载主机>映射与新增映射合并到同一容器中返回
简化代码如下
@Override
public List<Map<String, Object>> optimizeAllocation(List<? extends Vm> vmList) {
// 获取CPU利用率过载的的物理机列表
List<PowerHostUtilizationHistory> overUtilizedHosts = getOverUtilizedHosts();
// 由过载物理机列表和虚机选择策略,返回要迁移的虚机列表`vmsToMigrate`(执行后消除迁移虚机和原主机映射,使转为不过载状态)
List<? extends Vm> vmsToMigrate = getVmsToMigrateFromHosts(overUtilizedHosts);
// 根据要迁移的虚机列表,选择除原过载主机以外合适的主机进行迁移,返回迁入后新增的<迁入虚机, 目标主机>映射容器
List<Map<String, Object>> migrationMap = getNewVmPlacement(vmsToMigrate, new HashSet<Host>(
overUtilizedHosts));
//将其他<虚机, 非过载主机>映射与新增映射合并到同一容器中返回
migrationMap.addAll(getMigrationMapFromUnderUtilizedHosts(overUtilizedHosts));
return migrationMap;
}
接下来让我们进一步分析代码中各个方法的内部机制
2.5.1 过载主机检测策略 —THR(0.8)
过载主机检测法——THR(0.8)'
- 返回过载主机列表:
overUtilizedHosts

@Override
protected boolean isHostOverUtilized(PowerHost host) {
addHistoryEntry(host, getUtilizationThreshold());
double totalRequestedMips = 0;
for (Vm vm : host.getVmList()) {
totalRequestedMips += vm.getCurrentRequestedTotalMips();
}
double utilization = totalRequestedMips / host.getTotalMips();
return utilization > getUtilizationThreshold();
}
我们可以看到阈值设置成0.8(可以根据需要修改)

2.5.2 选择待迁移虚机(从过载主机中依vmSelectionPolicy策略)—RS
此处用到之前传入的虚机选择策略——vmSelectionPolicy = 'rs'
- 返回过载主机上要迁移的虚机列表:
vmsToMigrate

2.5.3 选择目标迁入主机(选择除原过载主机以外合适主机进行迁移)
此处用到虚机分配策略——vmAllocationPolicy 本质为 最先降序分配(First-Fit-Decrease, FFD)
- 返回迁入后新增的
<迁入虚机, 目标主机>映射容器:migrationMap
算法:
- 根据CPU利用率降序排序待迁移的虚机集合
- 从excludedHosts以外的主机选择适合迁入该虚机的主机
- 将虚机迁移到目标主机上
- 保存迁入虚机和该主机的映射
我们来到 getNewVmPlacement方法

- 选择迁入后
剩余资源最少的主机作为目标主机,可见该虚机分配策略为最先降序分配(First-Fit-Decrease, FFD)法
public PowerHost findHostForVm(Vm vm, Set<? extends Host> excludedHosts) {
double minPower = Double.MAX_VALUE;
PowerHost allocatedHost = null;
// 从数据中心所有主机中选择不含过载的主机 && 迁移VM后不过载的主机
for (PowerHost host : this.<PowerHost> getHostList()) {
//排除过载主机
if (excludedHosts.contains(host)) {
continue;
}
if (host.isSuitableForVm(vm)) {
// if 主机是开机状态 && 迁入虚拟机后会过载,then 跳过
if (getUtilizationOfCpuMips(host) != 0 && isHostOverUtilizedAfterAllocation(host, vm)) {
continue;
}
try {
double powerAfterAllocation = getPowerAfterAllocation(host, vm);
if (powerAfterAllocation != -1) {
// 选择迁入后剩余资源最少的主机迁入主机
double powerDiff = powerAfterAllocation - host.getPower();
if (powerDiff < minPower) {
minPower = powerDiff;
allocatedHost = host;
}
}
} catch (Exception e) {
}
}
}
return allocatedHost;
}
2.6 运行结果
运行ThrRs, 部分运行结果如下图所示
