この方法getNextAvailableVm()
では、ラウンドロビン方式で特定のデータ センターに仮想マシンを割り当てます。(このメソッドによって返される整数は、割り当てられたマシンです)
データセンターには、構成の異なる仮想マシンが存在する可能性があります。例えば :
5 VMs with 1024 memory
4 VMs with 512 memory
Total : 9 VMs
このデータ センターでは、1024 メモリのマシンは、512 メモリのマシンと比較して 2 倍のタスクを取得します。
したがって、このデータ センターのマシンはgetNextAvailableVm()
、次のように返されます。
0 0 1 1 2 2 3 3 4 4 5 6 7 8
これが現在の方法であり、マシンは返却されています。しかし、問題があります。
特定のマシンがビジーで、タスクを割り当てることができない場合があります。代わりに、最高のメモリで利用可能な次のマシンにタスクを割り当てる必要があります。私はこれを実装できませんでした。
例えば :
0 (allotted first time)
0 (to be allotted the second time)
but if 0 is busy..
allot 1 if 1 is not busy
next circle check if 0 is busy
if not busy allot 0 (only when machine numbered 0 has not handled the requests it is entitled to handle)
if busy, allot the next
cloudSimEventFired
次のクラスのメソッドは、マシンが解放されるか割り当てられるたびに呼び出されます。
public class TempAlgo extends VmLoadBalancer implements CloudSimEventListener {
/**
* Key : Name of the data center
* Value : List of objects of class 'VmAllocationUIElement'.
*/
private Map<String,LinkedList<DepConfAttr>> confMap = new HashMap<String,LinkedList<DepConfAttr>>();
private Iterator<Integer> availableVms = null;
private DatacenterController dcc;
private boolean sorted = false;
private int currentVM;
private boolean calledOnce = false;
private boolean indexChanged = false;
private LinkedList<Integer> busyList = new LinkedList<Integer>();
private Map<String,LinkedList<AlgoAttr>> algoMap = new HashMap<String, LinkedList<AlgoAttr>>();
private Map<String,AlgoHelper> map = new HashMap<String,AlgoHelper>();
private Map<String,Integer> vmCountMap = new HashMap<String,Integer>();
public TempAlgo(DatacenterController dcb) {
confMap = DepConfList.dcConfMap;
this.dcc = dcb;
dcc.addCloudSimEventListener(this);
if(!this.calledOnce) {
this.calledOnce = true;
// Make a new map using dcConfMap that lists 'DataCenter' as a 'key' and 'LinkedList<AlgoAttr>' as 'value'.
Set<String> keyst =DepConfList.dcConfMap.keySet();
for(String dataCenter : keyst) {
LinkedList<AlgoAttr> tmpList = new LinkedList<AlgoAttr>();
LinkedList<DepConfAttr> list = dcConfMap.get(dataCenter);
int totalVms = 0;
for(DepConfAttr o : list) {
tmpList.add(new AlgoAttr(o.getVmCount(), o.getMemory()/512, 0));
totalVms = totalVms + o.getVmCount();
}
Temp_Algo_Static_Var.algoMap.put(dataCenter, tmpList);
Temp_Algo_Static_Var.vmCountMap.put(dataCenter, totalVms);
}
this.algoMap = new HashMap<String, LinkedList<AlgoAttr>>(Temp_Algo_Static_Var.algoMap);
this.vmCountMap = new HashMap<String,Integer>(Temp_Algo_Static_Var.vmCountMap);
this.map = new HashMap<String,AlgoHelper>(Temp_Algo_Static_Var.map);
}
}
@Override
public int getNextAvailableVm() {
synchronized(this) {
String dataCenter = this.dcc.getDataCenterName();
int totalVMs = this.vmCountMap.get(dataCenter);
AlgoHelper ah = (AlgoHelper)this.map.get(dataCenter);
int lastIndex = ah.getIndex();
int lastCount = ah.getLastCount();
LinkedList<AlgoAttr> list = this.algoMap.get(dataCenter);
AlgoAttr aAtr = (AlgoAttr)list.get(lastIndex);
indexChanged = false;
if(lastCount < totalVMs) {
if(aAtr.getRequestAllocated() % aAtr.getWeightCount() == 0) {
lastCount = lastCount + 1;
this.currentVM = lastCount;
if(aAtr.getRequestAllocated() == aAtr.getVmCount() * aAtr.getWeightCount()) {
lastIndex++;
if(lastIndex != list.size()) {
AlgoAttr aAtr_N = (AlgoAttr)list.get(lastIndex);
aAtr_N.setRequestAllocated(1);
this.indexChanged = true;
}
if(lastIndex == list.size()) {
lastIndex = 0;
lastCount = 0;
this.currentVM = lastCount;
AlgoAttr aAtr_N = (AlgoAttr)list.get(lastIndex);
aAtr_N.setRequestAllocated(1);
this.indexChanged = true;
}
}
}
if(!this.indexChanged) {
aAtr.setRequestAllocated(aAtr.getRequestAllocated() + 1);
}
this.map.put(dataCenter, new AlgoHelper(lastIndex, lastCount));
//System.out.println("Current VM : " + this.currentVM + " for data center : " + dataCenter);
return this.currentVM;
}}
System.out.println("--------Before final return statement---------");
return 0;
}
@Override
public void cloudSimEventFired(CloudSimEvent e) {
if(e.getId() == CloudSimEvents.EVENT_CLOUDLET_ALLOCATED_TO_VM) {
int vmId = (Integer) e.getParameter(Constants.PARAM_VM_ID);
busyList.add(vmId);
System.out.println("+++++++++++++++++++Machine with vmID : " + vmId + " attached");
}else if(e.getId() == CloudSimEvents.EVENT_VM_FINISHED_CLOUDLET) {
int vmId = (Integer) e.getParameter(Constants.PARAM_VM_ID);
busyList.remove(vmId);
//System.out.println("+++++++++++++++++++Machine with vmID : " + vmId + " freed");
}
}
}
上記のコードでは、すべてのリストがメモリの多い順に並べ替えられています。メモリの多いマシンにより多くのタスクを割り当てることで、メモリのバランスをとります。
マシンが割り当てられるたびに、割り当てられたリクエストは 1 ずつ増加します。マシンの各セットには、 で割って計算される重みカウントが関連付けられていmemory_allotted
ます512
。
メソッドgetNextAvailableVm()
は、一度に複数のスレッドによって呼び出されます。3 つのデータ センターの場合、3 つのスレッドが同時に呼び出されますgetNextAva...()
が、異なるクラス オブジェクトで呼び出されます。同じメソッド内のステートメントによって返されるデータ センターは、前に選択したデータ センター ブローカー ポリシーthis.dcc.getDataCenterName()
に従って返されます。
現在返却しているマシンが空いていることを確認するにはどうすればよいですか。マシンが空いていない場合は、使用可能なメモリが最も大きい次のマシンを割り当てます。また、タスクを処理する資格のあるマシンがタスクを処理することも確認する必要がありX
ます。X
そのマシンでさえ現在ビジーです。
これは、ここで使用されるデータ構造の一般的な説明です:
このクラスのコードはgithubでホストされています。
これはgithubの完全なプロジェクトへのリンクです。
ここで使用されるデータ構造/クラスのほとんどは、このパッケージ内にあります