CLOUDSTACK-4179: [Performance Testing] Time taken for Deploy VM async job to complete is considerably higher

The time increased due to the newly added dedicated resources feature. During regular VM deployment, all dedicated resources are put in avoid list so that they are not considered for deployment.
Now the way to compute the list of dedicated resources is not optimal and performance deteriorates in an environment having lot of pods, clusters and hosts as the logic is to query db. for each suc resource.

The fix is to optimize the logic not to loop through all resources but get the list of each resource type in a single query.

Conflicts:
	server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
This commit is contained in:
Koushik Das 2013-08-09 15:52:00 +05:30
parent 2100789f23
commit 8cf48ed2ce
10 changed files with 122 additions and 64 deletions

View File

@ -191,6 +191,13 @@ public interface DeploymentPlanner extends Adapter {
_podIds.add(podId);
}
public void addPodList(Collection<Long> podList) {
if (_podIds == null) {
_podIds = new HashSet<Long>();
}
_podIds.addAll(podList);
}
public void addCluster(long clusterId) {
if (_clusterIds == null) {
_clusterIds = new HashSet<Long>();

View File

@ -35,4 +35,5 @@ public interface ClusterDao extends GenericDao<ClusterVO, Long> {
List<Long> listDisabledClusters(long zoneId, Long podId);
List<Long> listClustersWithDisabledPods(long zoneId);
List<ClusterVO> listClustersByDcId(long zoneId);
List<Long> listAllCusters(long zoneId);
}

View File

@ -54,6 +54,8 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
protected final SearchBuilder<ClusterVO> ZoneHyTypeSearch;
protected final SearchBuilder<ClusterVO> ZoneClusterSearch;
protected GenericSearchBuilder<ClusterVO, Long> ClusterIdSearch;
private static final String GET_POD_CLUSTER_MAP_PREFIX = "SELECT pod_id, id FROM cloud.cluster WHERE cluster.id IN( ";
private static final String GET_POD_CLUSTER_MAP_SUFFIX = " )";
@Inject
@ -90,6 +92,11 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
ZoneClusterSearch = createSearchBuilder();
ZoneClusterSearch.and("dataCenterId", ZoneClusterSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
ZoneClusterSearch.done();
ClusterIdSearch = createSearchBuilder(Long.class);
ClusterIdSearch.selectField(ClusterIdSearch.entity().getId());
ClusterIdSearch.and("dataCenterId", ClusterIdSearch.entity().getDataCenterId(), Op.EQ);
ClusterIdSearch.done();
}
@Override
@ -168,11 +175,11 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
while (rs.next()) {
Long podId = rs.getLong(1);
Long clusterIdInPod = rs.getLong(2);
if(result.containsKey(podId)){
if (result.containsKey(podId)) {
List<Long> clusterList = result.get(podId);
clusterList.add(clusterIdInPod);
result.put(podId, clusterList);
}else{
} else {
List<Long> clusterList = new ArrayList<Long>();
clusterList.add(clusterIdInPod);
result.put(podId, clusterList);
@ -191,13 +198,12 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
GenericSearchBuilder<ClusterVO, Long> clusterIdSearch = createSearchBuilder(Long.class);
clusterIdSearch.selectField(clusterIdSearch.entity().getId());
clusterIdSearch.and("dataCenterId", clusterIdSearch.entity().getDataCenterId(), Op.EQ);
if(podId != null){
if (podId != null) {
clusterIdSearch.and("podId", clusterIdSearch.entity().getPodId(), Op.EQ);
}
clusterIdSearch.and("allocationState", clusterIdSearch.entity().getAllocationState(), Op.EQ);
clusterIdSearch.done();
SearchCriteria<Long> sc = clusterIdSearch.create();
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
if (podId != null) {
@ -250,4 +256,10 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
return result;
}
@Override
public List<Long> listAllCusters(long zoneId) {
SearchCriteria<Long> sc = ClusterIdSearch.create();
sc.setParameters("dataCenterId", zoneId);
return customSearch(sc, null);
}
}

View File

@ -24,12 +24,13 @@ import com.cloud.utils.db.GenericDao;
import com.cloud.vm.VirtualMachine;
public interface HostPodDao extends GenericDao<HostPodVO, Long> {
public List<HostPodVO> listByDataCenterId(long id);
public List<HostPodVO> listByDataCenterId(long id);
public HostPodVO findByName(String name, long dcId);
public HashMap<Long, List<Object>> getCurrentPodCidrSubnets(long zoneId, long podIdToSkip);
public HashMap<Long, List<Object>> getCurrentPodCidrSubnets(long zoneId, long podIdToSkip);
public List<Long> listDisabledPods(long zoneId);
public List<Long> listAllPods(long zoneId);
}

View File

@ -44,6 +44,7 @@ public class HostPodDaoImpl extends GenericDaoBase<HostPodVO, Long> implements H
protected SearchBuilder<HostPodVO> DataCenterAndNameSearch;
protected SearchBuilder<HostPodVO> DataCenterIdSearch;
protected GenericSearchBuilder<HostPodVO, Long> PodIdSearch;
public HostPodDaoImpl() {
DataCenterAndNameSearch = createSearchBuilder();
@ -54,6 +55,12 @@ public class HostPodDaoImpl extends GenericDaoBase<HostPodVO, Long> implements H
DataCenterIdSearch = createSearchBuilder();
DataCenterIdSearch.and("dcId", DataCenterIdSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
DataCenterIdSearch.done();
PodIdSearch = createSearchBuilder(Long.class);
PodIdSearch.selectField(PodIdSearch.entity().getId());
PodIdSearch.and("dataCenterId", PodIdSearch.entity().getDataCenterId(), Op.EQ);
PodIdSearch.and("allocationState", PodIdSearch.entity().getAllocationState(), Op.EQ);
PodIdSearch.done();
}
@Override
@ -118,17 +125,16 @@ public class HostPodDaoImpl extends GenericDaoBase<HostPodVO, Long> implements H
@Override
public List<Long> listDisabledPods(long zoneId) {
GenericSearchBuilder<HostPodVO, Long> podIdSearch = createSearchBuilder(Long.class);
podIdSearch.selectField(podIdSearch.entity().getId());
podIdSearch.and("dataCenterId", podIdSearch.entity().getDataCenterId(), Op.EQ);
podIdSearch.and("allocationState", podIdSearch.entity().getAllocationState(), Op.EQ);
podIdSearch.done();
SearchCriteria<Long> sc = podIdSearch.create();
SearchCriteria<Long> sc = PodIdSearch.create();
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
sc.addAnd("allocationState", SearchCriteria.Op.EQ, Grouping.AllocationState.Disabled);
return customSearch(sc, null);
}
@Override
public List<Long> listAllPods(long zoneId) {
SearchCriteria<Long> sc = PodIdSearch.create();
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
return customSearch(sc, null);
}
}

View File

@ -43,7 +43,7 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
*/
void markHostsAsDisconnected(long msId, long lastPing);
List<HostVO> findLostHosts(long timeout);
List<HostVO> findLostHosts(long timeout);
List<HostVO> findAndUpdateDirectAgentToLoad(long lastPingSecondsAfter, Long limit, long managementServerId);
@ -61,15 +61,14 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
long countRoutingHostsByDataCenter(long dcId);
List<HostVO> findAndUpdateApplianceToLoad(long lastPingSecondsAfter, long managementServerId);
List<HostVO> findAndUpdateApplianceToLoad(long lastPingSecondsAfter, long managementServerId);
boolean updateResourceState(ResourceState oldState, ResourceState.Event event, ResourceState newState, Host vo);
HostVO findByGuid(String guid);
HostVO findByTypeNameAndZoneId(long zoneId, String name, Host.Type type);
List<HostVO> findHypervisorHostInCluster(long clusterId);
HostVO findByGuid(String guid);
HostVO findByTypeNameAndZoneId(long zoneId, String name, Host.Type type);
List<HostVO> findHypervisorHostInCluster(long clusterId);
/**
* @param type
@ -86,4 +85,6 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
List<HostVO> findByClusterId(Long clusterId);
List<HostVO> listByDataCenterId(long id);
List<Long> listAllHosts(long zoneId);
}

View File

@ -105,7 +105,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
protected SearchBuilder<HostVO> ManagedRoutingServersSearch;
protected SearchBuilder<HostVO> SecondaryStorageVMSearch;
protected GenericSearchBuilder<HostVO, Long> HostIdSearch;
protected GenericSearchBuilder<HostVO, Long> HostsInStatusSearch;
protected GenericSearchBuilder<HostVO, Long> CountRoutingByDc;
protected SearchBuilder<HostTransferMapVO> HostTransferSearch;
@ -319,7 +319,6 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
CountRoutingByDc.and("dc", CountRoutingByDc.entity().getDataCenterId(), SearchCriteria.Op.EQ);
CountRoutingByDc.and("type", CountRoutingByDc.entity().getType(), SearchCriteria.Op.EQ);
CountRoutingByDc.and("status", CountRoutingByDc.entity().getStatus(), SearchCriteria.Op.EQ);
CountRoutingByDc.done();
ManagedDirectConnectSearch = createSearchBuilder();
@ -370,6 +369,11 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
HostsInClusterSearch.and("server", HostsInClusterSearch.entity().getManagementServerId(), SearchCriteria.Op.NNULL);
HostsInClusterSearch.done();
HostIdSearch = createSearchBuilder(Long.class);
HostIdSearch.selectField(HostIdSearch.entity().getId());
HostIdSearch.and("dataCenterId", HostIdSearch.entity().getDataCenterId(), Op.EQ);
HostIdSearch.done();
_statusAttr = _allAttributes.get("status");
_msIdAttr = _allAttributes.get("managementServerId");
_pingTimeAttr = _allAttributes.get("lastPinged");
@ -1027,4 +1031,10 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
return listBy(sc);
}
@Override
public List<Long> listAllHosts(long zoneId) {
SearchCriteria<Long> sc = HostIdSearch.create();
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
return customSearch(sc, null);
}
}

View File

@ -46,4 +46,10 @@ public interface DedicatedResourceDao extends GenericDao<DedicatedResourceVO, Lo
List<DedicatedResourceVO> listByDomainId(Long domainId);
List<DedicatedResourceVO> listZonesNotInDomainIds(List<Long> domainIds);
List<Long> listAllPods();
List<Long> listAllClusters();
List<Long> listAllHosts();
}

View File

@ -23,11 +23,14 @@ import javax.ejb.Local;
import org.springframework.stereotype.Component;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.HostPodVO;
import com.cloud.utils.Pair;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Func;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
@ -59,6 +62,10 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
protected SearchBuilder<DedicatedResourceVO> ZoneByDomainIdsSearch;
protected GenericSearchBuilder<DedicatedResourceVO, Long> ListPodsSearch;
protected GenericSearchBuilder<DedicatedResourceVO, Long> ListClustersSearch;
protected GenericSearchBuilder<DedicatedResourceVO, Long> ListHostsSearch;
protected DedicatedResourceDaoImpl() {
PodSearch = createSearchBuilder();
PodSearch.and("podId", PodSearch.entity().getPodId(), SearchCriteria.Op.EQ);
@ -169,6 +176,21 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
ZoneByDomainIdsSearch.and("zoneId", ZoneByDomainIdsSearch.entity().getDataCenterId(), SearchCriteria.Op.NNULL);
ZoneByDomainIdsSearch.and("domainId", ZoneByDomainIdsSearch.entity().getDomainId(), SearchCriteria.Op.NIN);
ZoneByDomainIdsSearch.done();
ListPodsSearch = createSearchBuilder(Long.class);
ListPodsSearch.select(null, Func.DISTINCT, ListPodsSearch.entity().getPodId());
ListPodsSearch.and("podId", ListPodsSearch.entity().getPodId(), Op.NNULL);
ListPodsSearch.done();
ListClustersSearch = createSearchBuilder(Long.class);
ListClustersSearch.select(null, Func.DISTINCT, ListClustersSearch.entity().getClusterId());
ListClustersSearch.and("clusterId", ListClustersSearch.entity().getClusterId(), Op.NNULL);
ListClustersSearch.done();
ListHostsSearch = createSearchBuilder(Long.class);
ListHostsSearch.select(null, Func.DISTINCT, ListHostsSearch.entity().getHostId());
ListHostsSearch.and("hostId", ListHostsSearch.entity().getHostId(), Op.NNULL);
ListHostsSearch.done();
}
@Override
@ -301,4 +323,22 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
txn.commit();
return result;
}
@Override
public List<Long> listAllPods() {
SearchCriteria<Long> sc = ListPodsSearch.create();
return customSearch(sc, null);
}
@Override
public List<Long> listAllClusters() {
SearchCriteria<Long> sc = ListClustersSearch.create();
return customSearch(sc, null);
}
@Override
public List<Long> listAllHosts() {
SearchCriteria<Long> sc = ListHostsSearch.create();
return customSearch(sc, null);
}
}

View File

@ -44,14 +44,8 @@ import org.apache.cloudstack.framework.messagebus.MessageSubscriber;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.utils.identity.ManagementServerNode;
import org.apache.log4j.Logger;
import com.cloud.capacity.CapacityManager;
import com.cloud.capacity.dao.CapacityDao;
import com.cloud.configuration.Config;
@ -61,7 +55,6 @@ import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.Pod;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
@ -100,8 +93,6 @@ import com.cloud.utils.Pair;
import com.cloud.utils.component.Manager;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
@ -466,39 +457,22 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(dc.getId());
if (dedicatedZone != null && dedicatedZone.getDomainId() != null) {
throw new CloudRuntimeException("Failed to deploy VM. Zone " + dc.getName() + " is dedicated . Please use Explicit Dedication Affinity Group");
}
}
List<HostPodVO> podsInDc = _podDao.listByDataCenterId(dc.getId());
for (HostPodVO pod : podsInDc) {
DedicatedResourceVO dedicatedPod = _dedicatedDao.findByPodId(pod.getId());
if (dedicatedPod != null) {
avoids.addPod(dedicatedPod.getPodId());
if (s_logger.isDebugEnabled()) {
s_logger.debug("Cannot use this dedicated pod " + pod.getName() + ".");
}
}
}
List<ClusterVO> clusterInDc = _clusterDao.listClustersByDcId(dc.getId());
for (ClusterVO cluster : clusterInDc) {
DedicatedResourceVO dedicatedCluster = _dedicatedDao.findByClusterId(cluster.getId());
if (dedicatedCluster != null) {
avoids.addCluster(dedicatedCluster.getClusterId());
if (s_logger.isDebugEnabled()) {
s_logger.debug("Cannot use this dedicated Cluster " + cluster.getName() + ".");
}
}
}
List<HostVO> hostInDc = _hostDao.listByDataCenterId(dc.getId());
for (HostVO host : hostInDc) {
DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(host.getId());
if (dedicatedHost != null) {
avoids.addHost(dedicatedHost.getHostId());
if (s_logger.isDebugEnabled()) {
s_logger.debug("Cannot use this dedicated host " + host.getName() + ".");
}
}
}
List<Long> allPodsInDc = _podDao.listAllPods(dc.getId());
List<Long> allDedicatedPods = _dedicatedDao.listAllPods();
allPodsInDc.retainAll(allDedicatedPods);
avoids.addPodList(allPodsInDc);
List<Long> allClustersInDc = _clusterDao.listAllCusters(dc.getId());
List<Long> allDedicatedClusters = _dedicatedDao.listAllClusters();
allClustersInDc.retainAll(allDedicatedClusters);
avoids.addClusterList(allClustersInDc);
List<Long> allHostsInDc = _hostDao.listAllHosts(dc.getId());
List<Long> allDedicatedHosts = _dedicatedDao.listAllHosts();
allHostsInDc.retainAll(allDedicatedHosts);
avoids.addHostList(allHostsInDc);
}
}