mirror of https://github.com/apache/cloudstack.git
bug CS-15278: For removing clusters crossing threshold find out the list of cluster through db instead of iteratting cluster one by one in the java code.
Reviewed-by: Koushik
This commit is contained in:
parent
0bd667418e
commit
3aa0e9a352
|
|
@ -12,6 +12,7 @@
|
|||
// Automatically generated by addcopyright.py at 04/03/2012
|
||||
package com.cloud.deploy;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
|
@ -176,6 +177,13 @@ public interface DeploymentPlanner extends Adapter {
|
|||
_clusterIds.add(clusterId);
|
||||
}
|
||||
|
||||
public void addClusterList(Collection<Long> clusterList) {
|
||||
if (_clusterIds == null) {
|
||||
_clusterIds = new HashSet<Long>();
|
||||
}
|
||||
_clusterIds.addAll(clusterList);
|
||||
}
|
||||
|
||||
public void addHost(long hostId) {
|
||||
if (_hostIds == null) {
|
||||
_hostIds = new HashSet<Long>();
|
||||
|
|
|
|||
|
|
@ -36,5 +36,6 @@ public interface CapacityDao extends GenericDao<CapacityVO, Long> {
|
|||
Long podId, Long clusterId, String resourceState);
|
||||
List<SummedCapacity> listCapacitiesGroupedByLevelAndType(Integer capacityType, Long zoneId, Long podId, Long clusterId, int level, Long limit);
|
||||
void updateCapacityState(Long dcId, Long podId, Long clusterId,
|
||||
Long hostId, String capacityState);
|
||||
Long hostId, String capacityState);
|
||||
List<Long> listClustersCrossingThreshold(short capacityType, Long zoneId, Float disableThreshold, long computeRequested, Float overProvFactor);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import com.cloud.storage.Storage;
|
|||
import com.cloud.storage.StoragePoolVO;
|
||||
import com.cloud.storage.dao.StoragePoolDaoImpl;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.component.ComponentLocator;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
|
|
@ -104,7 +105,12 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||
"WHERE total_capacity > 0 AND cluster_id is not null AND capacity_state='Enabled'";
|
||||
private static final String LIST_CAPACITY_GROUP_BY_CLUSTER_TYPE_PART2 = " GROUP BY cluster_id, capacity_type order by percent desc limit ";
|
||||
private static final String UPDATE_CAPACITY_STATE = "UPDATE `cloud`.`op_host_capacity` SET capacity_state = ? WHERE ";
|
||||
|
||||
private static final String LIST_CLUSTERS_CROSSING_THRESHOLD = "SELECT cluster_id " +
|
||||
"FROM (SELECT cluster_id, ( (sum(capacity.used_capacity) + sum(capacity.reserved_capacity) + ?)/sum(total_capacity) ) ratio "+
|
||||
"FROM `cloud`.`op_host_capacity` capacity "+
|
||||
"WHERE capacity.data_center_id = ? AND capacity.capacity_type = ? AND capacity.total_capacity > 0 "+
|
||||
"GROUP BY cluster_id) tmp " +
|
||||
"WHERE tmp.ratio > ? ";
|
||||
|
||||
|
||||
public CapacityDaoImpl() {
|
||||
|
|
@ -128,6 +134,52 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||
|
||||
_allFieldsSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listClustersCrossingThreshold(short capacityType, Long zoneId, Float disableThreshold, long compute_requested, Float overProvFactor){
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
PreparedStatement pstmt = null;
|
||||
List<Long> result = new ArrayList<Long>();
|
||||
StringBuilder sql = new StringBuilder(LIST_CLUSTERS_CROSSING_THRESHOLD);
|
||||
|
||||
|
||||
try {
|
||||
pstmt = txn.prepareAutoCloseStatement(sql.toString());
|
||||
pstmt.setLong(1, compute_requested);
|
||||
pstmt.setLong(2, zoneId);
|
||||
pstmt.setShort(3, capacityType);
|
||||
pstmt.setFloat(4, disableThreshold*overProvFactor);
|
||||
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
result.add(rs.getLong(1));
|
||||
}
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("DB Exception on: " + sql, e);
|
||||
} catch (Throwable e) {
|
||||
throw new CloudRuntimeException("Caught: " + sql, e);
|
||||
}
|
||||
}
|
||||
|
||||
/*public static String preparePlaceHolders(int length) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < length;) {
|
||||
builder.append("?");
|
||||
if (++i < length) {
|
||||
builder.append(",");
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static void setValues(PreparedStatement preparedStatement, Object... values) throws SQLException {
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
preparedStatement.setObject(i + 1, values[i]);
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
@Override
|
||||
public List<SummedCapacity> findCapacityBy(Integer capacityType, Long zoneId, Long podId, Long clusterId, String resource_state){
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ import com.cloud.storage.dao.VolumeDao;
|
|||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.component.Adapters;
|
||||
import com.cloud.utils.component.Inject;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
|
|
@ -447,7 +448,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
|||
return capacityList;
|
||||
}
|
||||
|
||||
private void removeClustersCrossingThreshold(List<Long> clusterList, ExcludeList avoid, VirtualMachineProfile<? extends VirtualMachine> vmProfile){
|
||||
private void removeClustersCrossingThreshold(List<Long> clusterListForVmAllocation, ExcludeList avoid, VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan){
|
||||
|
||||
Map<Short,Float> capacityThresholdMap = getCapacityThresholdMap();
|
||||
List<Short> capacityList = getCapacitiesForCheckingThreshold();
|
||||
|
|
@ -457,37 +458,33 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
|||
int cpu_requested = offering.getCpu() * offering.getSpeed();
|
||||
long ram_requested = offering.getRamSize() * 1024L * 1024L;
|
||||
|
||||
// Iterate over the cluster List and check for each cluster whether it breaks disable threshold for any of the capacity types
|
||||
for (Long clusterId : clusterList){
|
||||
for(short capacity : capacityList){
|
||||
|
||||
List<SummedCapacity> summedCapacityList = _capacityDao.findCapacityBy(new Integer(capacity), null, null, clusterId);
|
||||
if (summedCapacityList != null && summedCapacityList.size() != 0 && summedCapacityList.get(0).getTotalCapacity() != 0){
|
||||
|
||||
double used = (double)(summedCapacityList.get(0).getUsedCapacity() + summedCapacityList.get(0).getReservedCapacity());
|
||||
double total = summedCapacityList.get(0).getTotalCapacity();
|
||||
|
||||
if (capacity == Capacity.CAPACITY_TYPE_CPU){
|
||||
total = total * ApiDBUtils.getCpuOverprovisioningFactor();
|
||||
used = used + cpu_requested;
|
||||
}else{
|
||||
used = used + ram_requested;
|
||||
}
|
||||
|
||||
double usedPercentage = used/total;
|
||||
if ( usedPercentage > capacityThresholdMap.get(capacity)){
|
||||
avoid.addCluster(clusterId);
|
||||
clustersCrossingThreshold.add(clusterId);
|
||||
s_logger.debug("Cannot allocate cluster " + clusterId + " for vm creation since its allocated percentage: " +usedPercentage +
|
||||
" will cross the disable capacity threshold: " + capacityThresholdMap.get(capacity) + " for capacity Type : " + capacity + ", skipping this cluster");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clusterList.removeAll(clustersCrossingThreshold);
|
||||
|
||||
// For each capacity get the cluster list crossing the threshold and remove it from the clusterList that will be used for vm allocation.
|
||||
for(short capacity : capacityList){
|
||||
|
||||
if (clusterListForVmAllocation == null || clusterListForVmAllocation.size() == 0){
|
||||
return;
|
||||
}
|
||||
|
||||
if (capacity == Capacity.CAPACITY_TYPE_CPU){
|
||||
clustersCrossingThreshold = _capacityDao.listClustersCrossingThreshold(Capacity.CAPACITY_TYPE_CPU, plan.getDataCenterId(),
|
||||
capacityThresholdMap.get(capacity), cpu_requested, ApiDBUtils.getCpuOverprovisioningFactor());
|
||||
}else{
|
||||
clustersCrossingThreshold = _capacityDao.listClustersCrossingThreshold(capacity, plan.getDataCenterId(),
|
||||
capacityThresholdMap.get(capacity), ram_requested, 1.0f);//Mem overprov not supported yet
|
||||
}
|
||||
|
||||
|
||||
if (clustersCrossingThreshold != null && clustersCrossingThreshold.size() != 0){
|
||||
// addToAvoid Set
|
||||
avoid.addClusterList(clustersCrossingThreshold);
|
||||
// Remove clusters crossing disabled threshold
|
||||
clusterListForVmAllocation.removeAll(clustersCrossingThreshold);
|
||||
|
||||
s_logger.debug("Cannot allocate cluster list " + clustersCrossingThreshold.toString() + " for vm creation since their allocated percentage" +
|
||||
" crosses the disable capacity threshold: " + capacityThresholdMap.get(capacity) + " for capacity Type : " + capacity + ", skipping these clusters");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private DeployDestination checkClustersforDestination(List<Long> clusterList, VirtualMachineProfile<? extends VirtualMachine> vmProfile,
|
||||
|
|
@ -497,7 +494,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
|||
s_logger.trace("ClusterId List to consider: " + clusterList);
|
||||
}
|
||||
|
||||
removeClustersCrossingThreshold(clusterList, avoid, vmProfile);
|
||||
removeClustersCrossingThreshold(clusterList, avoid, vmProfile, plan);
|
||||
|
||||
for(Long clusterId : clusterList){
|
||||
Cluster clusterVO = _clusterDao.findById(clusterId);
|
||||
|
|
|
|||
Loading…
Reference in New Issue