diff --git a/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsAssignmentManagerSource.java b/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsAssignmentManagerSource.java index ec4a34e3bd..cd30311768 100644 --- a/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsAssignmentManagerSource.java +++ b/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsAssignmentManagerSource.java @@ -66,6 +66,43 @@ public interface MetricsAssignmentManagerSource extends BaseSource { String OPERATION_COUNT_NAME = "operationCount"; + // Regions State metrics + String REGIONS_OFFLINE="regionsOffline"; + String REGIONS_OFFLINE_DESC="Regions in state OFFLINE"; + + String REGIONS_OPENING="regionsOpening"; + String REGIONS_OPENING_DESC="Regions in state OPENING"; + + String REGIONS_OPEN="regionsOpen"; + String REGIONS_OPEN_DESC="Regions in state OPEN"; + + String REGIONS_CLOSING="regionsClosing"; + String REGIONS_CLOSING_DESC="Regions in state CLOSING"; + + String REGIONS_CLOSED="regionsClosed"; + String REGIONS_CLOSED_DESC="Regions in state CLOSED"; + + String REGIONS_SPLITTING="regionsSplitting"; + String REGIONS_SPLITTING_DESC="Regions in state SPLITTING"; + + String REGIONS_SPLIT="regionsSplit"; + String REGIONS_SPLIT_DESC="Regions in state SPLIT"; + + String REGIONS_FAILED_OPEN="regionsFailedOpen"; + String REGIONS_FAILED_OPEN_DESC="Regions in state failed open"; + + String REGIONS_FAILED_CLOSE="regionsFailedClose"; + String REGIONS_FAILED_CLOSE_DESC="Regions in state failed close"; + + String REGIONS_MERGING="regionsMerging"; + String REGIONS_MERGING_DESC="Regions in state merging"; + + String REGIONS_MERGED="regionsMerged"; + String REGIONS_MERGED_DESC="Regions in state merged"; + + String REGIONS_SPLITTING_NEW="regionsSplittingNew"; + String REGIONS_SPLITTING_NEW_DESC="Regions in state splittingNew"; + /** * Set the number of regions in transition. * diff --git a/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsAssignmentWrapper.java b/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsAssignmentWrapper.java new file mode 100644 index 0000000000..57551376cd --- /dev/null +++ b/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsAssignmentWrapper.java @@ -0,0 +1,114 @@ +/** + * 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.hbase.master; + +import org.apache.yetus.audience.InterfaceAudience; + +@InterfaceAudience.Private +public interface MetricsAssignmentWrapper { + + /** + * Snapshot regions state map + */ + void snapshot(); + + /** + * Get the count of regions in the offline state + * + * @return concatenated encoded region names of offline regions + */ + String getOfflineRegions(); + + /** + * Get the count of regions in the opening state + * + * @return concatenated encoded region names of opening regions + */ + String getOpeningRegions(); + + /** + * Get the count of regions in the open state + * + * @return concatenated encoded region names of open regions + */ + String getOpenRegions(); + + /** + * Get the count of regions in the closing state + * + * @return concatenated encoded region names of closing regions + */ + String getClosingRegions(); + + /** + * Get the count of regions in the closed state + * + * @return concatenated encoded region names of closed regions + */ + String getClosedRegions(); + + /** + * Get the count of regions in the splitting state + * + * @return concatenated encoded region names of splitting regions + */ + String getSplittingRegions(); + + /** + * Get the count of regions in the split state + * + * @return concatenated encoded region names of split regions + */ + String getSplitRegions(); + + /** + * Get the count of regions in the failed open state + * + * @return concatenated encoded region names of failed open regions + */ + String getFailedOpenRegions(); + + /** + * Get the count of regions in the failed close state + * + * @return concatenated encoded region names of failed close regions + */ + String getFailedCloseRegions(); + + /** + * Get the count of regions in the merging state + * + * @return concatenated encoded region names of merging regions + */ + String getMergingRegions(); + + /** + * Get the count of regions in the merged state + * + * @return concatenated encoded region names of merged regions + */ + String getMergedRegions(); + + /** + * Get the count of regions in the splittingNew state + * + * @return concatenated encoded region names of splittingNew regions + */ + String getSplittingNewRegions(); +} diff --git a/hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsAssignmentManagerSourceImpl.java b/hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsAssignmentManagerSourceImpl.java index 52c03bf472..db92be140a 100644 --- a/hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsAssignmentManagerSourceImpl.java +++ b/hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsAssignmentManagerSourceImpl.java @@ -6,9 +6,9 @@ * 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 - * + *

+ * 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. @@ -18,6 +18,9 @@ package org.apache.hadoop.hbase.master; +import org.apache.hadoop.hbase.metrics.Interns; +import org.apache.hadoop.metrics2.MetricsCollector; +import org.apache.hadoop.metrics2.MetricsRecordBuilder; import org.apache.yetus.audience.InterfaceAudience; import org.apache.hadoop.hbase.metrics.BaseSourceImpl; import org.apache.hadoop.hbase.metrics.OperationMetrics; @@ -27,8 +30,8 @@ import org.apache.hadoop.metrics2.lib.MutableGaugeLong; @InterfaceAudience.Private public class MetricsAssignmentManagerSourceImpl - extends BaseSourceImpl - implements MetricsAssignmentManagerSource { + extends BaseSourceImpl + implements MetricsAssignmentManagerSource { private MutableGaugeLong ritGauge; private MutableGaugeLong ritCountOverThresholdGauge; @@ -42,8 +45,11 @@ public class MetricsAssignmentManagerSourceImpl private OperationMetrics splitMetrics; private OperationMetrics mergeMetrics; - public MetricsAssignmentManagerSourceImpl() { + private MetricsAssignmentWrapper metricsAssignmentWrapper; + + public MetricsAssignmentManagerSourceImpl(MetricsAssignmentWrapper metricsAssignmentWrapper) { this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT, METRICS_JMX_CONTEXT); + this.metricsAssignmentWrapper = metricsAssignmentWrapper; } public MetricsAssignmentManagerSourceImpl(String metricsName, @@ -55,7 +61,7 @@ public class MetricsAssignmentManagerSourceImpl public void init() { ritGauge = metricsRegistry.newGauge(RIT_COUNT_NAME, RIT_COUNT_DESC, 0l); ritCountOverThresholdGauge = metricsRegistry.newGauge(RIT_COUNT_OVER_THRESHOLD_NAME, - RIT_COUNT_OVER_THRESHOLD_DESC,0l); + RIT_COUNT_OVER_THRESHOLD_DESC, 0l); ritOldestAgeGauge = metricsRegistry.newGauge(RIT_OLDEST_AGE_NAME, RIT_OLDEST_AGE_DESC, 0l); ritDurationHisto = metricsRegistry.newTimeHistogram(RIT_DURATION_NAME, RIT_DURATION_DESC); operationCounter = metricsRegistry.getCounter(OPERATION_COUNT_NAME, 0l); @@ -71,6 +77,40 @@ public class MetricsAssignmentManagerSourceImpl mergeMetrics = new OperationMetrics(registry, MERGE_METRIC_PREFIX); } + @Override + public void getMetrics(MetricsCollector metricsCollector, boolean all) { + MetricsRecordBuilder metricsRecordBuilder = metricsCollector.addRecord(metricsName); + if (metricsRecordBuilder != null&&metricsAssignmentWrapper!=null) { + + metricsAssignmentWrapper.snapshot(); + metricsRecordBuilder.tag(Interns.info(REGIONS_OFFLINE, REGIONS_OFFLINE_DESC), + metricsAssignmentWrapper.getOfflineRegions()); + metricsRecordBuilder.tag(Interns.info(REGIONS_OPENING, REGIONS_OPENING_DESC), + metricsAssignmentWrapper.getOpeningRegions()); + metricsRecordBuilder.tag(Interns.info(REGIONS_OPEN, REGIONS_OPEN_DESC), + metricsAssignmentWrapper.getOpenRegions()); + metricsRecordBuilder.tag(Interns.info(REGIONS_CLOSING, REGIONS_CLOSING_DESC), + metricsAssignmentWrapper.getClosingRegions()); + metricsRecordBuilder.tag(Interns.info(REGIONS_CLOSED, REGIONS_CLOSED_DESC), + metricsAssignmentWrapper.getClosedRegions()); + metricsRecordBuilder.tag(Interns.info(REGIONS_SPLITTING, REGIONS_SPLITTING_DESC), + metricsAssignmentWrapper.getSplitRegions()); + metricsRecordBuilder.tag(Interns.info(REGIONS_SPLIT, REGIONS_SPLIT_DESC), + metricsAssignmentWrapper.getSplitRegions()); + metricsRecordBuilder.tag(Interns.info(REGIONS_FAILED_OPEN, REGIONS_FAILED_OPEN_DESC), + metricsAssignmentWrapper.getFailedOpenRegions()); + metricsRecordBuilder.tag(Interns.info(REGIONS_FAILED_CLOSE, REGIONS_FAILED_CLOSE_DESC), + metricsAssignmentWrapper.getFailedCloseRegions()); + metricsRecordBuilder.tag(Interns.info(REGIONS_MERGING, REGIONS_MERGING_DESC), + metricsAssignmentWrapper.getMergingRegions()); + metricsRecordBuilder.tag(Interns.info(REGIONS_MERGED, REGIONS_MERGED_DESC), + metricsAssignmentWrapper.getMergedRegions()); + metricsRecordBuilder.tag(Interns.info(REGIONS_SPLITTING_NEW, REGIONS_SPLITTING_NEW_DESC), + metricsAssignmentWrapper.getSplittingNewRegions()); + } + metricsRegistry.snapshot(metricsRecordBuilder, all); + } + @Override public void setRIT(final int ritCount) { ritGauge.set(ritCount); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MetricsAssignmentManager.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MetricsAssignmentManager.java index d13ffe9b83..3a6e75e84c 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MetricsAssignmentManager.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MetricsAssignmentManager.java @@ -33,10 +33,8 @@ public class MetricsAssignmentManager { private final ProcedureMetrics splitProcMetrics; private final ProcedureMetrics mergeProcMetrics; - public MetricsAssignmentManager() { - assignmentManagerSource = CompatibilitySingletonFactory.getInstance( - MetricsAssignmentManagerSource.class); - + public MetricsAssignmentManager(MetricsAssignmentWrapper metricsAssignmentWrapper) { + assignmentManagerSource=new MetricsAssignmentManagerSourceImpl(metricsAssignmentWrapper); assignProcMetrics = convertToProcedureMetrics(assignmentManagerSource.getAssignMetrics()); unassignProcMetrics = convertToProcedureMetrics(assignmentManagerSource.getUnassignMetrics()); splitProcMetrics = convertToProcedureMetrics(assignmentManagerSource.getSplitMetrics()); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java index 1d95041a04..febe0103af 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java @@ -144,6 +144,10 @@ public class AssignmentManager implements ServerListener { "hbase.metrics.rit.stuck.warning.threshold"; private static final int DEFAULT_RIT_STUCK_WARNING_THRESHOLD = 60 * 1000; + /* control the number of region names in each region state */ + public static final String METRIC_MAX_NUM_REGIONS_IN_EACH_STATE="hbase.assignment.metric.maximum.regions.in.each.state"; + private static final int DEFAULT_METRIC_MAX_NUM_REGIONS_IN_EACH_STATE = 100; + private final ProcedureEvent metaInitializedEvent = new ProcedureEvent<>("meta initialized"); private final ProcedureEvent metaLoadEvent = new ProcedureEvent<>("meta load"); @@ -176,6 +180,7 @@ public class AssignmentManager implements ServerListener { private final int assignDispatchWaitQueueMaxSize; private final int assignDispatchWaitMillis; private final int assignMaxAttempts; + private final int maxRegionsInEachState; private final Object checkIfShouldMoveSystemRegionLock = new Object(); @@ -188,7 +193,7 @@ public class AssignmentManager implements ServerListener { public AssignmentManager(final MasterServices master, final RegionStateStore stateStore) { this.master = master; this.regionStateStore = stateStore; - this.metrics = new MetricsAssignmentManager(); + this.metrics = new MetricsAssignmentManager(new MetricsAssignmentWrapperImpl(this)); final Configuration conf = master.getConfiguration(); @@ -208,6 +213,7 @@ public class AssignmentManager implements ServerListener { DEFAULT_RIT_CHORE_INTERVAL_MSEC); this.ritChore = new RegionInTransitionChore(ritChoreInterval); + this.maxRegionsInEachState=conf.getInt(METRIC_MAX_NUM_REGIONS_IN_EACH_STATE,DEFAULT_METRIC_MAX_NUM_REGIONS_IN_EACH_STATE); // Used for region related procedure. setRegionNormalizer(master.getRegionNormalizer()); } @@ -289,6 +295,10 @@ public class AssignmentManager implements ServerListener { return assignMaxAttempts; } + protected int getMaxNumRegionsInEachState(){ + return maxRegionsInEachState; + } + /** * Add the listener to the notification list. * @param listener The AssignmentListener to register diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/MetricsAssignmentWrapperImpl.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/MetricsAssignmentWrapperImpl.java new file mode 100644 index 0000000000..ee3adc5381 --- /dev/null +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/MetricsAssignmentWrapperImpl.java @@ -0,0 +1,148 @@ +/** + * 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.hbase.master.assignment; + +import org.apache.commons.lang.StringUtils; +import org.apache.hadoop.hbase.master.MetricsAssignmentWrapper; +import org.apache.hadoop.hbase.master.RegionState; +import org.apache.yetus.audience.InterfaceAudience; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +@InterfaceAudience.Private +public class MetricsAssignmentWrapperImpl implements MetricsAssignmentWrapper { + + private AssignmentManager am; + + private Map> regionsStateMap; + + public MetricsAssignmentWrapperImpl(AssignmentManager am) { + this.am = am; + } + + public synchronized void snapshot() { + RegionStates rstates = this.am.getRegionStates(); + if (rstates == null) { + return; + } + List list = rstates.getRegionsInTransition(); + if (list == null || list.isEmpty()) { + return; + } + regionsStateMap = new HashMap>(); + List allRegions = new LinkedList(); + List userRegions = new LinkedList(); + for (RegionStates.RegionStateNode rsn : list) { + if (rsn.getTable().isSystemTable()) { + allRegions.add(rsn); + } else { + userRegions.add(rsn); + } + } + allRegions.addAll(userRegions); + for (RegionStates.RegionStateNode rsn : allRegions) { + List regionsState = regionsStateMap.get(rsn.getState()); + if (regionsState == null) { + regionsState = new LinkedList(); + } + if (regionsState.size() > am.getMaxNumRegionsInEachState()) { + continue; + } + regionsStateMap.put(rsn.getState(), regionsState); + regionsState.add(String.format("%s_%s_%s", + rsn.getTable().getNamespaceAsString(), + rsn.getTable().getNameAsString(), + rsn.getRegionInfo() == null ? "" : rsn.getRegionInfo().getEncodedName())); + } + } + + private String getRegionsStringByState(RegionState.State state) { + if (this.regionsStateMap == null) { + return ""; + } + List regionsState = regionsStateMap.get(state); + if (regionsState == null) { + return ""; + } + return StringUtils.join(regionsState, ", "); + } + + @Override + public String getOfflineRegions() { + return this.getRegionsStringByState(RegionState.State.OFFLINE); + } + + @Override + public String getOpeningRegions() { + return this.getRegionsStringByState(RegionState.State.OPENING); + } + + @Override + public String getOpenRegions() { + return this.getRegionsStringByState(RegionState.State.OPEN); + } + + @Override + public String getClosingRegions() { + return this.getRegionsStringByState(RegionState.State.CLOSING); + } + + @Override + public String getClosedRegions() { + return this.getRegionsStringByState(RegionState.State.CLOSED); + } + + @Override + public String getSplittingRegions() { + return this.getRegionsStringByState(RegionState.State.SPLITTING); + } + + @Override + public String getSplitRegions() { + return this.getRegionsStringByState(RegionState.State.SPLIT); + } + + @Override + public String getFailedOpenRegions() { + return this.getRegionsStringByState(RegionState.State.FAILED_OPEN); + } + + @Override + public String getFailedCloseRegions() { + return this.getRegionsStringByState(RegionState.State.FAILED_CLOSE); + } + + @Override + public String getMergingRegions() { + return this.getRegionsStringByState(RegionState.State.MERGING); + } + + @Override + public String getMergedRegions() { + return this.getRegionsStringByState(RegionState.State.MERGED); + } + + @Override + public String getSplittingNewRegions() { + return this.getRegionsStringByState(RegionState.State.SPLITTING_NEW); + } +}