From 5603bf9c1afcf979578be713d81ab2650beb7885 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Fri, 10 May 2024 00:06:58 +0530 Subject: [PATCH] engine: optimise CPU and DB hotspot to return enabled hypervisors in the zone This refactors a ResourceManager::listAvailHypervisorInZone method that should return unique hypervisors for which existing hosts are Up and processed. We can approximate this by assuming that those hosts would have setup their hypervisor-specific systemvmtemplates. In a given environment there wouldn't be thousands of systemvmtemplates, but can have thousands of hosts. So, instead of scanning the entire cloud.host table, we can make calculate guess by returning unique hypervisors of systemvm templates which are ready. This method was used in ::processConnect() when an agent joins, to speed up its handling. Signed-off-by: Rohit Yadav --- .../com/cloud/resource/ResourceManager.java | 2 +- .../com/cloud/storage/dao/VMTemplateDao.java | 2 ++ .../cloud/storage/dao/VMTemplateDaoImpl.java | 14 ++++++---- .../com/cloud/api/query/QueryManagerImpl.java | 2 +- .../cloud/resource/ResourceManagerImpl.java | 26 +++++-------------- .../storage/download/DownloadListener.java | 2 +- .../resource/MockResourceManagerImpl.java | 2 +- 7 files changed, 22 insertions(+), 28 deletions(-) diff --git a/engine/components-api/src/main/java/com/cloud/resource/ResourceManager.java b/engine/components-api/src/main/java/com/cloud/resource/ResourceManager.java index 9308be5fb32..235ed46784d 100755 --- a/engine/components-api/src/main/java/com/cloud/resource/ResourceManager.java +++ b/engine/components-api/src/main/java/com/cloud/resource/ResourceManager.java @@ -132,7 +132,7 @@ public interface ResourceManager extends ResourceService, Configurable { public List listAllHostsInAllZonesByType(Type type); - public List listAvailHypervisorInZone(Long hostId, Long zoneId); + public List listAvailHypervisorInZone(Long zoneId); public HostVO findHostByGuid(String guid); diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDao.java index c1678d2ba72..f1b01d12b64 100644 --- a/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDao.java +++ b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDao.java @@ -67,6 +67,8 @@ public interface VMTemplateDao extends GenericDao, StateDao< public List userIsoSearch(boolean listRemoved); + List listAllReadySystemVMTemplates(Long zoneId); + VMTemplateVO findSystemVMTemplate(long zoneId); VMTemplateVO findSystemVMReadyTemplate(long zoneId, HypervisorType hypervisorType); diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDaoImpl.java index 7e4ff2d55ed..84643beb83d 100644 --- a/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -551,17 +551,22 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } @Override - public VMTemplateVO findSystemVMReadyTemplate(long zoneId, HypervisorType hypervisorType) { + public List listAllReadySystemVMTemplates(Long zoneId) { SearchCriteria sc = readySystemTemplateSearch.create(); sc.setParameters("templateType", Storage.TemplateType.SYSTEM); sc.setParameters("state", VirtualMachineTemplate.State.Active); sc.setJoinParameters("tmplHyper", "type", Host.Type.Routing); - sc.setJoinParameters("tmplHyper", "zoneId", zoneId); + if (zoneId != null) { + sc.setJoinParameters("tmplHyper", "zoneId", zoneId); + } sc.setJoinParameters("vmTemplateJoinTemplateStoreRef", "downloadState", new VMTemplateStorageResourceAssoc.Status[] {VMTemplateStorageResourceAssoc.Status.DOWNLOADED, VMTemplateStorageResourceAssoc.Status.BYPASSED}); - // order by descending order of id - List tmplts = listBy(sc, new Filter(VMTemplateVO.class, "id", false, null, null)); + return listBy(sc, new Filter(VMTemplateVO.class, "id", false, null, null)); + } + @Override + public VMTemplateVO findSystemVMReadyTemplate(long zoneId, HypervisorType hypervisorType) { + List tmplts = listAllReadySystemVMTemplates(zoneId); if (tmplts.size() > 0) { if (hypervisorType == HypervisorType.Any) { return tmplts.get(0); @@ -571,7 +576,6 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem return tmplt; } } - } return null; } diff --git a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java index e654207c615..7cef9154e8f 100644 --- a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java @@ -4207,7 +4207,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q // check if zone is configured, if not, just return empty list List hypers = null; if (!isIso) { - hypers = _resourceMgr.listAvailHypervisorInZone(null, null); + hypers = _resourceMgr.listAvailHypervisorInZone(null); if (hypers == null || hypers.isEmpty()) { return new Pair, Integer>(new ArrayList(), 0); } diff --git a/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java b/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java index 2f0d93b2c81..67982a26886 100755 --- a/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Random; +import java.util.Set; import javax.inject.Inject; import javax.naming.ConfigurationException; @@ -3275,26 +3276,13 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } @Override - public List listAvailHypervisorInZone(final Long hostId, final Long zoneId) { - final SearchCriteria sc = _hypervisorsInDC.create(); - if (zoneId != null) { - sc.setParameters("dataCenter", zoneId); + public List listAvailHypervisorInZone(final Long zoneId) { + List systemVMTemplates = _templateDao.listAllReadySystemVMTemplates(zoneId); + final Set hypervisors = new HashSet<>(); + for (final VMTemplateVO systemVMTemplate : systemVMTemplates) { + hypervisors.add(systemVMTemplate.getHypervisorType()); } - if (hostId != null) { - // exclude the given host, since we want to check what hypervisor is already handled - // in adding this new host - sc.setParameters("id", hostId); - } - sc.setParameters("type", Host.Type.Routing); - - // The search is not able to return list of enums, so getting - // list of hypervisors as strings and then converting them to enum - final List hvs = _hostDao.customSearch(sc, null); - final List hypervisors = new ArrayList(); - for (final String hv : hvs) { - hypervisors.add(HypervisorType.getType(hv)); - } - return hypervisors; + return new ArrayList<>(hypervisors); } @Override diff --git a/server/src/main/java/com/cloud/storage/download/DownloadListener.java b/server/src/main/java/com/cloud/storage/download/DownloadListener.java index 9f528195bfa..8909a9942f9 100644 --- a/server/src/main/java/com/cloud/storage/download/DownloadListener.java +++ b/server/src/main/java/com/cloud/storage/download/DownloadListener.java @@ -275,7 +275,7 @@ public class DownloadListener implements Listener { @Override public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (cmd instanceof StartupRoutingCommand) { - List hypers = _resourceMgr.listAvailHypervisorInZone(agent.getId(), agent.getDataCenterId()); + List hypers = _resourceMgr.listAvailHypervisorInZone(agent.getDataCenterId()); HypervisorType hostHyper = agent.getHypervisorType(); if (hypers.contains(hostHyper)) { return; diff --git a/server/src/test/java/com/cloud/resource/MockResourceManagerImpl.java b/server/src/test/java/com/cloud/resource/MockResourceManagerImpl.java index 73d4adf050b..5bb0ff971a8 100755 --- a/server/src/test/java/com/cloud/resource/MockResourceManagerImpl.java +++ b/server/src/test/java/com/cloud/resource/MockResourceManagerImpl.java @@ -438,7 +438,7 @@ public class MockResourceManagerImpl extends ManagerBase implements ResourceMana * @see com.cloud.resource.ResourceManager#listAvailHypervisorInZone(java.lang.Long, java.lang.Long) */ @Override - public List listAvailHypervisorInZone(final Long hostId, final Long zoneId) { + public List listAvailHypervisorInZone(final Long zoneId) { // TODO Auto-generated method stub return null; }