From eeac80eaa2c66569d96140eef34a7e219e4e25f1 Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Mon, 26 Aug 2013 15:54:36 +0530 Subject: [PATCH] CLOUDSTACK-4350: [Performance Testing] Adding hosts take much longer time than baselines During host connect multiple listeners gets invoked, one of them is the download listener. As part of processConnect() method, it checks if templates needs to be downloaded to secondary store for a particular HV type. As part of that check it computes list of HVs present in the zone. The earlier logic was to query all hosts (excluding current one) and iterate over them to make the list. This is not optimal and is bound to have some latency as the number of hosts increases. Optimized the logic by querying the list of HVs from the db. directly instead of iterating over all hosts in the zone. Conflicts: server/src/com/cloud/resource/ResourceManagerImpl.java --- .../cloud/resource/ResourceManagerImpl.java | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index 44ee8e3bd51..400879d8029 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -31,11 +31,10 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import com.google.gson.Gson; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd; import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd; @@ -147,9 +146,11 @@ import com.cloud.utils.UriUtils; import com.cloud.utils.component.Manager; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; +import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.GlobalLock; 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.SearchCriteria2; import com.cloud.utils.db.SearchCriteriaService; @@ -262,6 +263,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 30; // seconds + private GenericSearchBuilder _hypervisorsInDC; + private void insertListener(Integer event, ResourceListener listener) { List lst = _lifeCycleListeners.get(event); if (lst == null) { @@ -1338,6 +1341,15 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, public boolean configure(String name, Map params) throws ConfigurationException { _defaultSystemVMHypervisor = HypervisorType.getType(_configDao.getValue(Config.SystemVMDefaultHypervisor.toString())); _gson = GsonHelper.getGson(); + + _hypervisorsInDC = _hostDao.createSearchBuilder(String.class); + _hypervisorsInDC.select(null, Func.DISTINCT, _hypervisorsInDC.entity().getHypervisorType()); + _hypervisorsInDC.and("hypervisorType", _hypervisorsInDC.entity().getHypervisorType(), SearchCriteria.Op.NNULL); + _hypervisorsInDC.and("dataCenter", _hypervisorsInDC.entity().getDataCenterId(), SearchCriteria.Op.EQ); + _hypervisorsInDC.and("id", _hypervisorsInDC.entity().getId(), SearchCriteria.Op.NEQ); + _hypervisorsInDC.and("type", _hypervisorsInDC.entity().getType(), SearchCriteria.Op.EQ); + _hypervisorsInDC.done(); + return true; } @@ -2418,23 +2430,25 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, @Override public List listAvailHypervisorInZone(Long hostId, Long zoneId) { - SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); + SearchCriteria sc = _hypervisorsInDC.create(); if (zoneId != null) { - sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, zoneId); + sc.setParameters("dataCenter", zoneId); } if (hostId != null) { // exclude the given host, since we want to check what hypervisor is already handled // in adding this new host - sc.addAnd(sc.getEntity().getId(), Op.NEQ, hostId); + sc.setParameters("id", hostId); } - sc.addAnd(sc.getEntity().getType(), Op.EQ, Host.Type.Routing); - List hosts = sc.list(); + sc.setParameters("type", Host.Type.Routing); - List hypers = new ArrayList(5); - for (HostVO host : hosts) { - hypers.add(host.getHypervisorType()); + // The search is not able to return list of enums, so getting + // list of hypervisors as strings and then converting them to enum + List hvs = _hostDao.customSearch(sc, null); + List hypervisors = new ArrayList(); + for (String hv : hvs) { + hypervisors.add(HypervisorType.getType(hv)); } - return hypers; + return hypervisors; } @Override