From 989494e1fc2fbf5c3e3a89b0bea7b6ea8b76af3f Mon Sep 17 00:00:00 2001 From: Viraj Jasani Date: Mon, 30 Sep 2019 15:05:22 +0530 Subject: [PATCH] HBASE-22903 : Table to RegionStatesCount metrics - Use for broken alter_status command (#611) Signed-off-by: huzheng --- .../apache/hadoop/hbase/ClusterMetrics.java | 15 +- .../hadoop/hbase/ClusterMetricsBuilder.java | 42 ++++- .../apache/hadoop/hbase/ClusterStatus.java | 7 + .../hbase/client/RegionStatesCount.java | 167 ++++++++++++++++++ .../hbase/shaded/protobuf/ProtobufUtil.java | 48 +++++ .../src/main/protobuf/ClusterStatus.proto | 15 ++ .../apache/hadoop/hbase/master/HMaster.java | 19 ++ .../master/assignment/AssignmentManager.java | 38 ++++ .../hbase/TestClientClusterMetrics.java | 44 +++++ hbase-shell/src/main/ruby/hbase/admin.rb | 15 +- hbase-shell/src/test/ruby/hbase/admin_test.rb | 7 + 11 files changed, 407 insertions(+), 10 deletions(-) create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/client/RegionStatesCount.java diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterMetrics.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterMetrics.java index 103c107ddf..e3052d8458 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterMetrics.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterMetrics.java @@ -23,6 +23,7 @@ import edu.umd.cs.findbugs.annotations.Nullable; import java.util.List; import java.util.Map; import org.apache.hadoop.hbase.client.RegionInfo; +import org.apache.hadoop.hbase.client.RegionStatesCount; import org.apache.hadoop.hbase.master.RegionState; import org.apache.yetus.audience.InterfaceAudience; @@ -150,6 +151,14 @@ public interface ClusterMetrics { return (double)getRegionCount() / (double)serverSize; } + /** + * Provide region states count for given table. + * e.g howmany regions of give table are opened/closed/rit etc + * + * @return map of table to region states count + */ + Map getTableRegionStatesCount(); + /** * Kinds of ClusterMetrics */ @@ -193,6 +202,10 @@ public interface ClusterMetrics { /** * metrics info port */ - MASTER_INFO_PORT + MASTER_INFO_PORT, + /** + * metrics about table to no of regions status count + */ + TABLE_TO_REGIONS_COUNT } } diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterMetricsBuilder.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterMetricsBuilder.java index ab6d353486..a651feb2d6 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterMetricsBuilder.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterMetricsBuilder.java @@ -26,6 +26,8 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.stream.Collectors; + +import org.apache.hadoop.hbase.client.RegionStatesCount; import org.apache.hadoop.hbase.master.RegionState; import org.apache.yetus.audience.InterfaceAudience; @@ -67,7 +69,14 @@ public final class ClusterMetricsBuilder { .setRegionState(r.convert()) .build()) .collect(Collectors.toList())) - .setMasterInfoPort(metrics.getMasterInfoPort()); + .setMasterInfoPort(metrics.getMasterInfoPort()) + .addAllTableRegionStatesCount(metrics.getTableRegionStatesCount().entrySet().stream() + .map(status -> + ClusterStatusProtos.TableRegionStatesCount.newBuilder() + .setTableName(ProtobufUtil.toProtoTableName((status.getKey()))) + .setRegionStatesCount(ProtobufUtil.toTableRegionStatesCount(status.getValue())) + .build()) + .collect(Collectors.toList())); if (metrics.getMasterName() != null) { builder.setMaster(ProtobufUtil.toServerName((metrics.getMasterName()))); } @@ -103,7 +112,12 @@ public final class ClusterMetricsBuilder { .collect(Collectors.toList())) .setMasterCoprocessorNames(proto.getMasterCoprocessorsList().stream() .map(HBaseProtos.Coprocessor::getName) - .collect(Collectors.toList())); + .collect(Collectors.toList())) + .setTableRegionStatesCount( + proto.getTableRegionStatesCountList().stream() + .collect(Collectors.toMap( + e -> ProtobufUtil.toTableName(e.getTableName()), + e -> ProtobufUtil.toTableRegionStatesCount(e.getRegionStatesCount())))); if (proto.hasClusterId()) { builder.setClusterId(ClusterId.convert(proto.getClusterId()).toString()); } @@ -143,6 +157,7 @@ public final class ClusterMetricsBuilder { case BACKUP_MASTERS: return ClusterMetrics.Option.BACKUP_MASTERS; case BALANCER_ON: return ClusterMetrics.Option.BALANCER_ON; case MASTER_INFO_PORT: return ClusterMetrics.Option.MASTER_INFO_PORT; + case TABLE_TO_REGIONS_COUNT: return ClusterMetrics.Option.TABLE_TO_REGIONS_COUNT; // should not reach here default: throw new IllegalArgumentException("Invalid option: " + option); } @@ -165,6 +180,7 @@ public final class ClusterMetricsBuilder { case BACKUP_MASTERS: return ClusterStatusProtos.Option.BACKUP_MASTERS; case BALANCER_ON: return ClusterStatusProtos.Option.BALANCER_ON; case MASTER_INFO_PORT: return ClusterStatusProtos.Option.MASTER_INFO_PORT; + case TABLE_TO_REGIONS_COUNT: return ClusterStatusProtos.Option.TABLE_TO_REGIONS_COUNT; // should not reach here default: throw new IllegalArgumentException("Invalid option: " + option); } @@ -206,6 +222,7 @@ public final class ClusterMetricsBuilder { @Nullable private Boolean balancerOn; private int masterInfoPort; + private Map tableRegionStatesCount = Collections.emptyMap(); private ClusterMetricsBuilder() { } @@ -251,6 +268,13 @@ public final class ClusterMetricsBuilder { this.masterInfoPort = value; return this; } + + public ClusterMetricsBuilder setTableRegionStatesCount( + Map tableRegionStatesCount) { + this.tableRegionStatesCount = tableRegionStatesCount; + return this; + } + public ClusterMetrics build() { return new ClusterMetricsImpl( hbaseVersion, @@ -262,7 +286,9 @@ public final class ClusterMetricsBuilder { clusterId, masterCoprocessorNames, balancerOn, - masterInfoPort); + masterInfoPort, + tableRegionStatesCount + ); } private static class ClusterMetricsImpl implements ClusterMetrics { @Nullable @@ -279,6 +305,7 @@ public final class ClusterMetricsBuilder { @Nullable private final Boolean balancerOn; private final int masterInfoPort; + private final Map tableRegionStatesCount; ClusterMetricsImpl(String hbaseVersion, List deadServerNames, Map liveServerMetrics, @@ -288,7 +315,8 @@ public final class ClusterMetricsBuilder { String clusterId, List masterCoprocessorNames, Boolean balancerOn, - int masterInfoPort) { + int masterInfoPort, + Map tableRegionStatesCount) { this.hbaseVersion = hbaseVersion; this.deadServerNames = Preconditions.checkNotNull(deadServerNames); this.liveServerMetrics = Preconditions.checkNotNull(liveServerMetrics); @@ -299,6 +327,7 @@ public final class ClusterMetricsBuilder { this.masterCoprocessorNames = Preconditions.checkNotNull(masterCoprocessorNames); this.balancerOn = balancerOn; this.masterInfoPort = masterInfoPort; + this.tableRegionStatesCount = Preconditions.checkNotNull(tableRegionStatesCount); } @Override @@ -351,6 +380,11 @@ public final class ClusterMetricsBuilder { return masterInfoPort; } + @Override + public Map getTableRegionStatesCount() { + return Collections.unmodifiableMap(tableRegionStatesCount); + } + @Override public String toString() { StringBuilder sb = new StringBuilder(1024); diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterStatus.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterStatus.java index f13de1e0e6..ae6ab89cfe 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterStatus.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterStatus.java @@ -26,6 +26,8 @@ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.stream.Collectors; + +import org.apache.hadoop.hbase.client.RegionStatesCount; import org.apache.hadoop.hbase.master.RegionState; import org.apache.yetus.audience.InterfaceAudience; @@ -344,6 +346,11 @@ public class ClusterStatus implements ClusterMetrics { return metrics.getMasterInfoPort(); } + @Override + public Map getTableRegionStatesCount() { + return metrics.getTableRegionStatesCount(); + } + @Override public String toString() { StringBuilder sb = new StringBuilder(1024); diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RegionStatesCount.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RegionStatesCount.java new file mode 100644 index 0000000000..1e1ce95113 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RegionStatesCount.java @@ -0,0 +1,167 @@ +/* + * + * 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.client; + +import org.apache.yetus.audience.InterfaceAudience; + +@InterfaceAudience.Private +public final class RegionStatesCount { + + private int openRegions; + private int splitRegions; + private int closedRegions; + private int regionsInTransition; + private int totalRegions; + + private RegionStatesCount() { + } + + public int getClosedRegions() { + return closedRegions; + } + + public int getOpenRegions() { + return openRegions; + } + + public int getSplitRegions() { + return splitRegions; + } + + public int getRegionsInTransition() { + return regionsInTransition; + } + + public int getTotalRegions() { + return totalRegions; + } + + private void setClosedRegions(int closedRegions) { + this.closedRegions = closedRegions; + } + + private void setOpenRegions(int openRegions) { + this.openRegions = openRegions; + } + + private void setSplitRegions(int splitRegions) { + this.splitRegions = splitRegions; + } + + private void setRegionsInTransition(int regionsInTransition) { + this.regionsInTransition = regionsInTransition; + } + + private void setTotalRegions(int totalRegions) { + this.totalRegions = totalRegions; + } + + public static class RegionStatesCountBuilder { + private int openRegions; + private int splitRegions; + private int closedRegions; + private int regionsInTransition; + private int totalRegions; + + public RegionStatesCountBuilder setOpenRegions(int openRegions) { + this.openRegions = openRegions; + return this; + } + + public RegionStatesCountBuilder setSplitRegions(int splitRegions) { + this.splitRegions = splitRegions; + return this; + } + + public RegionStatesCountBuilder setClosedRegions(int closedRegions) { + this.closedRegions = closedRegions; + return this; + } + + public RegionStatesCountBuilder setRegionsInTransition(int regionsInTransition) { + this.regionsInTransition = regionsInTransition; + return this; + } + + public RegionStatesCountBuilder setTotalRegions(int totalRegions) { + this.totalRegions = totalRegions; + return this; + } + + public RegionStatesCount build() { + RegionStatesCount regionStatesCount=new RegionStatesCount(); + regionStatesCount.setOpenRegions(openRegions); + regionStatesCount.setClosedRegions(closedRegions); + regionStatesCount.setRegionsInTransition(regionsInTransition); + regionStatesCount.setSplitRegions(splitRegions); + regionStatesCount.setTotalRegions(totalRegions); + return regionStatesCount; + } + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("RegionStatesCount{"); + sb.append("openRegions=").append(openRegions); + sb.append(", splitRegions=").append(splitRegions); + sb.append(", closedRegions=").append(closedRegions); + sb.append(", regionsInTransition=").append(regionsInTransition); + sb.append(", totalRegions=").append(totalRegions); + sb.append('}'); + return sb.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + RegionStatesCount that = (RegionStatesCount) o; + + if (openRegions != that.openRegions) { + return false; + } + if (splitRegions != that.splitRegions) { + return false; + } + if (closedRegions != that.closedRegions) { + return false; + } + if (regionsInTransition != that.regionsInTransition) { + return false; + } + return totalRegions == that.totalRegions; + } + + @Override + public int hashCode() { + int result = openRegions; + result = 31 * result + splitRegions; + result = 31 * result + closedRegions; + result = 31 * result + regionsInTransition; + result = 31 * result + totalRegions; + return result; + } + +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java index 7179272abd..3821fc1036 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java @@ -78,6 +78,7 @@ import org.apache.hadoop.hbase.client.PackagePrivateFieldAccessor; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.client.RegionInfoBuilder; import org.apache.hadoop.hbase.client.RegionLoadStats; +import org.apache.hadoop.hbase.client.RegionStatesCount; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.client.SnapshotDescription; @@ -3229,4 +3230,51 @@ public final class ProtobufUtil { .setTo(timeRange.getMax()) .build(); } + + public static ClusterStatusProtos.RegionStatesCount toTableRegionStatesCount( + RegionStatesCount regionStatesCount) { + int openRegions = 0; + int splitRegions = 0; + int closedRegions = 0; + int regionsInTransition = 0; + int totalRegions = 0; + if (regionStatesCount != null) { + openRegions = regionStatesCount.getOpenRegions(); + splitRegions = regionStatesCount.getSplitRegions(); + closedRegions = regionStatesCount.getClosedRegions(); + regionsInTransition = regionStatesCount.getRegionsInTransition(); + totalRegions = regionStatesCount.getTotalRegions(); + } + return ClusterStatusProtos.RegionStatesCount.newBuilder() + .setOpenRegions(openRegions) + .setSplitRegions(splitRegions) + .setClosedRegions(closedRegions) + .setRegionsInTransition(regionsInTransition) + .setTotalRegions(totalRegions) + .build(); + } + + public static RegionStatesCount toTableRegionStatesCount( + ClusterStatusProtos.RegionStatesCount regionStatesCount) { + int openRegions = 0; + int splitRegions = 0; + int closedRegions = 0; + int regionsInTransition = 0; + int totalRegions = 0; + if (regionStatesCount != null) { + closedRegions = regionStatesCount.getClosedRegions(); + regionsInTransition = regionStatesCount.getRegionsInTransition(); + openRegions = regionStatesCount.getOpenRegions(); + splitRegions = regionStatesCount.getSplitRegions(); + totalRegions = regionStatesCount.getTotalRegions(); + } + return new RegionStatesCount.RegionStatesCountBuilder() + .setOpenRegions(openRegions) + .setSplitRegions(splitRegions) + .setClosedRegions(closedRegions) + .setRegionsInTransition(regionsInTransition) + .setTotalRegions(totalRegions) + .build(); + } + } diff --git a/hbase-protocol-shaded/src/main/protobuf/ClusterStatus.proto b/hbase-protocol-shaded/src/main/protobuf/ClusterStatus.proto index 9fd5f04413..b1c7f87f07 100644 --- a/hbase-protocol-shaded/src/main/protobuf/ClusterStatus.proto +++ b/hbase-protocol-shaded/src/main/protobuf/ClusterStatus.proto @@ -214,6 +214,19 @@ message LiveServerInfo { required ServerLoad server_load = 2; } +message RegionStatesCount { + required uint32 open_regions = 1; + required uint32 split_regions = 2; + required uint32 closed_regions = 3; + required uint32 regions_in_transition = 4; + required uint32 total_regions = 5; +} + +message TableRegionStatesCount { + required TableName table_name = 1; + required RegionStatesCount region_states_count = 2; +} + message ClusterStatus { optional HBaseVersionFileContent hbase_version = 1; repeated LiveServerInfo live_servers = 2; @@ -225,6 +238,7 @@ message ClusterStatus { repeated ServerName backup_masters = 8; optional bool balancer_on = 9; optional int32 master_info_port = 10 [default = -1]; + repeated TableRegionStatesCount table_region_states_count = 11; } enum Option { @@ -238,4 +252,5 @@ enum Option { REGIONS_IN_TRANSITION = 7; BALANCER_ON = 8; MASTER_INFO_PORT = 9; + TABLE_TO_REGIONS_COUNT = 10; } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java index c0e362d11f..19824a8712 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java @@ -85,6 +85,7 @@ import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; import org.apache.hadoop.hbase.client.MasterSwitchType; import org.apache.hadoop.hbase.client.RegionInfo; import org.apache.hadoop.hbase.client.RegionInfoBuilder; +import org.apache.hadoop.hbase.client.RegionStatesCount; import org.apache.hadoop.hbase.client.TableDescriptor; import org.apache.hadoop.hbase.client.TableDescriptorBuilder; import org.apache.hadoop.hbase.client.TableState; @@ -2703,6 +2704,24 @@ public class HMaster extends HRegionServer implements MasterServices { } break; } + case TABLE_TO_REGIONS_COUNT: { + if (isActiveMaster() && isInitialized() && assignmentManager != null) { + try { + Map tableRegionStatesCountMap = new HashMap<>(); + Map tableDescriptorMap = getTableDescriptors().getAll(); + for (TableDescriptor tableDescriptor : tableDescriptorMap.values()) { + TableName tableName = tableDescriptor.getTableName(); + RegionStatesCount regionStatesCount = assignmentManager + .getRegionStatesCount(tableName); + tableRegionStatesCountMap.put(tableName, regionStatesCount); + } + builder.setTableRegionStatesCount(tableRegionStatesCountMap); + } catch (IOException e) { + LOG.error("Error while populating TABLE_TO_REGIONS_COUNT for Cluster Metrics..", e); + } + } + break; + } } } return builder.build(); 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 99fd04d5d3..184204443d 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 @@ -43,6 +43,7 @@ import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.YouAreDeadException; import org.apache.hadoop.hbase.client.RegionInfo; import org.apache.hadoop.hbase.client.RegionInfoBuilder; +import org.apache.hadoop.hbase.client.RegionStatesCount; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.TableState; import org.apache.hadoop.hbase.exceptions.UnexpectedStateException; @@ -1911,4 +1912,41 @@ public class AssignmentManager implements ServerListener { } return rsReportsSnapshot; } + + /** + * Provide regions state count for given table. + * e.g howmany regions of give table are opened/closed/rit etc + * + * @param tableName TableName + * @return region states count + */ + public RegionStatesCount getRegionStatesCount(TableName tableName) { + int openRegionsCount = 0; + int closedRegionCount = 0; + int ritCount = 0; + int splitRegionCount = 0; + int totalRegionCount = 0; + if (!isTableDisabled(tableName)) { + final List states = regionStates.getTableRegionStates(tableName); + for (RegionState regionState : states) { + if (regionState.isOpened()) { + openRegionsCount++; + } else if (regionState.isClosed()) { + closedRegionCount++; + } else if (regionState.isSplit()) { + splitRegionCount++; + } + } + totalRegionCount = states.size(); + ritCount = totalRegionCount - openRegionsCount - splitRegionCount; + } + return new RegionStatesCount.RegionStatesCountBuilder() + .setOpenRegions(openRegionsCount) + .setClosedRegions(closedRegionCount) + .setSplitRegions(splitRegionCount) + .setRegionsInTransition(ritCount) + .setTotalRegions(totalRegionCount) + .build(); + } + } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/TestClientClusterMetrics.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestClientClusterMetrics.java index a2605f272a..753bdf7929 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/TestClientClusterMetrics.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestClientClusterMetrics.java @@ -30,6 +30,9 @@ import org.apache.hadoop.hbase.client.Admin; import org.apache.hadoop.hbase.client.AsyncAdmin; import org.apache.hadoop.hbase.client.AsyncConnection; import org.apache.hadoop.hbase.client.ConnectionFactory; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.client.RegionStatesCount; +import org.apache.hadoop.hbase.client.Table; import org.apache.hadoop.hbase.coprocessor.CoprocessorHost; import org.apache.hadoop.hbase.coprocessor.MasterCoprocessor; import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment; @@ -38,6 +41,7 @@ import org.apache.hadoop.hbase.coprocessor.ObserverContext; import org.apache.hadoop.hbase.master.HMaster; import org.apache.hadoop.hbase.regionserver.HRegionServer; import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.JVMClusterUtil.MasterThread; import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread; import org.junit.AfterClass; @@ -60,6 +64,9 @@ public class TestClientClusterMetrics { private final static int MASTERS = 3; private static MiniHBaseCluster CLUSTER; private static HRegionServer DEAD; + private static final TableName TABLE_NAME = TableName.valueOf("test"); + private static final byte[] CF = Bytes.toBytes("cf"); + @BeforeClass public static void setUpBeforeClass() throws Exception { @@ -119,6 +126,11 @@ public class TestClientClusterMetrics { Assert.assertEquals(origin.getLiveServerMetrics().size(), defaults.getLiveServerMetrics().size()); Assert.assertEquals(origin.getMasterInfoPort(), defaults.getMasterInfoPort()); + origin.getTableRegionStatesCount().forEach(((tableName, regionStatesCount) -> { + RegionStatesCount defaultRegionStatesCount = defaults.getTableRegionStatesCount() + .get(tableName); + Assert.assertEquals(defaultRegionStatesCount, regionStatesCount); + })); } } @@ -160,6 +172,38 @@ public class TestClientClusterMetrics { Assert.assertEquals(DEAD.getServerName(), deadServerName); } + @Test + public void testRegionStatesCount() throws Exception { + Table table = UTIL.createTable(TABLE_NAME, CF); + table.put(new Put(Bytes.toBytes("k1")) + .addColumn(CF, Bytes.toBytes("q1"), Bytes.toBytes("v1"))); + table.put(new Put(Bytes.toBytes("k2")) + .addColumn(CF, Bytes.toBytes("q2"), Bytes.toBytes("v2"))); + table.put(new Put(Bytes.toBytes("k3")) + .addColumn(CF, Bytes.toBytes("q3"), Bytes.toBytes("v3"))); + + ClusterMetrics metrics = ADMIN.getClusterMetrics(); + Assert.assertEquals(metrics.getTableRegionStatesCount().size(), 3); + Assert.assertEquals(metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME) + .getRegionsInTransition(), 0); + Assert.assertEquals(metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME) + .getOpenRegions(), 1); + Assert.assertEquals(metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME) + .getTotalRegions(), 1); + Assert.assertEquals(metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME) + .getClosedRegions(), 0); + Assert.assertEquals(metrics.getTableRegionStatesCount().get(TableName.META_TABLE_NAME) + .getSplitRegions(), 0); + Assert.assertEquals(metrics.getTableRegionStatesCount().get(TABLE_NAME) + .getRegionsInTransition(), 0); + Assert.assertEquals(metrics.getTableRegionStatesCount().get(TABLE_NAME) + .getOpenRegions(), 1); + Assert.assertEquals(metrics.getTableRegionStatesCount().get(TABLE_NAME) + .getTotalRegions(), 1); + + UTIL.deleteTable(TABLE_NAME); + } + @Test public void testMasterAndBackupMastersStatus() throws Exception { // get all the master threads diff --git a/hbase-shell/src/main/ruby/hbase/admin.rb b/hbase-shell/src/main/ruby/hbase/admin.rb index 386e1cba6a..140c72419e 100644 --- a/hbase-shell/src/main/ruby/hbase/admin.rb +++ b/hbase-shell/src/main/ruby/hbase/admin.rb @@ -592,16 +592,21 @@ module Hbase # Table should exist raise(ArgumentError, "Can't find a table: #{table_name}") unless exists?(table_name) - status = Pair.new begin - status = @admin.getAlterStatus(org.apache.hadoop.hbase.TableName.valueOf(table_name)) - if status.getSecond != 0 - puts "#{status.getSecond - status.getFirst}/#{status.getSecond} regions updated." + cluster_metrics = @admin.getClusterMetrics + table_region_status = cluster_metrics + .getTableRegionStatesCount + .get(org.apache.hadoop.hbase.TableName.valueOf(table_name)) + if table_region_status.getTotalRegions != 0 + updated_regions = table_region_status.getTotalRegions - + table_region_status.getRegionsInTransition - + table_region_status.getClosedRegions + puts "#{updated_regions}/#{table_region_status.getTotalRegions} regions updated." else puts 'All regions updated.' end sleep 1 - end while !status.nil? && status.getFirst != 0 + end while !table_region_status.nil? && table_region_status.getRegionsInTransition != 0 puts 'Done.' end diff --git a/hbase-shell/src/test/ruby/hbase/admin_test.rb b/hbase-shell/src/test/ruby/hbase/admin_test.rb index a55bb28eb3..c2a350a9b9 100644 --- a/hbase-shell/src/test/ruby/hbase/admin_test.rb +++ b/hbase-shell/src/test/ruby/hbase/admin_test.rb @@ -113,6 +113,13 @@ module Hbase #------------------------------------------------------------------------------- + define_test 'alter_status should work' do + output = capture_stdout { command(:alter_status, @test_name) } + assert(output.include?('1/1 regions updated')) + end + + #------------------------------------------------------------------------------- + define_test "compact should work" do command(:compact, 'hbase:meta') end -- 2.17.2 (Apple Git-113)