From 807cd6a830ea4b1fbf7c5a92ede90a6a36c9f874 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Sat, 4 May 2024 15:48:26 +0530 Subject: [PATCH] metrics: speed up list zones and cluster metrics APIs Also add a flag to disable on-the-fly metrics computation when the list metrics APIs for zones and clusters are called. Signed-off-by: Rohit Yadav --- .../java/com/cloud/dc/dao/ClusterDao.java | 4 + .../java/com/cloud/dc/dao/ClusterDaoImpl.java | 20 ++++ .../main/java/com/cloud/host/dao/HostDao.java | 2 + .../java/com/cloud/host/dao/HostDaoImpl.java | 26 ++++- .../cloudstack/metrics/MetricsService.java | 8 +- .../metrics/MetricsServiceImpl.java | 108 +++++++++++------- 6 files changed, 125 insertions(+), 43 deletions(-) diff --git a/engine/schema/src/main/java/com/cloud/dc/dao/ClusterDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/ClusterDao.java index ab9c5cab8c4..0e726b806cb 100644 --- a/engine/schema/src/main/java/com/cloud/dc/dao/ClusterDao.java +++ b/engine/schema/src/main/java/com/cloud/dc/dao/ClusterDao.java @@ -45,6 +45,10 @@ public interface ClusterDao extends GenericDao { List listClustersWithDisabledPods(long zoneId); + Integer countAllByDcId(long zoneId); + + Integer countAllManagedAndEnabledByDcId(long zoneId); + List listClustersByDcId(long zoneId); List listAllClusters(Long zoneId); diff --git a/engine/schema/src/main/java/com/cloud/dc/dao/ClusterDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/ClusterDaoImpl.java index 4d9bedba966..069a8759651 100644 --- a/engine/schema/src/main/java/com/cloud/dc/dao/ClusterDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/dc/dao/ClusterDaoImpl.java @@ -22,6 +22,7 @@ import com.cloud.dc.ClusterVO; import com.cloud.dc.HostPodVO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.org.Grouping; +import com.cloud.org.Managed; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.JoinBuilder; @@ -94,6 +95,8 @@ public class ClusterDaoImpl extends GenericDaoBase implements C ZoneClusterSearch = createSearchBuilder(); ZoneClusterSearch.and("dataCenterId", ZoneClusterSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + ZoneClusterSearch.and("allocationState", ZoneClusterSearch.entity().getAllocationState(), Op.EQ); + ZoneClusterSearch.and("managedState", ZoneClusterSearch.entity().getManagedState(), Op.EQ); ZoneClusterSearch.done(); ClusterIdSearch = createSearchBuilder(Long.class); @@ -252,6 +255,23 @@ public class ClusterDaoImpl extends GenericDaoBase implements C return customSearch(sc, null); } + @Override + public Integer countAllByDcId(long zoneId) { + SearchCriteria sc = ZoneClusterSearch.create(); + sc.setParameters("dataCenterId", zoneId); + return getCount(sc); + } + + @Override + public Integer countAllManagedAndEnabledByDcId(long zoneId) { + SearchCriteria sc = ZoneClusterSearch.create(); + sc.setParameters("dataCenterId", zoneId); + sc.setParameters("allocationState", Grouping.AllocationState.Enabled); + sc.setParameters("managedState", Managed.ManagedState.Managed); + + return getCount(sc); + } + @Override public List listClustersByDcId(long zoneId) { SearchCriteria sc = ZoneClusterSearch.create(); diff --git a/engine/schema/src/main/java/com/cloud/host/dao/HostDao.java b/engine/schema/src/main/java/com/cloud/host/dao/HostDao.java index df410d67c67..423d79a90c8 100644 --- a/engine/schema/src/main/java/com/cloud/host/dao/HostDao.java +++ b/engine/schema/src/main/java/com/cloud/host/dao/HostDao.java @@ -39,6 +39,8 @@ public interface HostDao extends GenericDao, StateDao status); + Integer countAllByTypeInZone(long zoneId, final Host.Type type); Integer countUpAndEnabledHostsInZone(long zoneId); diff --git a/engine/schema/src/main/java/com/cloud/host/dao/HostDaoImpl.java b/engine/schema/src/main/java/com/cloud/host/dao/HostDaoImpl.java index e6eea05f94b..5785124a782 100644 --- a/engine/schema/src/main/java/com/cloud/host/dao/HostDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/host/dao/HostDaoImpl.java @@ -122,6 +122,7 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao protected SearchBuilder UnmanagedApplianceSearch; protected SearchBuilder MaintenanceCountSearch; protected SearchBuilder HostTypeCountSearch; + protected SearchBuilder HostTypeClusterCountSearch; protected SearchBuilder ResponsibleMsCountSearch; protected SearchBuilder HostTypeZoneCountSearch; protected SearchBuilder ClusterStatusSearch; @@ -187,6 +188,13 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao ResponsibleMsCountSearch.and("managementServerId", ResponsibleMsCountSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ); ResponsibleMsCountSearch.done(); + HostTypeClusterCountSearch = createSearchBuilder(); + HostTypeClusterCountSearch.and("cluster", HostTypeClusterCountSearch.entity().getClusterId(), SearchCriteria.Op.EQ); + HostTypeClusterCountSearch.and("type", HostTypeClusterCountSearch.entity().getType(), SearchCriteria.Op.EQ); + HostTypeClusterCountSearch.and("status", HostTypeClusterCountSearch.entity().getStatus(), SearchCriteria.Op.IN); + HostTypeClusterCountSearch.and("removed", HostTypeClusterCountSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + HostTypeClusterCountSearch.done(); + HostTypeZoneCountSearch = createSearchBuilder(); HostTypeZoneCountSearch.and("type", HostTypeZoneCountSearch.entity().getType(), SearchCriteria.Op.EQ); HostTypeZoneCountSearch.and("dc", HostTypeZoneCountSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); @@ -462,8 +470,7 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao sc.setParameters("resourceState", (Object[])states); sc.setParameters("cluster", clusterId); - List hosts = listBy(sc); - return hosts.size(); + return getCount(sc); } @Override @@ -473,6 +480,21 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao return getCount(sc); } + @Override + public Integer countAllInClusterByTypeAndStates(Long clusterId, final Host.Type type, List status) { + SearchCriteria sc = HostTypeClusterCountSearch.create(); + if (clusterId != null) { + sc.setParameters("cluster", clusterId); + } + if (type != null) { + sc.setParameters("type", type); + } + if (status != null) { + sc.setParameters("status", status.toArray()); + } + return getCount(sc); + } + @Override public Integer countAllByTypeInZone(long zoneId, Type type) { SearchCriteria sc = HostTypeCountSearch.create(); diff --git a/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsService.java b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsService.java index 48033dd7538..bb776368838 100644 --- a/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsService.java +++ b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsService.java @@ -30,6 +30,7 @@ import org.apache.cloudstack.api.response.StoragePoolResponse; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.api.response.VolumeResponse; import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.response.ClusterMetricsResponse; import org.apache.cloudstack.response.DbMetricsResponse; import org.apache.cloudstack.response.HostMetricsResponse; @@ -47,6 +48,11 @@ import com.cloud.utils.Pair; import com.cloud.utils.component.PluggableService; public interface MetricsService extends PluggableService { + + ConfigKey AllowListMetricsComputation = new ConfigKey<>("Advanced", Boolean.class, "allow.list.metrics.computation", "true", + "Whether the list zones and cluster metrics APIs are allowed metrics computation. Large environments may disabled this.", + true, ConfigKey.Scope.Global); + InfrastructureResponse listInfrastructure(); ListResponse searchForVmMetricsStats(ListVMsUsageHistoryCmd cmd); @@ -56,10 +62,10 @@ public interface MetricsService extends PluggableService { List listVmMetrics(List vmResponses); List listStoragePoolMetrics(List poolResponses); List listHostMetrics(List poolResponses); - List listManagementServerMetrics(List poolResponses); List listClusterMetrics(Pair, Integer> clusterResponses); List listZoneMetrics(List poolResponses); + List listManagementServerMetrics(List poolResponses); UsageServerMetricsResponse listUsageServerMetrics(); DbMetricsResponse listDbMetrics(); } diff --git a/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java index 4bbe7627f2c..7c03bccce61 100644 --- a/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java +++ b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java @@ -58,6 +58,8 @@ import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.api.response.VolumeResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.management.ManagementServerHost.State; import org.apache.cloudstack.response.ClusterMetricsResponse; import org.apache.cloudstack.response.DbMetricsResponse; @@ -107,8 +109,6 @@ import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.network.router.VirtualRouter; import com.cloud.org.Cluster; -import com.cloud.org.Grouping; -import com.cloud.org.Managed; import com.cloud.server.DbStatsCollection; import com.cloud.server.ManagementServerHostStats; import com.cloud.server.StatsCollector; @@ -138,7 +138,7 @@ import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.dao.VmStatsDao; import com.google.gson.Gson; -public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements MetricsService { +public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements MetricsService, Configurable { private static final Logger LOGGER = Logger.getLogger(MetricsServiceImpl.class); @Inject @@ -192,7 +192,6 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements } private void updateHostMetrics(final HostMetrics hostMetrics, final HostJoinVO host) { - hostMetrics.incrTotalHosts(); hostMetrics.addCpuAllocated(host.getCpuReservedCapacity() + host.getCpuUsedCapacity()); hostMetrics.addMemoryAllocated(host.getMemReservedCapacity() + host.getMemUsedCapacity()); final HostStats hostStats = ApiDBUtils.getHostStatistics(host.getId()); @@ -570,7 +569,7 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements } } response.setCpuSockets(cpuSockets); - response.setManagementServers(managementServerHostDao.listAll().size()); + response.setManagementServers(managementServerHostDao.countAll()); return response; } @@ -747,28 +746,36 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements } final Long clusterId = cluster.getId(); - // CPU and memory capacities final CapacityDaoImpl.SummedCapacity cpuCapacity = getCapacity((int) Capacity.CAPACITY_TYPE_CPU, null, clusterId); final CapacityDaoImpl.SummedCapacity memoryCapacity = getCapacity((int) Capacity.CAPACITY_TYPE_MEMORY, null, clusterId); final HostMetrics hostMetrics = new HostMetrics(cpuCapacity, memoryCapacity); + hostMetrics.setUpResources(Long.valueOf(hostDao.countAllInClusterByTypeAndStates(clusterId, Host.Type.Routing, List.of(Status.Up)))); + hostMetrics.setTotalResources(Long.valueOf(hostDao.countAllInClusterByTypeAndStates(clusterId, Host.Type.Routing, null))); + hostMetrics.setTotalHosts(hostMetrics.getTotalResources()); - for (final Host host: hostDao.findByClusterId(clusterId)) { - if (host == null || host.getType() != Host.Type.Routing) { - continue; + if (AllowListMetricsComputation.value()) { + for (final Host host : hostDao.findByClusterId(clusterId)) { + if (host == null || host.getType() != Host.Type.Routing) { + continue; + } + updateHostMetrics(hostMetrics, hostJoinDao.findById(host.getId())); } - if (host.getStatus() == Status.Up) { - hostMetrics.incrUpResources(); + } else { + if (cpuCapacity != null) { + hostMetrics.setCpuAllocated(cpuCapacity.getAllocatedCapacity()); + } + if (memoryCapacity != null) { + hostMetrics.setMemoryAllocated(memoryCapacity.getAllocatedCapacity()); } - hostMetrics.incrTotalResources(); - updateHostMetrics(hostMetrics, hostJoinDao.findById(host.getId())); } - metricsResponse.setState(clusterResponse.getAllocationState(), clusterResponse.getManagedState()); - metricsResponse.setResources(hostMetrics.getUpResources(), hostMetrics.getTotalResources()); addHostCpuMetricsToResponse(metricsResponse, clusterId, hostMetrics); addHostMemoryMetricsToResponse(metricsResponse, clusterId, hostMetrics); metricsResponse.setHasAnnotation(clusterResponse.hasAnnotation()); + metricsResponse.setState(clusterResponse.getAllocationState(), clusterResponse.getManagedState()); + metricsResponse.setResources(hostMetrics.getUpResources(), hostMetrics.getTotalResources()); + metricsResponses.add(metricsResponse); } return metricsResponses; @@ -915,35 +922,38 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements final CapacityDaoImpl.SummedCapacity cpuCapacity = getCapacity((int) Capacity.CAPACITY_TYPE_CPU, zoneId, null); final CapacityDaoImpl.SummedCapacity memoryCapacity = getCapacity((int) Capacity.CAPACITY_TYPE_MEMORY, zoneId, null); final HostMetrics hostMetrics = new HostMetrics(cpuCapacity, memoryCapacity); + hostMetrics.setUpResources(Long.valueOf(clusterDao.countAllManagedAndEnabledByDcId(zoneId))); + hostMetrics.setTotalResources(Long.valueOf(clusterDao.countAllByDcId(zoneId))); + hostMetrics.setTotalHosts(Long.valueOf(hostDao.countAllByTypeInZone(zoneId, Host.Type.Routing))); - for (final Cluster cluster : clusterDao.listClustersByDcId(zoneId)) { - if (cluster == null) { - continue; - } - hostMetrics.incrTotalResources(); - if (cluster.getAllocationState() == Grouping.AllocationState.Enabled - && cluster.getManagedState() == Managed.ManagedState.Managed) { - hostMetrics.incrUpResources(); - } - - for (final Host host: hostDao.findByClusterId(cluster.getId())) { - if (host == null || host.getType() != Host.Type.Routing) { + if (AllowListMetricsComputation.value()) { + for (final Cluster cluster : clusterDao.listClustersByDcId(zoneId)) { + if (cluster == null) { continue; } - updateHostMetrics(hostMetrics, hostJoinDao.findById(host.getId())); + for (final Host host: hostDao.findByClusterId(cluster.getId())) { + if (host == null || host.getType() != Host.Type.Routing) { + continue; + } + updateHostMetrics(hostMetrics, hostJoinDao.findById(host.getId())); + } + } + } else { + if (cpuCapacity != null) { + hostMetrics.setCpuAllocated(cpuCapacity.getAllocatedCapacity()); + } + if (memoryCapacity != null) { + hostMetrics.setMemoryAllocated(memoryCapacity.getAllocatedCapacity()); } } + addHostCpuMetricsToResponse(metricsResponse, null, hostMetrics); + addHostMemoryMetricsToResponse(metricsResponse, null, hostMetrics); + metricsResponse.setHasAnnotation(zoneResponse.hasAnnotation()); metricsResponse.setState(zoneResponse.getAllocationState()); metricsResponse.setResource(hostMetrics.getUpResources(), hostMetrics.getTotalResources()); - final Long totalHosts = hostMetrics.getTotalHosts(); - // CPU - addHostCpuMetricsToResponse(metricsResponse, null, hostMetrics); - // Memory - addHostMemoryMetricsToResponse(metricsResponse, null, hostMetrics); - metricsResponses.add(metricsResponse); } return metricsResponses; @@ -1081,6 +1091,16 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements return cmdList; } + @Override + public String getConfigComponentName() { + return MetricsService.class.getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] {AllowListMetricsComputation}; + } + private class HostMetrics { // CPU metrics private Long totalCpu = 0L; @@ -1106,6 +1126,14 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements } } + public void setCpuAllocated(Long cpuAllocated) { + this.cpuAllocated = cpuAllocated; + } + + public void setMemoryAllocated(Long memoryAllocated) { + this.memoryAllocated = memoryAllocated; + } + public void addCpuAllocated(Long cpuAllocated) { this.cpuAllocated += cpuAllocated; } @@ -1134,16 +1162,16 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements } } - public void incrTotalHosts() { - this.totalHosts++; + public void setTotalHosts(Long totalHosts) { + this.totalHosts = totalHosts; } - public void incrTotalResources() { - this.totalResources++; + public void setTotalResources(Long totalResources) { + this.totalResources = totalResources; } - public void incrUpResources() { - this.upResources++; + public void setUpResources(Long upResources) { + this.upResources = upResources; } public Long getTotalCpu() {