CloudSim源码分析之虚拟机分配策略(VmAllocationPolicy)
虚拟机分配是指根据特定的分配策略在满足一定条件的物理机上创建虚拟机。CloudSim只是实现了简单的虚拟机分配策略,默认情况下直接使用FCFS策略为主机分配虚拟机。VmAllocationPolicy是虚拟机分配策略的抽象类,CloudSim开发者推荐研究人员根据需求的特定场景实现自己的虚拟机分配策略,需要实现VmAllocationPolicy抽象类。
目前CloudSim通过VmAllocationPolicySimple类实现虚拟机分配, 方法allocateHostForVm(Vm vm)是该类的核心,它实现了从主机列表中选择一台物理机,并在其上创建虚拟机vm。主要实现过程的描述如下:
(1) 记录下所有物理机可用的处理器核心数。
(2) 从中选出可用处理器核心数最多的第一台物理机,并尝试在其上创建虚拟机。
(3) 如果(2)失败了且还有物理机没有尝试过,就排除当前选择的这台物理机,重做(2)。
(4) 根据虚拟机是否创建成功,返回true或false。
(5) 如果返回true,更新虚拟机ID与物理机映射,更新虚拟机ID与使用的PE数映射,更新物理机空闲PE数。
-
/*******VmAllocationPolicySimple源码分析******/
-
public class VmAllocationPolicySimple extends VmAllocationPolicy {
-
-
/** The vm table. */
-
// 保存虚拟机ID与物理机的映射
-
-
private Map<String, Host> vmTable;
-
-
/** The used pes. */
-
// 保存虚拟机ID与分配的PE数映射
-
-
private Map<String, Integer> usedPes;
-
-
/** The free pes. */
-
// 保存每台物理机可用的PE数
-
-
private List<Integer> freePes;
-
-
/**
-
* Creates the new VmAllocationPolicySimple object.
-
*
-
* @param list the list
-
* @pre $none
-
* @post $none
-
*/
-
public VmAllocationPolicySimple(List<? extends Host> list) {
-
super(list); // 设置物理机列表
-
-
-
setFreePes(new ArrayList<Integer>());
-
// 获取每台主机的可用PE数
-
-
for (Host host : getHostList()) {
-
getFreePes().add(host.getNumberOfPes());
-
-
}
-
-
// 初始化VmTable和usedPes
-
-
setVmTable(new HashMap<String, Host>());
-
setUsedPes(new HashMap<String, Integer>());
-
}
-
-
/**
-
* Allocates a host for a given VM.
-
*
-
* @param vm VM specification
-
* @return $true if the host could be allocated; $false otherwise
-
* @pre $none
-
* @post $none
-
*/
-
// 为虚拟机分配一台物理机
-
-
@Override
-
public boolean allocateHostForVm(Vm vm) {
-
int requiredPes = vm.getNumberOfPes(); // 获取该虚拟机需要的PE数
-
-
boolean result = false;
-
int tries = 0; // 分配物理机的失败次数
-
-
List<Integer> freePesTmp = new ArrayList<Integer>();
-
for (Integer freePes : getFreePes()) { // 临时保存每台物理机可用的PE数
-
-
freePesTmp.add(freePes);
-
}
-
-
// 如果该虚拟机没有分配物理机,尝试为其分配物理机
-
-
if (!getVmTable().containsKey(vm.getUid())) { // if this vm was not created
-
-
do {// we still trying until we find a host or until we try all of them
-
-
int moreFree = Integer.MIN_VALUE; // 最小整数(为了保存可用PE数最大值)
-
-
int idx = -1; // 保存物理机ID
-
-
-
// we want the host with less pes in use
-
-
// 获取可用PE数最大的物理机ID
-
-
for (int i = 0; i < freePesTmp.size(); i++) {
-
if (freePesTmp.get(i) > moreFree) {
-
moreFree = freePesTmp.get(i);
-
idx = i;
-
}
-
}
-
-
// 获取可用PE数最大的物理机,并尝试在其上创建虚拟机
-
-
Host host = getHostList().get(idx);
-
result = host.vmCreate(vm); // 虚拟创建(后续会深入分析)
-
-
-
if (result) { // if vm were succesfully created in the host
-
-
// 如果虚拟机创建成功,更新虚拟机ID与物理机映射,更新虚拟机ID与使用的PE数映射,更新物理机空闲PE数
-
-
getVmTable().put(vm.getUid(), host);
-
getUsedPes().put(vm.getUid(), requiredPes);
-
getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
-
result = true;
-
break;
-
} else {
-
// 如果分配失败(还没看完其他代码,猜测可能失败的情况有:虽然物理机的PE数满足该虚拟机需求,但是其他资源可能不满足,如内存、存储等。),
-
-
// 则将该物理机的可用PE数设置为整数最小值(只是在临时列表中设置),从而排除该物理机。
-
-
freePesTmp.set(idx, Integer.MIN_VALUE);
-
}
-
tries++;
-
} while (!result && tries < getFreePes().size());
-
-
}
-
-
return result;
-
}
-
-
/**
-
* Releases the host used by a VM.
-
*
-
* @param vm the vm
-
* @pre $none
-
* @post none
-
*/
-
// 销毁虚拟机
-
-
@Override
-
public void deallocateHostForVm(Vm vm) {
-
Host host = getVmTable().remove(vm.getUid()); // 删除该虚拟机与物理机的映射关系
-
-
int idx = getHostList().indexOf(host);
-
int pes = getUsedPes().remove(vm.getUid()); // 删除该虚拟机与使用PE数的映射关系
-
-
if (host != null) {
-
host.vmDestroy(vm); // 销毁虚拟机(后续会深入分析)
-
-
getFreePes().set(idx, getFreePes().get(idx) + pes); // 更新物理机可用PE数
-
-
}
-
}
-
-
/**
-
* Gets the host that is executing the given VM belonging to the given user.
-
*
-
* @param vm the vm
-
* @return the Host with the given vmID and userID; $null if not found
-
* @pre $none
-
* @post $none
-
*/
-
@Override
-
public Host getHost(Vm vm) {
-
return getVmTable().get(vm.getUid());
-
}
-
-
/**
-
* Gets the host that is executing the given VM belonging to the given user.
-
*
-
* @param vmId the vm id
-
* @param userId the user id
-
* @return the Host with the given vmID and userID; $null if not found
-
* @pre $none
-
* @post $none
-
*/
-
@Override
-
public Host getHost(int vmId, int userId) {
-
return getVmTable().get(Vm.getUid(userId, vmId));
-
}
-
-
/**
-
* Gets the vm table.
-
*
-
* @return the vm table
-
*/
-
public Map<String, Host> getVmTable() {
-
return vmTable;
-
}
-
-
/**
-
* Sets the vm table.
-
*
-
* @param vmTable the vm table
-
*/
-
protected void setVmTable(Map<String, Host> vmTable) {
-
this.vmTable = vmTable;
-
}
-
-
/**
-
* Gets the used pes.
-
*
-
* @return the used pes
-
*/
-
protected Map<String, Integer> getUsedPes() {
-
return usedPes;
-
}
-
-
/**
-
* Sets the used pes.
-
*
-
* @param usedPes the used pes
-
*/
-
protected void setUsedPes(Map<String, Integer> usedPes) {
-
this.usedPes = usedPes;
-
}
-
-
/**
-
* Gets the free pes.
-
*
-
* @return the free pes
-
*/
-
protected List<Integer> getFreePes() {
-
return freePes;
-
}
-
-
/**
-
* Sets the free pes.
-
*
-
* @param freePes the new free pes
-
*/
-
protected void setFreePes(List<Integer> freePes) {
-
this.freePes = freePes;
-
}
-
-
/*
-
* (non-Javadoc)
-
* @see cloudsim.VmAllocationPolicy#optimizeAllocation(double, cloudsim.VmList, double)
-
*/
-
// 最优分配,具体不清楚
-
-
@Override
-
public List<Map<String, Object>> optimizeAllocation(List<? extends Vm> vmList) {
-
// TODO Auto-generated method stub
-
-
return null;
-
}
-
-
/*
-
* (non-Javadoc)
-
* @see org.cloudbus.cloudsim.VmAllocationPolicy#allocateHostForVm(org.cloudbus.cloudsim.Vm,
-
* org.cloudbus.cloudsim.Host)
-
*/
-
// 将虚拟机分配给特定的物理机
-
-
@Override
-
public boolean allocateHostForVm(Vm vm, Host host) {
-
if (host.vmCreate(vm)) { // if vm has been succesfully created in the host
-
-
// 如果虚拟机在指定物理机上被成功创建,更新相关数据结构,分析见allocateHostForVm(Vm vm)
-
-
getVmTable().put(vm.getUid(), host);
-
-
int requiredPes = vm.getNumberOfPes();
-
int idx = getHostList().indexOf(host);
-
getUsedPes().put(vm.getUid(), requiredPes);
-
getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
-
-
Log.formatLine(
-
"%.2f: VM #" + vm.getId() + " has been allocated to the host #" + host.getId(),
-
CloudSim.clock()); // clock()没搞清楚
-
-
return true;
-
}
-
-
return false;
-
}
-
}
阅读(7014) | 评论(0) | 转发(3) |