You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bf...@apache.org on 2013/12/11 00:52:03 UTC
[23/50] [abbrv] git commit: updated refs/heads/ui-restyle to 326b3a6
CLOUDSTACK-3664:
scaling up vms was not considering parameter cluster.(memory/cpu).allocated.capacity.disablethreshold. Fixed it
Also added overprovisioning factor retrieval at the cluster level for host capacity check
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/e79350d2
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/e79350d2
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/e79350d2
Branch: refs/heads/ui-restyle
Commit: e79350d256cbd2bb64393ddae453c815b5a68339
Parents: 4a9da03
Author: Nitin Mehta <ni...@citrix.com>
Authored: Mon Dec 9 15:40:17 2013 -0800
Committer: Nitin Mehta <ni...@citrix.com>
Committed: Mon Dec 9 15:40:17 2013 -0800
----------------------------------------------------------------------
.../src/com/cloud/capacity/CapacityManager.java | 11 ++++
.../src/com/cloud/capacity/dao/CapacityDao.java | 15 +++---
.../com/cloud/capacity/dao/CapacityDaoImpl.java | 56 +++++++++++++++-----
.../com/cloud/capacity/CapacityManagerImpl.java | 48 +++++++++++++++++
server/src/com/cloud/vm/UserVmManagerImpl.java | 29 +++++++---
5 files changed, 133 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e79350d2/engine/components-api/src/com/cloud/capacity/CapacityManager.java
----------------------------------------------------------------------
diff --git a/engine/components-api/src/com/cloud/capacity/CapacityManager.java b/engine/components-api/src/com/cloud/capacity/CapacityManager.java
index 13624e6..bd1a610 100755
--- a/engine/components-api/src/com/cloud/capacity/CapacityManager.java
+++ b/engine/components-api/src/com/cloud/capacity/CapacityManager.java
@@ -91,4 +91,15 @@ public interface CapacityManager {
* @return true if the count of host's running VMs >= hypervisor limit
*/
boolean checkIfHostHasCpuCapability(long hostId, Integer cpuNum, Integer cpuSpeed);
+
+ /**
+ * Check if cluster will cross threshold if the cpu/memory requested are accomodated
+ * @param clusterId the clusterId to check
+ * @param cpuRequested cpu requested
+ * @param ramRequested cpu requested
+ * @return true if the customer crosses threshold, false otherwise
+ */
+ boolean checkIfClusterCrossesThreshold(Long clusterId, Integer cpuRequested, long ramRequested);
+
+ float getClusterOverProvisioningFactor(Long clusterId, short capacityType);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e79350d2/engine/schema/src/com/cloud/capacity/dao/CapacityDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/capacity/dao/CapacityDao.java b/engine/schema/src/com/cloud/capacity/dao/CapacityDao.java
index e32f96e..079d9a8 100755
--- a/engine/schema/src/com/cloud/capacity/dao/CapacityDao.java
+++ b/engine/schema/src/com/cloud/capacity/dao/CapacityDao.java
@@ -45,11 +45,12 @@ public interface CapacityDao extends GenericDao<CapacityVO, Long> {
Pair<List<Long>, Map<Long, Double>> orderPodsByAggregateCapacity(long zoneId, short capacityType);
- List<SummedCapacity> findCapacityBy(Integer capacityType, Long zoneId, 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);
-
- List<Long> listClustersCrossingThreshold(short capacityType, Long zoneId, String ConfigName, long computeRequested);
+ List<SummedCapacity> findCapacityBy(Integer capacityType, Long zoneId,
+ 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);
+ List<Long> listClustersCrossingThreshold(short capacityType, Long zoneId, String ConfigName, long computeRequested);
+
+ float findClusterConsumption(Long clusterId, short capacityType, long computeRequested);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e79350d2/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java b/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java
index cb916c3..7919ed5 100755
--- a/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java
+++ b/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java
@@ -27,6 +27,9 @@ import java.util.Map;
import javax.ejb.Local;
import javax.inject.Inject;
+import com.cloud.dc.ClusterDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
@@ -161,19 +164,24 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
* query from the configuration table
*
* */
- private static final String LIST_CLUSTERS_CROSSING_THRESHOLD =
- "SELECT clusterList.cluster_id "
- + "FROM (SELECT cluster.cluster_id cluster_id, ( (sum(cluster.used) + sum(cluster.reserved) + ?)/sum(cluster.total) ) ratio, cluster.configValue value "
- + "FROM (SELECT capacity.cluster_id cluster_id, capacity.used_capacity used, capacity.reserved_capacity reserved, capacity.total_capacity * overcommit.value total, "
- + "CASE (SELECT count(*) FROM `cloud`.`cluster_details` details WHERE details.cluster_id = capacity.cluster_id AND details.name = ? ) "
- + "WHEN 1 THEN (CASE WHEN (SELECT details.value FROM `cloud`.`cluster_details` details WHERE details.cluster_id = capacity.cluster_id AND details.name = ?) is NULL "
- + "THEN (SELECT config.value FROM `cloud`.`configuration` config WHERE config.name = ?)"
- + "ELSE (SELECT details.value FROM `cloud`.`cluster_details` details WHERE details.cluster_id = capacity.cluster_id AND details.name = ? ) END )"
- + "ELSE ( SELECT config.value FROM `cloud`.`configuration` config WHERE config.name = ?) " + "END configValue "
- + "FROM `cloud`.`op_host_capacity` capacity INNER JOIN `cloud`.`cluster_details` overcommit ON overcommit.cluster_id = capacity.cluster_id "
- + "WHERE capacity.data_center_id = ? AND capacity.capacity_type = ? AND capacity.total_capacity > 0 AND overcommit.name = ?) cluster " +
-
- "GROUP BY cluster.cluster_id) clusterList " + "WHERE clusterList.ratio > clusterList.value; ";
+
+ private static final String LIST_CLUSTERS_CROSSING_THRESHOLD = "SELECT clusterList.cluster_id " +
+ "FROM ( SELECT cluster.cluster_id cluster_id, ( (sum(cluster.used) + sum(cluster.reserved) + ?)/sum(cluster.total) ) ratio, cluster.configValue value " +
+ "FROM ( SELECT capacity.cluster_id cluster_id, capacity.used_capacity used, capacity.reserved_capacity reserved, capacity.total_capacity * overcommit.value total, " +
+ "CASE (SELECT count(*) FROM `cloud`.`cluster_details` details WHERE details.cluster_id = capacity.cluster_id AND details.name = ? ) " +
+ "WHEN 1 THEN ( CASE WHEN (SELECT details.value FROM `cloud`.`cluster_details` details WHERE details.cluster_id = capacity.cluster_id AND details.name = ?) is NULL " +
+ "THEN (SELECT config.value FROM `cloud`.`configuration` config WHERE config.name = ?)" +
+ "ELSE (SELECT details.value FROM `cloud`.`cluster_details` details WHERE details.cluster_id = capacity.cluster_id AND details.name = ? ) END )" +
+ "ELSE ( SELECT config.value FROM `cloud`.`configuration` config WHERE config.name = ?) " +
+ "END configValue " +
+ "FROM `cloud`.`op_host_capacity` capacity INNER JOIN `cloud`.`cluster_details` overcommit ON overcommit.cluster_id = capacity.cluster_id " +
+ "WHERE capacity.data_center_id = ? AND capacity.capacity_type = ? AND capacity.total_capacity > 0 AND overcommit.name = ?) cluster " +
+
+ "GROUP BY cluster.cluster_id) clusterList " +
+ "WHERE clusterList.ratio > clusterList.value; ";
+
+ private static final String FIND_CLUSTER_CONSUMPTION_RATIO = "select ( (sum(capacity.used_capacity) + sum(capacity.reserved_capacity) + ?)/sum(capacity.total_capacity) ) " +
+ "from op_host_capacity capacity where cluster_id = ? and capacity_type = ?;";
public CapacityDaoImpl() {
_hostIdTypeSearch = createSearchBuilder();
@@ -883,4 +891,26 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
s_logger.warn("Error updating CapacityVO", e);
}
}
+
+ @Override
+ public float findClusterConsumption(Long clusterId, short capacityType, long computeRequested){
+ TransactionLegacy txn = TransactionLegacy.currentTxn();
+ StringBuilder sql = new StringBuilder(FIND_CLUSTER_CONSUMPTION_RATIO);
+ PreparedStatement pstmt = null;
+ try {
+ pstmt = txn.prepareAutoCloseStatement(sql.toString());
+
+ pstmt.setLong(1, computeRequested);
+ pstmt.setLong(2, clusterId);
+ pstmt.setShort(3, capacityType);
+ ResultSet rs = pstmt.executeQuery();
+ while (rs.next()) {
+ return rs.getFloat(1);
+ }
+ } catch (Exception e) {
+ s_logger.warn("Error checking cluster threshold", e);
+ }
+ return 0;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e79350d2/server/src/com/cloud/capacity/CapacityManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/capacity/CapacityManagerImpl.java b/server/src/com/cloud/capacity/CapacityManagerImpl.java
index 2358f92..e42879c 100755
--- a/server/src/com/cloud/capacity/CapacityManagerImpl.java
+++ b/server/src/com/cloud/capacity/CapacityManagerImpl.java
@@ -27,7 +27,10 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import com.cloud.deploy.DeploymentClusterPlanner;
+import com.cloud.deploy.DeploymentPlanner;
import com.cloud.event.UsageEventVO;
+import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.log4j.Logger;
import org.apache.cloudstack.framework.config.ConfigDepot;
@@ -94,6 +97,7 @@ import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.UserVmDetailsDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+import org.springframework.instrument.classloading.glassfish.GlassFishLoadTimeWeaver;
@Local(value = CapacityManager.class)
public class CapacityManagerImpl extends ManagerBase implements CapacityManager, StateListener<State, VirtualMachine.Event, VirtualMachine>, Listener, ResourceListener,
@@ -853,6 +857,50 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
}
@Override
+ public float getClusterOverProvisioningFactor(Long clusterId, short capacityType){
+
+ String capacityOverProvisioningName = "";
+ if(capacityType == Capacity.CAPACITY_TYPE_CPU){
+ capacityOverProvisioningName = "cpuOvercommitRatio";
+ }else if(capacityType == Capacity.CAPACITY_TYPE_MEMORY){
+ capacityOverProvisioningName = "memoryOvercommitRatio";
+ }else{
+ throw new CloudRuntimeException("Invalid capacityType - " + capacityType);
+ }
+
+ ClusterDetailsVO clusterDetailCpu = _clusterDetailsDao.findDetail(clusterId, capacityOverProvisioningName);
+ Float clusterOverProvisioningRatio = Float.parseFloat(clusterDetailCpu.getValue());
+ return clusterOverProvisioningRatio;
+
+ }
+
+ @Override
+ public boolean checkIfClusterCrossesThreshold(Long clusterId, Integer cpuRequested, long ramRequested){
+
+ Float clusterCpuOverProvisioning = getClusterOverProvisioningFactor(clusterId, Capacity.CAPACITY_TYPE_CPU);
+ Float clusterMemoryOverProvisioning = getClusterOverProvisioningFactor(clusterId, Capacity.CAPACITY_TYPE_MEMORY);
+ Float clusterCpuCapacityDisableThreshold = DeploymentClusterPlanner.ClusterCPUCapacityDisableThreshold.valueIn(clusterId);
+ Float clusterMemoryCapacityDisableThreshold = DeploymentClusterPlanner.ClusterMemoryCapacityDisableThreshold.valueIn(clusterId);
+
+ float cpuConsumption = _capacityDao.findClusterConsumption(clusterId, Capacity.CAPACITY_TYPE_CPU, cpuRequested);
+ if(cpuConsumption/clusterCpuOverProvisioning > clusterCpuCapacityDisableThreshold){
+ s_logger.debug("Cluster: " +clusterId + " cpu consumption " + cpuConsumption/clusterCpuOverProvisioning
+ + " crosses disable threshold " + clusterCpuCapacityDisableThreshold);
+ return true;
+ }
+
+ float memoryConsumption = _capacityDao.findClusterConsumption(clusterId, Capacity.CAPACITY_TYPE_MEMORY, ramRequested);
+ if(memoryConsumption/clusterMemoryOverProvisioning > clusterMemoryCapacityDisableThreshold){
+ s_logger.debug("Cluster: " +clusterId + " memory consumption " + memoryConsumption/clusterMemoryOverProvisioning
+ + " crosses disable threshold " + clusterMemoryCapacityDisableThreshold);
+ return true;
+ }
+
+ return false;
+
+ }
+
+ @Override
public boolean processAnswers(long agentId, long seq, Answer[] answers) {
// TODO Auto-generated method stub
return false;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e79350d2/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 1752c22..582ddcf 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -36,6 +36,8 @@ import javax.naming.ConfigurationException;
import com.cloud.event.UsageEventVO;
import com.cloud.uuididentity.UUIDManager;
+import com.cloud.capacity.Capacity;
+import com.cloud.exception.InsufficientServerCapacityException;
import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
@@ -1306,6 +1308,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
int currentCpu = currentServiceOffering.getCpu();
int currentMemory = currentServiceOffering.getRamSize();
int currentSpeed = currentServiceOffering.getSpeed();
+ int memoryDiff = newMemory - currentMemory;
+ int cpuDiff = newCpu*newSpeed - currentCpu*currentSpeed;
// Don't allow to scale when (Any of the new values less than current values) OR (All current and new values are same)
if ((newSpeed < currentSpeed || newMemory < currentMemory || newCpu < currentCpu) ||
@@ -1328,14 +1332,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
if (vmInstance.getState().equals(State.Running)) {
int retry = _scaleRetry;
ExcludeList excludes = new ExcludeList();
+
+ // Check zone wide flag
boolean enableDynamicallyScaleVm = EnableDynamicallyScaleVm.valueIn(vmInstance.getDataCenterId());
if (!enableDynamicallyScaleVm) {
throw new PermissionDeniedException("Dynamically scaling virtual machines is disabled for this zone, please contact your admin");
}
+
+ // Check vm flag
if (!vmInstance.isDynamicallyScalable()) {
throw new CloudRuntimeException("Unable to Scale the vm: " + vmInstance.getUuid() + " as vm does not have tools to support dynamic scaling");
}
+ // Check disable threshold for cluster is not crossed
+ HostVO host = _hostDao.findById(vmInstance.getHostId());
+ if(_capacityMgr.checkIfClusterCrossesThreshold(host.getClusterId(), cpuDiff, memoryDiff)){
+ throw new CloudRuntimeException("Unable to scale vm: " + vmInstance.getUuid() + " due to insufficient resources");
+ }
+
while (retry-- != 0) { // It's != so that it can match -1.
try {
boolean existingHostHasCapacity = false;
@@ -1344,15 +1358,17 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
if (newCpu > currentCpu) {
_resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
}
- if (newMemory > currentMemory) {
- _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(newMemory - currentMemory));
+
+ if (memoryDiff > 0) {
+ _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long (memoryDiff));
}
// #1 Check existing host has capacity
if( !excludes.shouldAvoid(ApiDBUtils.findHostById(vmInstance.getHostId())) ){
existingHostHasCapacity = _capacityMgr.checkIfHostHasCpuCapability(vmInstance.getHostId(), newCpu, newSpeed)
- && _capacityMgr.checkIfHostHasCapacity(vmInstance.getHostId(), newServiceOffering.getSpeed() - currentServiceOffering.getSpeed(),
- (newServiceOffering.getRamSize() - currentServiceOffering.getRamSize()) * 1024L * 1024L, false, ApiDBUtils.getCpuOverprovisioningFactor(), 1f, false); // TO DO fill it with mem.
+ && _capacityMgr.checkIfHostHasCapacity(vmInstance.getHostId(), cpuDiff,
+ (memoryDiff) * 1024L * 1024L, false, _capacityMgr.getClusterOverProvisioningFactor(host.getClusterId(), Capacity.CAPACITY_TYPE_CPU),
+ _capacityMgr.getClusterOverProvisioningFactor(host.getClusterId(), Capacity.CAPACITY_TYPE_MEMORY), false);
excludes.addHost(vmInstance.getHostId());
}
@@ -1392,8 +1408,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
if (newCpu > currentCpu) {
_resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
}
- if (newMemory > currentMemory) {
- _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(newMemory - currentMemory));
+
+ if (memoryDiff > 0) {
+ _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long (memoryDiff));
}
}
}