org.btrplace.examples.SolverTuning Maven / Gradle / Ivy
/*
* Copyright (c) 2017 University Nice Sophia Antipolis
*
* This file is part of btrplace.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*/
package org.btrplace.examples;
import org.btrplace.model.*;
import org.btrplace.model.constraint.Overbook;
import org.btrplace.model.constraint.Preserve;
import org.btrplace.model.constraint.SatConstraint;
import org.btrplace.model.view.ShareableResource;
import org.btrplace.plan.ReconfigurationPlan;
import org.btrplace.plan.event.MigrateVM;
import org.btrplace.scheduler.SchedulerException;
import org.btrplace.scheduler.choco.ChocoScheduler;
import org.btrplace.scheduler.choco.DefaultChocoScheduler;
import org.btrplace.scheduler.choco.duration.LinearToAResourceActionDuration;
import java.util.*;
/**
* Tutorial about the basic tuning of a {@link org.btrplace.scheduler.choco.ChocoScheduler}.
*
* @author Fabien Hermenier
* @see btrplace website
*/
@SuppressWarnings("squid:S106")
public class SolverTuning implements Example {
private List nodes;
@Override
public String toString() {
return "Solver Tuning";
}
@Override
@SuppressWarnings("squid:S1166")
public void run() {
//Make a default model with 500 nodes hosting 3,000 VMs
Model model = makeModel();
Set constraints = new HashSet<>();
//We allow memory over-commitment with a overbooking ratio of 50%
//i.e. 1MB physical RAM for 1.5MB virtual RAM
constraints.addAll(Overbook.newOverbooks(model.getMapping().getAllNodes(), "mem", 1.5));
/**
* On 10 nodes, 4 of the 6 hosted VMs ask now for a 4GB bandwidth
*/
for (int i = 0; i < 5; i++) {
Node n = nodes.get(i);
Set vmsOnN = model.getMapping().getRunningVMs(n);
Iterator ite = vmsOnN.iterator();
for (int j = 0; ite.hasNext() && j < 4; j++) {
VM v = ite.next();
constraints.add(new Preserve(v, "bandwidth", 4));
}
}
ChocoScheduler cra = new DefaultChocoScheduler();
//Customize the estimated duration of actions
cra.getDurationEvaluators().register(MigrateVM.class, new LinearToAResourceActionDuration("mem", 1, 3));
//We want the best possible solution, computed in up to 5 sec.
cra.doOptimize(true);
cra.setTimeLimit(5);
//We solve without the repair mode
cra.doRepair(false);
try {
solve(cra, model, constraints);
} catch (SchedulerException ex) {
//Just in case the testing environment is not performant enough
//It does not matter that much if there is no enough time to get a solution here
}
//Re-solve using the repair mode to check for the improvement
cra.doRepair(true);
solve(cra, model, constraints);
}
private static void solve(ChocoScheduler cra, Model model, Set constraints) {
try {
ReconfigurationPlan p = cra.solve(model, constraints);
if (p != null) {
System.out.println("\nReconfiguration plan:");
System.out.println(p);
}
} finally {
System.out.println("--- Solving using repair : " + cra.doRepair());
System.out.println(cra.getStatistics());
}
}
/**
* A default model with 500 nodes hosting 3000 VMs.
* 6 VMs per node
* Each node has a 10GB network interface and 32 GB RAM
* Each VM consumes 1GB Bandwidth and between 1 to 5 GB RAM
*/
private Model makeModel() {
Model mo = new DefaultModel();
Mapping mapping = mo.getMapping();
int nbNodes = 300;
int nbVMs = 6 * nbNodes;
//Memory usage/consumption in GB
ShareableResource rcMem = new ShareableResource("mem");
//A resource representing the bandwidth usage/consumption of the elements in GB
ShareableResource rcBW = new ShareableResource("bandwidth");
nodes = new ArrayList<>(nbNodes);
for (int i = 0; i < nbNodes; i++) {
Node n = mo.newNode();
nodes.add(n);
mapping.addOnlineNode(n);
//Each node provides a 10GB bandwidth and 32 GB RAM to its VMs
rcBW.setCapacity(n, 10);
rcMem.setCapacity(n, 32);
}
for (int i = 0; i < nbVMs; i++) {
VM vm = mo.newVM();
//Basic balancing through a round-robin: 6 VMs per node
mapping.addRunningVM(vm, nodes.get(i % nodes.size()));
//Each VM uses currently a 1GB bandwidth and 1,2 or 3 GB RAM
rcBW.setConsumption(vm, 1);
rcMem.setConsumption(vm, i % 5 + 1);
}
mo.attach(rcBW);
mo.attach(rcMem);
return mo;
}
}