001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.master; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.fail; 022 023import java.io.IOException; 024import java.util.AbstractMap.SimpleImmutableEntry; 025import java.util.List; 026import org.apache.hadoop.hbase.HBaseTestingUtil; 027import org.apache.hadoop.hbase.TableName; 028import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 029import org.apache.hadoop.hbase.client.RegionInfo; 030import org.apache.hadoop.hbase.client.TableDescriptor; 031import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 032import org.apache.hadoop.hbase.master.assignment.RegionStates; 033import org.apache.hadoop.hbase.quotas.SpaceQuotaSnapshot; 034import org.apache.hadoop.hbase.quotas.SpaceQuotaSnapshot.SpaceQuotaStatus; 035import org.apache.hadoop.hbase.quotas.SpaceViolationPolicy; 036import org.apache.hadoop.hbase.testclassification.MasterTests; 037import org.apache.hadoop.hbase.testclassification.MediumTests; 038import org.apache.hadoop.hbase.util.Bytes; 039import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 040import org.apache.hadoop.hbase.util.PairOfSameType; 041import org.apache.hadoop.hbase.util.Threads; 042import org.junit.jupiter.api.AfterAll; 043import org.junit.jupiter.api.BeforeAll; 044import org.junit.jupiter.api.Tag; 045import org.junit.jupiter.api.Test; 046import org.slf4j.Logger; 047import org.slf4j.LoggerFactory; 048 049@Tag(MasterTests.TAG) 050@Tag(MediumTests.TAG) 051public class TestMasterMetricsWrapper { 052 053 private static final Logger LOG = LoggerFactory.getLogger(TestMasterMetricsWrapper.class); 054 055 private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 056 private static final int NUM_RS = 4; 057 058 @BeforeAll 059 public static void setup() throws Exception { 060 TEST_UTIL.startMiniCluster(NUM_RS); 061 } 062 063 @AfterAll 064 public static void teardown() throws Exception { 065 TEST_UTIL.shutdownMiniCluster(); 066 } 067 068 @Test 069 public void testInfo() throws IOException { 070 HMaster master = TEST_UTIL.getHBaseCluster().getMaster(); 071 MetricsMasterWrapperImpl info = new MetricsMasterWrapperImpl(master); 072 assertEquals(master.getRegionNormalizerManager().getSplitPlanCount(), info.getSplitPlanCount(), 073 0); 074 assertEquals(master.getRegionNormalizerManager().getMergePlanCount(), info.getMergePlanCount(), 075 0); 076 assertEquals(master.getAverageLoad(), info.getAverageLoad(), 0); 077 assertEquals(master.getClusterId(), info.getClusterId()); 078 assertEquals(master.getMasterActiveTime(), info.getActiveTime()); 079 assertEquals(master.getMasterStartTime(), info.getStartTime()); 080 assertEquals(master.getMasterCoprocessors().length, info.getCoprocessors().length); 081 assertEquals(master.getServerManager().getOnlineServersList().size(), 082 info.getNumRegionServers()); 083 assertEquals(master.getMasterWalManager().getOldWALsDirSize(), info.getOldWALsDirSize()); 084 int regionServerCount = NUM_RS; 085 assertEquals(regionServerCount, info.getNumRegionServers()); 086 087 String zkServers = info.getZookeeperQuorum(); 088 assertEquals(zkServers.split(",").length, TEST_UTIL.getZkCluster().getZooKeeperServerNum()); 089 090 final int index = 3; 091 LOG.info("Stopping " + TEST_UTIL.getMiniHBaseCluster().getRegionServer(index)); 092 TEST_UTIL.getMiniHBaseCluster().stopRegionServer(index, false); 093 TEST_UTIL.getMiniHBaseCluster().waitOnRegionServer(index); 094 // We stopped the regionserver but could take a while for the master to notice it so hang here 095 // until it does... then move forward to see if metrics wrapper notices. 096 while ( 097 TEST_UTIL.getHBaseCluster().getMaster().getServerManager().getOnlineServers().size() 098 == regionServerCount 099 ) { 100 Threads.sleep(10); 101 } 102 assertEquals(regionServerCount - 1, info.getNumRegionServers()); 103 assertEquals(1, info.getNumDeadRegionServers()); 104 // now we do not expose this information as WALProcedureStore is not the only ProcedureStore 105 // implementation any more. 106 assertEquals(0, info.getNumWALFiles()); 107 // We decommission the first online region server and verify the metrics. 108 TEST_UTIL.getMiniHBaseCluster().getMaster().decommissionRegionServers( 109 master.getServerManager().getOnlineServersList().subList(0, 1), false); 110 assertEquals(1, info.getNumDrainingRegionServers()); 111 assertEquals(master.getServerManager().getOnlineServersList().get(0).toString(), 112 info.getDrainingRegionServers()); 113 } 114 115 @Test 116 public void testQuotaSnapshotConversion() { 117 MetricsMasterWrapperImpl info = 118 new MetricsMasterWrapperImpl(TEST_UTIL.getHBaseCluster().getMaster()); 119 assertEquals(new SimpleImmutableEntry<Long, Long>(1024L, 2048L), info 120 .convertSnapshot(new SpaceQuotaSnapshot(SpaceQuotaStatus.notInViolation(), 1024L, 2048L))); 121 assertEquals(new SimpleImmutableEntry<Long, Long>(4096L, 2048L), info.convertSnapshot( 122 new SpaceQuotaSnapshot(new SpaceQuotaStatus(SpaceViolationPolicy.NO_INSERTS), 4096L, 2048L))); 123 } 124 125 /** 126 * tests online and offline region number 127 */ 128 @Test 129 public void testOfflineRegion() throws Exception { 130 HMaster master = TEST_UTIL.getHBaseCluster().getMaster(); 131 MetricsMasterWrapperImpl info = new MetricsMasterWrapperImpl(master); 132 TableName table = TableName.valueOf("testRegionNumber"); 133 try { 134 RegionInfo hri; 135 byte[] FAMILY = Bytes.toBytes("FAMILY"); 136 TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(table) 137 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY)).build(); 138 TEST_UTIL.getAdmin().createTable(tableDescriptor, Bytes.toBytes("A"), Bytes.toBytes("Z"), 5); 139 140 // wait till the table is assigned 141 long timeoutTime = EnvironmentEdgeManager.currentTime() + 1000; 142 while (true) { 143 List<RegionInfo> regions = 144 master.getAssignmentManager().getRegionStates().getRegionsOfTable(table); 145 if (regions.size() > 3) { 146 hri = regions.get(2); 147 break; 148 } 149 long now = EnvironmentEdgeManager.currentTime(); 150 if (now > timeoutTime) { 151 fail("Could not find an online region"); 152 } 153 Thread.sleep(10); 154 } 155 156 PairOfSameType<Integer> regionNumberPair = info.getRegionCounts(); 157 assertEquals(5, regionNumberPair.getFirst().intValue()); 158 assertEquals(0, regionNumberPair.getSecond().intValue()); 159 160 TEST_UTIL.getAdmin().offline(hri.getRegionName()); 161 162 timeoutTime = EnvironmentEdgeManager.currentTime() + 800; 163 RegionStates regionStates = master.getAssignmentManager().getRegionStates(); 164 while (true) { 165 if ( 166 regionStates.getRegionByStateOfTable(table).get(RegionState.State.OFFLINE).contains(hri) 167 ) { 168 break; 169 } 170 long now = EnvironmentEdgeManager.currentTime(); 171 if (now > timeoutTime) { 172 fail("Failed to offline the region in time"); 173 break; 174 } 175 Thread.sleep(10); 176 } 177 regionNumberPair = info.getRegionCounts(); 178 assertEquals(4, regionNumberPair.getFirst().intValue()); 179 assertEquals(1, regionNumberPair.getSecond().intValue()); 180 } finally { 181 TEST_UTIL.deleteTable(table); 182 } 183 } 184}