You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sr...@apache.org on 2015/09/10 01:41:54 UTC
ambari git commit: AMBARI-13035. BE / Hosts Page Performance:
alerts_summary takes too long to load (srimanth)
Repository: ambari
Updated Branches:
refs/heads/branch-2.1 59371e6cf -> 34180fb27
AMBARI-13035. BE / Hosts Page Performance: alerts_summary takes too long to load (srimanth)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/34180fb2
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/34180fb2
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/34180fb2
Branch: refs/heads/branch-2.1
Commit: 34180fb27851df7d84e682877ef2291ae452b57d
Parents: 59371e6
Author: Srimanth Gunturi <sg...@hortonworks.com>
Authored: Tue Sep 8 11:21:56 2015 -0700
Committer: Srimanth Gunturi <sg...@hortonworks.com>
Committed: Wed Sep 9 16:41:37 2015 -0700
----------------------------------------------------------------------
.../internal/AlertSummaryPropertyProvider.java | 57 ++++++++++++--
.../apache/ambari/server/orm/dao/AlertsDAO.java | 41 ++++++++++
.../server/orm/dao/HostAlertSummaryDTO.java | 63 +++++++++++++++
.../ambari/server/orm/dao/AlertsDAOTest.java | 81 ++++++++++++++++++++
4 files changed, 237 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/34180fb2/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java
index 2e8cf83..5c6bc85 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java
@@ -89,22 +89,60 @@ public class AlertSummaryPropertyProvider extends BaseProvider implements Proper
@Override
public Set<Resource> populateResources(Set<Resource> resources,
Request request, Predicate predicate) throws SystemException {
-
Set<String> propertyIds = getRequestPropertyIds(request, predicate);
try {
+ // Optimization:
+ // Some information can be determined more efficiently when requested in bulk
+ // for an entire cluster at once.
+ // For Example:
+ // (1) Cluster level alert-status counts
+ // (2) Per host alert-status counts
+ // These can be determined in 1 SQL call per cluster, and results used multiple times.
+ Map<Long, Map<String, AlertSummaryDTO>> perHostSummaryMap = new HashMap<Long, Map<String, AlertSummaryDTO>>();
+ Map<Long, AlertHostSummaryDTO> hostsSummaryMap = new HashMap<Long, AlertHostSummaryDTO>();
+ Map<String, Cluster> resourcesClusterMap = new HashMap<String, Cluster>();
+ for (Resource res : resources) {
+ String clusterName = (String) res.getPropertyValue(m_clusterPropertyId);
+ if (clusterName == null || resourcesClusterMap.containsKey(clusterName)) {
+ continue;
+ }
+ Cluster cluster = s_clusters.get().getCluster(clusterName);
+ resourcesClusterMap.put(clusterName, cluster);
+ }
+ for (Cluster cluster : resourcesClusterMap.values()) {
+ long clusterId = cluster.getClusterId();
+ switch (m_resourceType.getInternalType()) {
+ case Cluster:
+ // only make the calculation if asked
+ if (BaseProvider.isPropertyRequested(ALERTS_SUMMARY_HOSTS, propertyIds)) {
+ hostsSummaryMap.put(clusterId, s_dao.findCurrentHostCounts(clusterId));
+ }
+ break;
+ case Host:
+ if (resources.size() > 1) {
+ // More efficient to get information for all hosts in 1 call
+ Map<String, AlertSummaryDTO> perHostCounts = s_dao.findCurrentPerHostCounts(clusterId);
+ perHostSummaryMap.put(clusterId, perHostCounts);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
for (Resource res : resources) {
- populateResource(res, propertyIds);
+ populateResource(res, propertyIds, perHostSummaryMap, hostsSummaryMap);
}
} catch (AmbariException e) {
LOG.error("Could not load built-in alerts - Executor exception ({})",
e.getMessage());
}
-
return resources;
}
- private void populateResource(Resource resource, Set<String> requestedIds) throws AmbariException {
+ private void populateResource(Resource resource, Set<String> requestedIds, Map<Long, Map<String,
+ AlertSummaryDTO>> perHostSummaryMap, Map<Long, AlertHostSummaryDTO> hostsSummaryMap) throws AmbariException {
AlertSummaryDTO summary = null;
AlertHostSummaryDTO hostSummary = null;
@@ -130,7 +168,11 @@ public class AlertSummaryPropertyProvider extends BaseProvider implements Proper
// only make the calculation if asked
if (BaseProvider.isPropertyRequested(ALERTS_SUMMARY_HOSTS,
requestedIds)) {
- hostSummary = s_dao.findCurrentHostCounts(clusterId);
+ if (hostsSummaryMap.containsKey(cluster.getClusterId())) {
+ hostSummary = hostsSummaryMap.get(cluster.getClusterId());
+ } else {
+ hostSummary = s_dao.findCurrentHostCounts(clusterId);
+ }
}
break;
@@ -138,7 +180,12 @@ public class AlertSummaryPropertyProvider extends BaseProvider implements Proper
summary = s_dao.findCurrentCounts(cluster.getClusterId(), typeId, null);
break;
case Host:
+ if (perHostSummaryMap.containsKey(cluster.getClusterId()) &&
+ perHostSummaryMap.get(cluster.getClusterId()).containsKey(typeId)) {
+ summary = perHostSummaryMap.get(cluster.getClusterId()).get(typeId);
+ } else {
summary = s_dao.findCurrentCounts(cluster.getClusterId(), null, typeId);
+ }
break;
default:
break;
http://git-wip-us.apache.org/repos/asf/ambari/blob/34180fb2/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
index adcc710..73ca637 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
@@ -20,6 +20,7 @@ package org.apache.ambari.server.orm.dao;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -86,6 +87,15 @@ public class AlertsDAO {
+ "SUM(CASE WHEN alert.maintenanceState != :maintenanceStateOff THEN 1 ELSE 0 END)) "
+ "FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId";
+ private static final String ALERT_COUNT_PER_HOST_SQL_TEMPLATE = "SELECT NEW %s("
+ + "history.hostName, "
+ + "SUM(CASE WHEN history.alertState = :okState AND alert.maintenanceState = :maintenanceStateOff THEN 1 ELSE 0 END), "
+ + "SUM(CASE WHEN history.alertState = :warningState AND alert.maintenanceState = :maintenanceStateOff THEN 1 ELSE 0 END), "
+ + "SUM(CASE WHEN history.alertState = :criticalState AND alert.maintenanceState = :maintenanceStateOff THEN 1 ELSE 0 END), "
+ + "SUM(CASE WHEN history.alertState = :unknownState AND alert.maintenanceState = :maintenanceStateOff THEN 1 ELSE 0 END), "
+ + "SUM(CASE WHEN alert.maintenanceState != :maintenanceStateOff THEN 1 ELSE 0 END)) "
+ + "FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId GROUP BY history.hostName";
+
/**
* JPA entity manager
*/
@@ -445,6 +455,37 @@ public class AlertsDAO {
}
/**
+ * Retrieves the summary information for all the hosts in the provided cluster.
+ * The result is mapping from hostname to summary DTO.
+ *
+ * @param clusterId
+ * the cluster id
+ * @return map from hostnames to summary DTO
+ */
+ @RequiresSession
+ public Map<String, AlertSummaryDTO> findCurrentPerHostCounts(long clusterId) {
+ String sql = String.format(ALERT_COUNT_PER_HOST_SQL_TEMPLATE, HostAlertSummaryDTO.class.getName());
+
+ StringBuilder sb = new StringBuilder(sql);
+
+ TypedQuery<HostAlertSummaryDTO> query = m_entityManagerProvider.get().createQuery(sb.toString(), HostAlertSummaryDTO.class);
+
+ query.setParameter("clusterId", Long.valueOf(clusterId));
+ query.setParameter("okState", AlertState.OK);
+ query.setParameter("warningState", AlertState.WARNING);
+ query.setParameter("criticalState", AlertState.CRITICAL);
+ query.setParameter("unknownState", AlertState.UNKNOWN);
+ query.setParameter("maintenanceStateOff", MaintenanceState.OFF);
+
+ Map<String, AlertSummaryDTO> map = new HashMap<String, AlertSummaryDTO>();
+ List<HostAlertSummaryDTO> resultList = m_daoUtils.selectList(query);
+ for (HostAlertSummaryDTO result : resultList) {
+ map.put(result.getHostName(), result);
+ }
+ return map;
+ }
+
+ /**
* Retrieve the summary alert information for all hosts. This is different
* from {@link #findCurrentCounts(long, String, String)} since this will
* return only alerts related to hosts and those values will be the total
http://git-wip-us.apache.org/repos/asf/ambari/blob/34180fb2/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostAlertSummaryDTO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostAlertSummaryDTO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostAlertSummaryDTO.java
new file mode 100644
index 0000000..4f9fe66
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostAlertSummaryDTO.java
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.orm.dao;
+
+/**
+ * Used when getting per host alert summary in bulk where a single database call will
+ * return alert summaries for multiple hosts. In addition to the information
+ * returned by {@link AlertSummaryDTO}, a host name is provided.
+ */
+public class HostAlertSummaryDTO extends AlertSummaryDTO {
+
+ private String hostName;
+
+ /**
+ * Constructor, used by JPA. JPA invokes this constructor, even if there are no
+ * records in the resultset. In that case, all arguments are {@code null}.
+ *
+ * @param hostName
+ * @param ok
+ * @param warning
+ * @param critical
+ * @param unknown
+ * @param maintenance
+ */
+ public HostAlertSummaryDTO(String hostName, Number ok, Number warning, Number critical, Number unknown, Number maintenance) {
+ super(ok, warning, critical, unknown, maintenance);
+ this.setHostName(hostName);
+ }
+
+ /**
+ * Provide host name for this alerts summary
+ *
+ * @return
+ */
+ public String getHostName() {
+ return hostName;
+ }
+
+ /**
+ * Set host name for this alerts summary
+ *
+ * @param hostName
+ */
+ public void setHostName(String hostName) {
+ this.hostName = hostName;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/34180fb2/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
index f267544..0bbe998 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
@@ -29,6 +29,7 @@ import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
+import java.util.Map;
import java.util.TimeZone;
import java.util.UUID;
@@ -653,6 +654,86 @@ public class AlertsDAOTest {
*
*/
@Test
+ public void testFindCurrentPerHostSummary() throws Exception {
+ // Add extra host and alerts
+ m_helper.addHost(m_clusters, m_cluster, "h2");
+ List<AlertDefinitionEntity> definitions = m_definitionDao.findAll();
+ AlertDefinitionEntity definition = definitions.get(0);
+ AlertHistoryEntity h2CriticalHistory = new AlertHistoryEntity();
+ h2CriticalHistory.setServiceName(definition.getServiceName());
+ h2CriticalHistory.setClusterId(m_cluster.getClusterId());
+ h2CriticalHistory.setAlertDefinition(definition);
+ h2CriticalHistory.setAlertLabel(definition.getDefinitionName() + " h2");
+ h2CriticalHistory.setAlertText(definition.getDefinitionName() + " h2");
+ h2CriticalHistory.setAlertTimestamp(calendar.getTimeInMillis());
+ h2CriticalHistory.setComponentName(definition.getComponentName());
+ h2CriticalHistory.setHostName("h2");
+ h2CriticalHistory.setAlertState(AlertState.CRITICAL);
+ m_dao.create(h2CriticalHistory);
+ AlertCurrentEntity h2CriticalCurrent = new AlertCurrentEntity();
+ h2CriticalCurrent.setAlertHistory(h2CriticalHistory);
+ h2CriticalCurrent.setLatestTimestamp(new Date().getTime());
+ h2CriticalCurrent.setOriginalTimestamp(new Date().getTime() - 10800000);
+ h2CriticalCurrent.setMaintenanceState(MaintenanceState.OFF);
+ m_dao.create(h2CriticalCurrent);
+
+ try {
+ long clusterId = m_cluster.getClusterId();
+ AlertSummaryDTO summary = m_dao.findCurrentCounts(clusterId, null, null);
+ assertEquals(5, summary.getOkCount());
+
+ AlertHistoryEntity h1 = m_dao.findCurrentByCluster(clusterId).get(2).getAlertHistory();
+ AlertHistoryEntity h2 = m_dao.findCurrentByCluster(clusterId).get(3).getAlertHistory();
+ AlertHistoryEntity h3 = m_dao.findCurrentByCluster(clusterId).get(4).getAlertHistory();
+
+ h1.setAlertState(AlertState.WARNING);
+ m_dao.merge(h1);
+ h2.setAlertState(AlertState.CRITICAL);
+ m_dao.merge(h2);
+ h3.setAlertState(AlertState.UNKNOWN);
+ m_dao.merge(h3);
+
+ Map<String, AlertSummaryDTO> perHostSummary = m_dao.findCurrentPerHostCounts(clusterId);
+
+ AlertSummaryDTO h1summary = m_dao.findCurrentCounts(clusterId, null, "h1");
+ assertEquals(2, h1summary.getOkCount());
+ assertEquals(1, h1summary.getWarningCount());
+ assertEquals(1, h1summary.getCriticalCount());
+ assertEquals(1, h1summary.getUnknownCount());
+ assertEquals(0, h1summary.getMaintenanceCount());
+
+ AlertSummaryDTO h2summary = m_dao.findCurrentCounts(clusterId, null, "h2");
+ assertEquals(0, h2summary.getOkCount());
+ assertEquals(0, h2summary.getWarningCount());
+ assertEquals(1, h2summary.getCriticalCount());
+ assertEquals(0, h2summary.getUnknownCount());
+ assertEquals(0, h2summary.getMaintenanceCount());
+
+ AlertSummaryDTO h1PerHostSummary = perHostSummary.get("h1");
+ assertEquals(h1PerHostSummary.getOkCount(), h1summary.getOkCount());
+ assertEquals(h1PerHostSummary.getWarningCount(), h1summary.getWarningCount());
+ assertEquals(h1PerHostSummary.getCriticalCount(), h1summary.getCriticalCount());
+ assertEquals(h1PerHostSummary.getUnknownCount(), h1summary.getUnknownCount());
+ assertEquals(h1PerHostSummary.getMaintenanceCount(), h1summary.getMaintenanceCount());
+
+ AlertSummaryDTO h2PerHostSummary = perHostSummary.get("h2");
+ assertEquals(h2PerHostSummary.getOkCount(), h2summary.getOkCount());
+ assertEquals(h2PerHostSummary.getWarningCount(), h2summary.getWarningCount());
+ assertEquals(h2PerHostSummary.getCriticalCount(), h2summary.getCriticalCount());
+ assertEquals(h2PerHostSummary.getUnknownCount(), h2summary.getUnknownCount());
+ assertEquals(h2PerHostSummary.getMaintenanceCount(), h2summary.getMaintenanceCount());
+ } finally {
+ // Cleanup extra host and alerts to not effect other tests
+ m_dao.remove(h2CriticalCurrent);
+ m_dao.remove(h2CriticalHistory);
+ m_clusters.unmapHostFromCluster("h2", m_cluster.getClusterName());
+ }
+ }
+
+ /**
+ *
+ */
+ @Test
public void testFindCurrentHostSummary() throws Exception {
// start out with 1 since all alerts are for a single host and are OK
AlertHostSummaryDTO summary = m_dao.findCurrentHostCounts(m_cluster.getClusterId());