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:
Nitin Mehta 2012-08-10 16:15:25 +05:30
parent 0bd667418e
commit 3aa0e9a352
4 changed files with 93 additions and 35 deletions

View File

@ -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>();

View File

@ -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);
}

View File

@ -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){

View File

@ -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);