def get_optimal_rackspace(cpu_usage, mem_usage, optimal=True, debug=False): """ Calculates the price of optimal resources allocation over a certain time span (with monthly granularity). Formulates the problem of satisfying user demand (in CPU and RAM) as an LP problem with a monetary objective function. """ assert(len(cpu_usage) == len(mem_usage)) prob = LpProblem("Rackspace cost optimization", LpMinimize) # variables ## 1h instances per_h_ondems = [] for p in range(len(cpu_usage)): per_h_ondems += ["p %s ondem %s" %(p, i) for i in vms.keys()] category = LpInteger if optimal else LpContinuous vars = LpVariable.dicts("rackspace", per_h_ondems, 0, None, cat=category) # objective function prob += lpSum([vars[vm] * vms[vm.split(" ")[3]][0] for vm in per_h_ondems]), "Total cost of running the infra (wrt to CPU/RAM)" # constraints ## demand constraints for p in range(len(cpu_usage)): prob += lpSum([vars[vm] * vms[vm.split(" ")[3]][2] for vm in per_h_ondems if int(vm.split(" ")[1]) == p]) >= cpu_usage[p], "CU demand period %s" %p prob += lpSum([vars[vm] * vms[vm.split(" ")[3]][3] for vm in per_h_ondems if int(vm.split(" ")[1]) == p]) >= mem_usage[p], "RAM demand period %s" %p prob.solve() if debug: for v in prob.variables(): if v.varValue != 0.0: print v.name, "=", v.varValue print "Total Cost of the solution = ", value(prob.objective) return value(prob.objective)
def get_optimal_ec2(cpu_usage, mem_usage, optimal=True, debug=False): """ Calculates the optimal allocation of resources over a certain time span (with monthly granularity). Formulates the problem of satisfying user demand (in CPU and RAM) as an LP problem with a monetary objective function. Returns allocation of reserved instances and a total price for running the allocation on AWS. """ assert(len(cpu_usage) == len(mem_usage)) prob = LpProblem("The Simplified EC2 cost optimization", LpMinimize) # variables ## 1h instances (both on-demand and reserved) per_h_ondems = [] per_h_reserved = [] for p in range(len(cpu_usage)): # ondemand per_h_ondems += ["p %s ondem %s" %(p, i) for i in vms.keys()] # reserved per_h_reserved += ["p %s reserved %s" %(p, i) for i in vms.keys()] ## nr of 1-year reserved instances nr_of_1year_reserved = [ "res_1year %s" % i for i in vms.keys()] nr_of_3year_reserved = [ "res_3year %s" % i for i in vms.keys()] category = LpInteger if optimal else LpContinuous vars = LpVariable.dicts("aws", per_h_ondems + per_h_reserved + nr_of_1year_reserved + nr_of_3year_reserved, \ lowBound = 0, upBound = None, cat = category) # objective function prob += lpSum([vars[vm] * vms[vm.split(" ")[3]][0] for vm in per_h_ondems]) \ + lpSum([vars[vm] * vms[vm.split(" ")[3]][3] for vm in per_h_reserved]) \ + lpSum([vars[vm] * vms[vm.split(" ")[1]][1] for vm in nr_of_1year_reserved]) \ + lpSum([vars[vm] * vms[vm.split(" ")[1]][2] for vm in nr_of_3year_reserved]) \ , "Total cost of running the infrastructure consuming (CPU/RAM)/h" # constraints ## demand constraints for p in range(len(cpu_usage)): prob += lpSum([vars[vm] * vms[vm.split(" ")[3]][4] for vm in (per_h_ondems + per_h_reserved) if int(vm.split(" ")[1]) == p]) >= cpu_usage[p], "CPU demand, period %s" %p prob += lpSum([vars[vm] * vms[vm.split(" ")[3]][5] for vm in (per_h_ondems + per_h_reserved) if int(vm.split(" ")[1]) == p]) >= mem_usage[p], "RAM demand. period %s" %p ## constraints on the reserved instances - cannot use more than we paid for for i in per_h_reserved: t = i.split(" ")[3] prob += vars["res_1year %s" % t] + vars["res_3year %s" % t] >= vars[i], "Nr. of used reserved machines of type %s" %i prob.solve() if debug: print "Status:", LpStatus[prob.status] print "Total Cost of the solution = ", value(prob.objective) res_instance = {} for v in prob.variables(): if v.name.startswith("aws_res_") and v.varValue != 0.0: res_instance[v.name] = v.varValue if debug and v.varValue != 0.0: print v.name, "=", v.varValue return (res_instance, value(prob.objective))