From 1feb6cdccb80aa2f6d62b110f337a07eedafa8f3 Mon Sep 17 00:00:00 2001 From: jianghuazhu <740087514@qq.com> Date: Thu, 19 Sep 2024 01:17:45 +0800 Subject: [PATCH 1/5] HDDS-11469. Statistics of Pipeline and Container --- .../hdds/scm/container/ContainerManager.java | 2 +- .../scm/container/ContainerManagerImpl.java | 26 ++++- .../scm/container/ContainerManagerMXBean.java | 39 ++++++++ .../scm/pipeline/PipelineManagerImpl.java | 4 +- .../resources/webapps/scm/scm-overview.html | 64 +++++++++++++ .../src/main/resources/webapps/scm/scm.js | 58 +++++++++++ .../container/TestContainerManagerMXBean.java | 96 +++++++++++++++++++ 7 files changed, 283 insertions(+), 6 deletions(-) create mode 100644 hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerMXBean.java create mode 100644 hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerManagerMXBean.java diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManager.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManager.java index 3eba240533e3..763d7a4118db 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManager.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManager.java @@ -34,7 +34,7 @@ * ContainerManager is responsible for keeping track of all Containers and * managing all containers operations like creating, deleting etc. */ -public interface ContainerManager extends Closeable { +public interface ContainerManager extends Closeable, ContainerManagerMXBean { /** * Reinitialize the containerManager with the updated container store. diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerImpl.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerImpl.java index 00aee0f62c25..b1c163f96a98 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerImpl.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerImpl.java @@ -28,6 +28,7 @@ import java.util.Optional; import java.util.Random; import java.util.Set; +import java.util.HashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -48,11 +49,15 @@ import org.apache.hadoop.hdds.scm.pipeline.Pipeline; import org.apache.hadoop.hdds.scm.pipeline.PipelineManager; import org.apache.hadoop.hdds.utils.db.Table; +import org.apache.hadoop.metrics2.util.MBeans; import org.apache.hadoop.ozone.common.statemachine.InvalidStateTransitionException; import org.apache.hadoop.util.Time; +import org.apache.ratis.protocol.exceptions.NotLeaderException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.management.ObjectName; + import static java.util.Comparator.reverseOrder; import static org.apache.hadoop.hdds.scm.ha.SequenceIdGenerator.CONTAINER_ID; import static org.apache.hadoop.hdds.utils.CollectionUtils.findTopN; @@ -86,9 +91,8 @@ public class ContainerManagerImpl implements ContainerManager { @SuppressWarnings("java:S2245") // no need for secure random private final Random random = new Random(); - /** - * - */ + private ObjectName pmInfoBean; + public ContainerManagerImpl( final Configuration conf, final SCMHAManager scmHaManager, @@ -116,6 +120,8 @@ public ContainerManagerImpl( ScmConfigKeys.OZONE_SCM_PIPELINE_OWNER_CONTAINER_COUNT_DEFAULT); this.scmContainerManagerMetrics = SCMContainerManagerMetrics.create(); + this.pmInfoBean = MBeans.register("ContainerManager", + "SCMContainerManagerInfo", this); } @Override @@ -369,6 +375,16 @@ private int getOpenContainerCountPerPipeline(Pipeline pipeline) { ((double) minContainerCountPerDn / minPipelineCountPerDn)); } + @Override + public Map getContainerInfos() throws NotLeaderException { + final Map containerInfos = new HashMap<>(); + for (LifeCycleState state : LifeCycleState.values()) { + containerInfos.put(state.toString().toLowerCase(), + containerStateManager.getContainerIDs(state).size()); + } + return containerInfos; + } + /** * Returns the container ID's matching with specified owner. * @param pipeline @@ -449,6 +465,10 @@ private void throwContainerNotFoundException(final ContainerID id) @Override public void close() throws IOException { + if (pmInfoBean != null) { + MBeans.unregister(this.pmInfoBean); + pmInfoBean = null; + } containerStateManager.close(); } diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerMXBean.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerMXBean.java new file mode 100644 index 000000000000..7e1c465c73e4 --- /dev/null +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerMXBean.java @@ -0,0 +1,39 @@ +/** + * 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.hadoop.hdds.scm.container; + +import org.apache.hadoop.hdds.annotation.InterfaceAudience; +import org.apache.ratis.protocol.exceptions.NotLeaderException; + +import java.util.Map; + +/** + * This is the JMX management interface for information related + * to {@link ContainerManager}. + */ +@InterfaceAudience.Private +public interface ContainerManagerMXBean { + + /** + * Returns the number of containers in different state. + * @return state to number of container map. + * @throws NotLeaderException + */ + Map getContainerInfos() throws NotLeaderException; +} diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManagerImpl.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManagerImpl.java index 000d3e73633f..13164b418590 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManagerImpl.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManagerImpl.java @@ -779,11 +779,11 @@ public Pipeline waitOnePipelineReady(Collection pipelineIDs, public Map getPipelineInfo() throws NotLeaderException { final Map pipelineInfo = new HashMap<>(); for (Pipeline.PipelineState state : Pipeline.PipelineState.values()) { - pipelineInfo.put(state.toString(), 0); + pipelineInfo.put(state.toString().toLowerCase(), 0); } stateManager.getPipelines().forEach(pipeline -> pipelineInfo.computeIfPresent( - pipeline.getPipelineState().toString(), (k, v) -> v + 1)); + pipeline.getPipelineState().toString().toLowerCase(), (k, v) -> v + 1)); return pipelineInfo; } diff --git a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html index 0f233bf4ea18..9c48b410b33d 100644 --- a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html +++ b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html @@ -110,6 +110,70 @@

Space Statistics

+

Pipeline Statistics

+ + + + + + + + + + + + + + + + + + + + + + + +
Pipeline StateSize
Closed{{statistics.nodes.data.pipeline.closed}}
Allocated{{statistics.nodes.data.pipeline.allocated}}
Open{{statistics.nodes.data.pipeline.open}}
Dormant{{statistics.nodes.data.pipeline.dormant}}
+ +

Container Statistics

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Container StateSize
Open{{statistics.nodes.data.container.open}}
Closing{{statistics.nodes.data.container.closing}}
Quasi Closed{{statistics.nodes.data.container.quasi_closed}}
Closed{{statistics.nodes.data.container.closed}}
Deleting{{statistics.nodes.data.container.deleting}}
Deleted{{statistics.nodes.data.container.deleted}}
Recovering{{statistics.nodes.data.container.recovering}}
+

Node Status

diff --git a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm.js b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm.js index e00f8b8ede8c..02596894bb3e 100644 --- a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm.js +++ b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm.js @@ -52,6 +52,23 @@ scmused : "N/A", remaining : "N/A", nonscmused : "N/A" + }, + data : { + pipeline : { + closed : "N/A", + allocated : "N/A", + open : "N/A", + dormant : "N/A" + }, + container : { + open : "N/A", + closing : "N/A", + quasi_closed : "N/A", + closed : "N/A", + deleting : "N/A", + deleted : "N/A", + recovering : "N/A" + } } } } @@ -142,6 +159,47 @@ } }); }); + + $http.get("jmx?qry=Hadoop:service=SCMPipelineManager,name=SCMPipelineManagerInfo") + .then(function (result) { + const URLScheme = location.protocol.replace(":" , ""); + ctrl.scmpipelinemanager = result.data.beans[0]; + ctrl.scmpipelinemanager.PipelineInfo.forEach(({key, value}) => { + if(key == "closed") { + $scope.statistics.nodes.data.pipeline.closed = value; + } else if(key == "allocated") { + $scope.statistics.nodes.data.pipeline.allocated = value; + } else if(key == "open") { + $scope.statistics.nodes.data.pipeline.open = value; + } else if(key == "dormant") { + $scope.statistics.nodes.data.pipeline.dormant = value; + } + }); + }); + + $http.get("jmx?qry=Hadoop:service=ContainerManager,name=SCMContainerManagerInfo") + .then(function (result) { + const URLScheme = location.protocol.replace(":" , ""); + ctrl.scmcontainermanager = result.data.beans[0]; + ctrl.scmcontainermanager.ContainerInfos.forEach(({key, value}) => { + if(key == "open") { + $scope.statistics.nodes.data.container.open = value; + } else if(key == "closing") { + $scope.statistics.nodes.data.container.closing = value; + } else if(key == "quasi_closed") { + $scope.statistics.nodes.data.container.quasi_closed = value; + } else if(key == "closed") { + $scope.statistics.nodes.data.container.closed = value; + } else if(key == "deleting") { + $scope.statistics.nodes.data.container.deleting = value; + } else if(key == "deleted") { + $scope.statistics.nodes.data.container.deleted = value; + } else if(key == "recovering") { + $scope.statistics.nodes.data.container.recovering = value; + } + }); + }); + /*if option is 'All' display all records else display specified record on page*/ $scope.UpdateRecordsToShow = () => { if($scope.RecordsToDisplay == 'All') { diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerManagerMXBean.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerManagerMXBean.java new file mode 100644 index 000000000000..b8eb521ab683 --- /dev/null +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerManagerMXBean.java @@ -0,0 +1,96 @@ +/** + * 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.hadoop.hdds.scm.container; + +import org.apache.hadoop.hdds.conf.OzoneConfiguration; +import org.apache.hadoop.ozone.MiniOzoneCluster; +import org.apache.ozone.test.GenericTestUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + +import javax.management.MBeanServer; +import javax.management.ObjectName; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.TabularData; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.util.Map; +import java.util.concurrent.TimeoutException; + +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + +/** + * Test cases to verify the metrics exposed by {@link ContainerManager} via MXBean. + */ +@Timeout(3000) +public class TestContainerManagerMXBean { + private MiniOzoneCluster cluster; + private MBeanServer mbs; + + @BeforeEach + public void init() throws IOException, TimeoutException, + InterruptedException { + OzoneConfiguration conf = new OzoneConfiguration(); + cluster = MiniOzoneCluster.newBuilder(conf).build(); + cluster.waitForClusterToBeReady(); + mbs = ManagementFactory.getPlatformMBeanServer(); + } + + @AfterEach + public void teardown() { + cluster.shutdown(); + } + + @Test + public void testContainerInfo() throws Exception { + ObjectName bean = new ObjectName( + "Hadoop:service=ContainerManager,name=SCMContainerManagerInfo"); + GenericTestUtils.waitFor(() -> { + try { + Map containerInfos = cluster.getStorageContainerManager() + .getContainerManager().getContainerInfos(); + final TabularData data = (TabularData) mbs.getAttribute(bean, + "ContainerInfos"); + for (Map.Entry entry : containerInfos.entrySet()) { + final Integer count = entry.getValue(); + final Integer currentCount = getMetricsCount(data, entry.getKey()); + if (currentCount == null || !currentCount.equals(count)) { + return false; + } + } + return true; + } catch (Exception e) { + throw new RuntimeException(e); + } + }, 500, 3000); + } + + private Integer getMetricsCount(TabularData data, String state) { + for (Object obj : data.values()) { + CompositeData cds = assertInstanceOf(CompositeData.class, obj); + if (cds.get("key").equals(state)) { + return Integer.parseInt(cds.get("value").toString()); + } + } + return null; + } + +} From 52c86d3e41af8059eb2cdba8f57fc12e21908487 Mon Sep 17 00:00:00 2001 From: jianghuazhu <740087514@qq.com> Date: Tue, 24 Sep 2024 01:13:25 +0800 Subject: [PATCH 2/5] Add some statistics related to Container. --- .../hdds/scm/container/ContainerManager.java | 2 +- .../scm/container/ContainerManagerImpl.java | 26 +---- .../scm/container/ContainerManagerMXBean.java | 39 -------- .../scm/pipeline/PipelineManagerImpl.java | 4 +- .../resources/webapps/scm/scm-overview.html | 36 +++++++ .../src/main/resources/webapps/scm/scm.js | 54 ++++++----- .../container/TestContainerManagerMXBean.java | 96 ------------------- 7 files changed, 73 insertions(+), 184 deletions(-) delete mode 100644 hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerMXBean.java delete mode 100644 hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerManagerMXBean.java diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManager.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManager.java index 763d7a4118db..3eba240533e3 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManager.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManager.java @@ -34,7 +34,7 @@ * ContainerManager is responsible for keeping track of all Containers and * managing all containers operations like creating, deleting etc. */ -public interface ContainerManager extends Closeable, ContainerManagerMXBean { +public interface ContainerManager extends Closeable { /** * Reinitialize the containerManager with the updated container store. diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerImpl.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerImpl.java index b1c163f96a98..00aee0f62c25 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerImpl.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerImpl.java @@ -28,7 +28,6 @@ import java.util.Optional; import java.util.Random; import java.util.Set; -import java.util.HashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -49,15 +48,11 @@ import org.apache.hadoop.hdds.scm.pipeline.Pipeline; import org.apache.hadoop.hdds.scm.pipeline.PipelineManager; import org.apache.hadoop.hdds.utils.db.Table; -import org.apache.hadoop.metrics2.util.MBeans; import org.apache.hadoop.ozone.common.statemachine.InvalidStateTransitionException; import org.apache.hadoop.util.Time; -import org.apache.ratis.protocol.exceptions.NotLeaderException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.management.ObjectName; - import static java.util.Comparator.reverseOrder; import static org.apache.hadoop.hdds.scm.ha.SequenceIdGenerator.CONTAINER_ID; import static org.apache.hadoop.hdds.utils.CollectionUtils.findTopN; @@ -91,8 +86,9 @@ public class ContainerManagerImpl implements ContainerManager { @SuppressWarnings("java:S2245") // no need for secure random private final Random random = new Random(); - private ObjectName pmInfoBean; - + /** + * + */ public ContainerManagerImpl( final Configuration conf, final SCMHAManager scmHaManager, @@ -120,8 +116,6 @@ public ContainerManagerImpl( ScmConfigKeys.OZONE_SCM_PIPELINE_OWNER_CONTAINER_COUNT_DEFAULT); this.scmContainerManagerMetrics = SCMContainerManagerMetrics.create(); - this.pmInfoBean = MBeans.register("ContainerManager", - "SCMContainerManagerInfo", this); } @Override @@ -375,16 +369,6 @@ private int getOpenContainerCountPerPipeline(Pipeline pipeline) { ((double) minContainerCountPerDn / minPipelineCountPerDn)); } - @Override - public Map getContainerInfos() throws NotLeaderException { - final Map containerInfos = new HashMap<>(); - for (LifeCycleState state : LifeCycleState.values()) { - containerInfos.put(state.toString().toLowerCase(), - containerStateManager.getContainerIDs(state).size()); - } - return containerInfos; - } - /** * Returns the container ID's matching with specified owner. * @param pipeline @@ -465,10 +449,6 @@ private void throwContainerNotFoundException(final ContainerID id) @Override public void close() throws IOException { - if (pmInfoBean != null) { - MBeans.unregister(this.pmInfoBean); - pmInfoBean = null; - } containerStateManager.close(); } diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerMXBean.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerMXBean.java deleted file mode 100644 index 7e1c465c73e4..000000000000 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerManagerMXBean.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * 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.hadoop.hdds.scm.container; - -import org.apache.hadoop.hdds.annotation.InterfaceAudience; -import org.apache.ratis.protocol.exceptions.NotLeaderException; - -import java.util.Map; - -/** - * This is the JMX management interface for information related - * to {@link ContainerManager}. - */ -@InterfaceAudience.Private -public interface ContainerManagerMXBean { - - /** - * Returns the number of containers in different state. - * @return state to number of container map. - * @throws NotLeaderException - */ - Map getContainerInfos() throws NotLeaderException; -} diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManagerImpl.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManagerImpl.java index 13164b418590..000d3e73633f 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManagerImpl.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/pipeline/PipelineManagerImpl.java @@ -779,11 +779,11 @@ public Pipeline waitOnePipelineReady(Collection pipelineIDs, public Map getPipelineInfo() throws NotLeaderException { final Map pipelineInfo = new HashMap<>(); for (Pipeline.PipelineState state : Pipeline.PipelineState.values()) { - pipelineInfo.put(state.toString().toLowerCase(), 0); + pipelineInfo.put(state.toString(), 0); } stateManager.getPipelines().forEach(pipeline -> pipelineInfo.computeIfPresent( - pipeline.getPipelineState().toString().toLowerCase(), (k, v) -> v + 1)); + pipeline.getPipelineState().toString(), (k, v) -> v + 1)); return pipelineInfo; } diff --git a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html index 9c48b410b33d..6ea86efe6ff3 100644 --- a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html +++ b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html @@ -171,6 +171,42 @@

Container Statistics

Recovering {{statistics.nodes.data.container.recovering}} + + Under Replicated + {{statistics.nodes.data.container.under_replicated}} + + + Mis Replicated + {{statistics.nodes.data.container.mis_replicated}} + + + Over Replicated + {{statistics.nodes.data.container.over_replicated}} + + + Missing + {{statistics.nodes.data.container.missing}} + + + Unhealthy + {{statistics.nodes.data.container.unhealthy}} + + + Empty + {{statistics.nodes.data.container.empty}} + + + Open Unhealthy + {{statistics.nodes.data.container.open_unhealthy}} + + + Quasi Closed Stuck + {{statistics.nodes.data.container.quasi_closed_stuck}} + + + Open Without Pipeline + {{statistics.nodes.data.container.open_without_pipeline}} + diff --git a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm.js b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm.js index 02596894bb3e..63b1d76d57d0 100644 --- a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm.js +++ b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm.js @@ -67,7 +67,16 @@ closed : "N/A", deleting : "N/A", deleted : "N/A", - recovering : "N/A" + recovering : "N/A", + under_replicated : "N/A", + mis_replicated : "N/A", + over_replicated : "N/A", + missing : "N/A", + unhealthy : "N/A", + empty : "N/A", + open_unhealthy : "N/A", + quasi_closed_stuck : "N/A", + open_without_pipeline : "N/A" } } } @@ -165,39 +174,38 @@ const URLScheme = location.protocol.replace(":" , ""); ctrl.scmpipelinemanager = result.data.beans[0]; ctrl.scmpipelinemanager.PipelineInfo.forEach(({key, value}) => { - if(key == "closed") { + if(key == "CLOSED") { $scope.statistics.nodes.data.pipeline.closed = value; - } else if(key == "allocated") { + } else if(key == "ALLOCATED") { $scope.statistics.nodes.data.pipeline.allocated = value; - } else if(key == "open") { + } else if(key == "OPEN") { $scope.statistics.nodes.data.pipeline.open = value; - } else if(key == "dormant") { + } else if(key == "DORMANT") { $scope.statistics.nodes.data.pipeline.dormant = value; } }); }); - $http.get("jmx?qry=Hadoop:service=ContainerManager,name=SCMContainerManagerInfo") + $http.get("jmx?qry=Hadoop:service=StorageContainerManager,name=ReplicationManagerMetrics") .then(function (result) { const URLScheme = location.protocol.replace(":" , ""); ctrl.scmcontainermanager = result.data.beans[0]; - ctrl.scmcontainermanager.ContainerInfos.forEach(({key, value}) => { - if(key == "open") { - $scope.statistics.nodes.data.container.open = value; - } else if(key == "closing") { - $scope.statistics.nodes.data.container.closing = value; - } else if(key == "quasi_closed") { - $scope.statistics.nodes.data.container.quasi_closed = value; - } else if(key == "closed") { - $scope.statistics.nodes.data.container.closed = value; - } else if(key == "deleting") { - $scope.statistics.nodes.data.container.deleting = value; - } else if(key == "deleted") { - $scope.statistics.nodes.data.container.deleted = value; - } else if(key == "recovering") { - $scope.statistics.nodes.data.container.recovering = value; - } - }); + $scope.statistics.nodes.data.container.open = ctrl.scmcontainermanager.OpenContainers; + $scope.statistics.nodes.data.container.closing = ctrl.scmcontainermanager.ClosingContainers; + $scope.statistics.nodes.data.container.quasi_closed = ctrl.scmcontainermanager.QuasiClosedContainers; + $scope.statistics.nodes.data.container.closed = ctrl.scmcontainermanager.ClosedContainers; + $scope.statistics.nodes.data.container.deleting = ctrl.scmcontainermanager.DeletingContainers; + $scope.statistics.nodes.data.container.deleted = ctrl.scmcontainermanager.DeletedContainers; + $scope.statistics.nodes.data.container.recovering = ctrl.scmcontainermanager.RecoveringContainers; + $scope.statistics.nodes.data.container.under_replicated = ctrl.scmcontainermanager.UnderReplicatedContainers; + $scope.statistics.nodes.data.container.mis_replicated = ctrl.scmcontainermanager.MisReplicatedContainers; + $scope.statistics.nodes.data.container.over_replicated = ctrl.scmcontainermanager.OverReplicatedContainers; + $scope.statistics.nodes.data.container.missing = ctrl.scmcontainermanager.MissingContainers; + $scope.statistics.nodes.data.container.unhealthy = ctrl.scmcontainermanager.UnhealthyContainers; + $scope.statistics.nodes.data.container.empty = ctrl.scmcontainermanager.EmptyContainers; + $scope.statistics.nodes.data.container.open_unhealthy = ctrl.scmcontainermanager.OpenUnhealthyContainers; + $scope.statistics.nodes.data.container.quasi_closed_stuck = ctrl.scmcontainermanager.StuckQuasiClosedContainers; + $scope.statistics.nodes.data.container.open_without_pipeline = ctrl.scmcontainermanager.OpenContainersWithoutPipeline; }); /*if option is 'All' display all records else display specified record on page*/ diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerManagerMXBean.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerManagerMXBean.java deleted file mode 100644 index b8eb521ab683..000000000000 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerManagerMXBean.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * 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.hadoop.hdds.scm.container; - -import org.apache.hadoop.hdds.conf.OzoneConfiguration; -import org.apache.hadoop.ozone.MiniOzoneCluster; -import org.apache.ozone.test.GenericTestUtils; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -import javax.management.MBeanServer; -import javax.management.ObjectName; -import javax.management.openmbean.CompositeData; -import javax.management.openmbean.TabularData; -import java.io.IOException; -import java.lang.management.ManagementFactory; -import java.util.Map; -import java.util.concurrent.TimeoutException; - -import static org.junit.jupiter.api.Assertions.assertInstanceOf; - -/** - * Test cases to verify the metrics exposed by {@link ContainerManager} via MXBean. - */ -@Timeout(3000) -public class TestContainerManagerMXBean { - private MiniOzoneCluster cluster; - private MBeanServer mbs; - - @BeforeEach - public void init() throws IOException, TimeoutException, - InterruptedException { - OzoneConfiguration conf = new OzoneConfiguration(); - cluster = MiniOzoneCluster.newBuilder(conf).build(); - cluster.waitForClusterToBeReady(); - mbs = ManagementFactory.getPlatformMBeanServer(); - } - - @AfterEach - public void teardown() { - cluster.shutdown(); - } - - @Test - public void testContainerInfo() throws Exception { - ObjectName bean = new ObjectName( - "Hadoop:service=ContainerManager,name=SCMContainerManagerInfo"); - GenericTestUtils.waitFor(() -> { - try { - Map containerInfos = cluster.getStorageContainerManager() - .getContainerManager().getContainerInfos(); - final TabularData data = (TabularData) mbs.getAttribute(bean, - "ContainerInfos"); - for (Map.Entry entry : containerInfos.entrySet()) { - final Integer count = entry.getValue(); - final Integer currentCount = getMetricsCount(data, entry.getKey()); - if (currentCount == null || !currentCount.equals(count)) { - return false; - } - } - return true; - } catch (Exception e) { - throw new RuntimeException(e); - } - }, 500, 3000); - } - - private Integer getMetricsCount(TabularData data, String state) { - for (Object obj : data.values()) { - CompositeData cds = assertInstanceOf(CompositeData.class, obj); - if (cds.get("key").equals(state)) { - return Integer.parseInt(cds.get("value").toString()); - } - } - return null; - } - -} From 2581d39536cb18f149f5c99d6add8314acbfa6e3 Mon Sep 17 00:00:00 2001 From: jianghuazhu <740087514@qq.com> Date: Tue, 24 Sep 2024 17:00:14 +0800 Subject: [PATCH 3/5] Optimize container table display. --- .../resources/webapps/scm/scm-overview.html | 54 ++++++----- .../src/main/resources/webapps/scm/scm.js | 92 ++++++++++--------- 2 files changed, 79 insertions(+), 67 deletions(-) diff --git a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html index 6ea86efe6ff3..73148df400cb 100644 --- a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html +++ b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html @@ -119,93 +119,103 @@

Pipeline Statistics

Closed - {{statistics.nodes.data.pipeline.closed}} + {{statistics.pipelines.closed}} Allocated - {{statistics.nodes.data.pipeline.allocated}} + {{statistics.pipelines.allocated}} Open - {{statistics.nodes.data.pipeline.open}} + {{statistics.pipelines.open}} Dormant - {{statistics.nodes.data.pipeline.dormant}} + {{statistics.pipelines.dormant}} -

Container Statistics

+

Container Lifecycle Statistics

- + - + - + - + - + - + - + - + + + +
Container StateState Size
Open{{statistics.nodes.data.container.open}}{{statistics.containers.lifecycle.open}}
Closing{{statistics.nodes.data.container.closing}}{{statistics.containers.lifecycle.closing}}
Quasi Closed{{statistics.nodes.data.container.quasi_closed}}{{statistics.containers.lifecycle.quasi_closed}}
Closed{{statistics.nodes.data.container.closed}}{{statistics.containers.lifecycle.closed}}
Deleting{{statistics.nodes.data.container.deleting}}{{statistics.containers.lifecycle.deleting}}
Deleted{{statistics.nodes.data.container.deleted}}{{statistics.containers.lifecycle.deleted}}
Recovering{{statistics.nodes.data.container.recovering}}{{statistics.containers.lifecycle.recovering}}
+ +

Container Health Statistics

+ + + + + - + - + - + - + - + - + - + - + - +
StateSize
Under Replicated{{statistics.nodes.data.container.under_replicated}}{{statistics.containers.health.under_replicated}}
Mis Replicated{{statistics.nodes.data.container.mis_replicated}}{{statistics.containers.health.mis_replicated}}
Over Replicated{{statistics.nodes.data.container.over_replicated}}{{statistics.containers.health.over_replicated}}
Missing{{statistics.nodes.data.container.missing}}{{statistics.containers.health.missing}}
Unhealthy{{statistics.nodes.data.container.unhealthy}}{{statistics.containers.health.unhealthy}}
Empty{{statistics.nodes.data.container.empty}}{{statistics.containers.health.empty}}
Open Unhealthy{{statistics.nodes.data.container.open_unhealthy}}{{statistics.containers.health.open_unhealthy}}
Quasi Closed Stuck{{statistics.nodes.data.container.quasi_closed_stuck}}{{statistics.containers.health.quasi_closed_stuck}}
Open Without Pipeline{{statistics.nodes.data.container.open_without_pipeline}}{{statistics.containers.health.open_without_pipeline}}
diff --git a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm.js b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm.js index 63b1d76d57d0..fc216c068625 100644 --- a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm.js +++ b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm.js @@ -52,32 +52,34 @@ scmused : "N/A", remaining : "N/A", nonscmused : "N/A" + } + }, + pipelines : { + closed : "N/A", + allocated : "N/A", + open : "N/A", + dormant : "N/A" + }, + containers : { + lifecycle : { + open : "N/A", + closing : "N/A", + quasi_closed : "N/A", + closed : "N/A", + deleting : "N/A", + deleted : "N/A", + recovering : "N/A" }, - data : { - pipeline : { - closed : "N/A", - allocated : "N/A", - open : "N/A", - dormant : "N/A" - }, - container : { - open : "N/A", - closing : "N/A", - quasi_closed : "N/A", - closed : "N/A", - deleting : "N/A", - deleted : "N/A", - recovering : "N/A", - under_replicated : "N/A", - mis_replicated : "N/A", - over_replicated : "N/A", - missing : "N/A", - unhealthy : "N/A", - empty : "N/A", - open_unhealthy : "N/A", - quasi_closed_stuck : "N/A", - open_without_pipeline : "N/A" - } + health : { + under_replicated : "N/A", + mis_replicated : "N/A", + over_replicated : "N/A", + missing : "N/A", + unhealthy : "N/A", + empty : "N/A", + open_unhealthy : "N/A", + quasi_closed_stuck : "N/A", + open_without_pipeline : "N/A" } } } @@ -175,13 +177,13 @@ ctrl.scmpipelinemanager = result.data.beans[0]; ctrl.scmpipelinemanager.PipelineInfo.forEach(({key, value}) => { if(key == "CLOSED") { - $scope.statistics.nodes.data.pipeline.closed = value; + $scope.statistics.pipelines.closed = value; } else if(key == "ALLOCATED") { - $scope.statistics.nodes.data.pipeline.allocated = value; + $scope.statistics.pipelines.allocated = value; } else if(key == "OPEN") { - $scope.statistics.nodes.data.pipeline.open = value; + $scope.statistics.pipelines.open = value; } else if(key == "DORMANT") { - $scope.statistics.nodes.data.pipeline.dormant = value; + $scope.statistics.pipelines.dormant = value; } }); }); @@ -190,22 +192,22 @@ .then(function (result) { const URLScheme = location.protocol.replace(":" , ""); ctrl.scmcontainermanager = result.data.beans[0]; - $scope.statistics.nodes.data.container.open = ctrl.scmcontainermanager.OpenContainers; - $scope.statistics.nodes.data.container.closing = ctrl.scmcontainermanager.ClosingContainers; - $scope.statistics.nodes.data.container.quasi_closed = ctrl.scmcontainermanager.QuasiClosedContainers; - $scope.statistics.nodes.data.container.closed = ctrl.scmcontainermanager.ClosedContainers; - $scope.statistics.nodes.data.container.deleting = ctrl.scmcontainermanager.DeletingContainers; - $scope.statistics.nodes.data.container.deleted = ctrl.scmcontainermanager.DeletedContainers; - $scope.statistics.nodes.data.container.recovering = ctrl.scmcontainermanager.RecoveringContainers; - $scope.statistics.nodes.data.container.under_replicated = ctrl.scmcontainermanager.UnderReplicatedContainers; - $scope.statistics.nodes.data.container.mis_replicated = ctrl.scmcontainermanager.MisReplicatedContainers; - $scope.statistics.nodes.data.container.over_replicated = ctrl.scmcontainermanager.OverReplicatedContainers; - $scope.statistics.nodes.data.container.missing = ctrl.scmcontainermanager.MissingContainers; - $scope.statistics.nodes.data.container.unhealthy = ctrl.scmcontainermanager.UnhealthyContainers; - $scope.statistics.nodes.data.container.empty = ctrl.scmcontainermanager.EmptyContainers; - $scope.statistics.nodes.data.container.open_unhealthy = ctrl.scmcontainermanager.OpenUnhealthyContainers; - $scope.statistics.nodes.data.container.quasi_closed_stuck = ctrl.scmcontainermanager.StuckQuasiClosedContainers; - $scope.statistics.nodes.data.container.open_without_pipeline = ctrl.scmcontainermanager.OpenContainersWithoutPipeline; + $scope.statistics.containers.lifecycle.open = ctrl.scmcontainermanager.OpenContainers; + $scope.statistics.containers.lifecycle.closing = ctrl.scmcontainermanager.ClosingContainers; + $scope.statistics.containers.lifecycle.quasi_closed = ctrl.scmcontainermanager.QuasiClosedContainers; + $scope.statistics.containers.lifecycle.closed = ctrl.scmcontainermanager.ClosedContainers; + $scope.statistics.containers.lifecycle.deleting = ctrl.scmcontainermanager.DeletingContainers; + $scope.statistics.containers.lifecycle.deleted = ctrl.scmcontainermanager.DeletedContainers; + $scope.statistics.containers.lifecycle.recovering = ctrl.scmcontainermanager.RecoveringContainers; + $scope.statistics.containers.health.under_replicated = ctrl.scmcontainermanager.UnderReplicatedContainers; + $scope.statistics.containers.health.mis_replicated = ctrl.scmcontainermanager.MisReplicatedContainers; + $scope.statistics.containers.health.over_replicated = ctrl.scmcontainermanager.OverReplicatedContainers; + $scope.statistics.containers.health.missing = ctrl.scmcontainermanager.MissingContainers; + $scope.statistics.containers.health.unhealthy = ctrl.scmcontainermanager.UnhealthyContainers; + $scope.statistics.containers.health.empty = ctrl.scmcontainermanager.EmptyContainers; + $scope.statistics.containers.health.open_unhealthy = ctrl.scmcontainermanager.OpenUnhealthyContainers; + $scope.statistics.containers.health.quasi_closed_stuck = ctrl.scmcontainermanager.StuckQuasiClosedContainers; + $scope.statistics.containers.health.open_without_pipeline = ctrl.scmcontainermanager.OpenContainersWithoutPipeline; }); /*if option is 'All' display all records else display specified record on page*/ From fdad127a24496b6b3a2d5096dc3042212ec47238 Mon Sep 17 00:00:00 2001 From: jianghuazhu <740087514@qq.com> Date: Tue, 24 Sep 2024 20:15:21 +0800 Subject: [PATCH 4/5] Improved some table displays. --- .../src/main/resources/webapps/scm/scm-overview.html | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html index 73148df400cb..ff3cba33fafc 100644 --- a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html +++ b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html @@ -136,11 +136,11 @@

Pipeline Statistics

-

Container Lifecycle Statistics

+

Container Statistics

- + @@ -171,14 +171,8 @@

Container Lifecycle Statistics

- -
StateOperational State Size
Recovering {{statistics.containers.lifecycle.recovering}}
- -

Container Health Statistics

- - - + From 9a28eb2c4369efe72e83ab5fd3a2080cc51ffd56 Mon Sep 17 00:00:00 2001 From: jianghuazhu <740087514@qq.com> Date: Tue, 24 Sep 2024 21:25:28 +0800 Subject: [PATCH 5/5] Improved some table displays. --- .../src/main/resources/webapps/scm/scm-overview.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html index ff3cba33fafc..2748716e67f0 100644 --- a/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html +++ b/hadoop-hdds/server-scm/src/main/resources/webapps/scm/scm-overview.html @@ -171,6 +171,10 @@

Container Statistics

+ +
StateHealth Size
Recovering {{statistics.containers.lifecycle.recovering}}
+ +
Health Size