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.regionserver; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertNotNull; 023import static org.junit.Assert.assertNull; 024 025import java.io.IOException; 026import org.apache.hadoop.conf.Configuration; 027import org.apache.hadoop.hbase.HBaseClassTestRule; 028import org.apache.hadoop.hbase.HBaseTestingUtility; 029import org.apache.hadoop.hbase.HConstants; 030import org.apache.hadoop.hbase.HRegionInfo; 031import org.apache.hadoop.hbase.JMXListener; 032import org.apache.hadoop.hbase.TableName; 033import org.apache.hadoop.hbase.client.RegionLocator; 034import org.apache.hadoop.hbase.client.Table; 035import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 036import org.apache.hadoop.hbase.coprocessor.CoprocessorHost; 037import org.apache.hadoop.hbase.master.HMaster; 038import org.apache.hadoop.hbase.regionserver.compactions.CompactionConfiguration; 039import org.apache.hadoop.hbase.testclassification.MediumTests; 040import org.apache.hadoop.hbase.util.Bytes; 041import org.junit.AfterClass; 042import org.junit.BeforeClass; 043import org.junit.ClassRule; 044import org.junit.Test; 045import org.junit.experimental.categories.Category; 046import org.slf4j.Logger; 047import org.slf4j.LoggerFactory; 048 049/** 050 * Verify that the Online config Changes on the HRegionServer side are actually happening. We should 051 * add tests for important configurations which will be changed online. 052 */ 053 054@Category({ MediumTests.class }) 055public class TestRegionServerOnlineConfigChange { 056 057 @ClassRule 058 public static final HBaseClassTestRule CLASS_RULE = 059 HBaseClassTestRule.forClass(TestRegionServerOnlineConfigChange.class); 060 061 private static final Logger LOG = 062 LoggerFactory.getLogger(TestRegionServerOnlineConfigChange.class.getName()); 063 private static HBaseTestingUtility hbaseTestingUtility = new HBaseTestingUtility(); 064 private static Configuration conf = null; 065 066 private static Table t1 = null; 067 private static HRegionServer rs1 = null; 068 private static HMaster hMaster = null; 069 private static byte[] r1name = null; 070 private static Region r1 = null; 071 072 private final static String table1Str = "table1"; 073 private final static String columnFamily1Str = "columnFamily1"; 074 private final static TableName TABLE1 = TableName.valueOf(table1Str); 075 private final static byte[] COLUMN_FAMILY1 = Bytes.toBytes(columnFamily1Str); 076 private final static long MAX_FILE_SIZE = 20 * 1024 * 1024L; 077 078 @BeforeClass 079 public static void setUp() throws Exception { 080 conf = hbaseTestingUtility.getConfiguration(); 081 hbaseTestingUtility.startMiniCluster(); 082 t1 = hbaseTestingUtility.createTable( 083 TableDescriptorBuilder.newBuilder(TABLE1).setMaxFileSize(MAX_FILE_SIZE).build(), 084 new byte[][] { COLUMN_FAMILY1 }, conf); 085 try (RegionLocator locator = hbaseTestingUtility.getConnection().getRegionLocator(TABLE1)) { 086 HRegionInfo firstHRI = locator.getAllRegionLocations().get(0).getRegionInfo(); 087 r1name = firstHRI.getRegionName(); 088 rs1 = hbaseTestingUtility.getHBaseCluster() 089 .getRegionServer(hbaseTestingUtility.getHBaseCluster().getServerWith(r1name)); 090 r1 = rs1.getRegion(r1name); 091 hMaster = hbaseTestingUtility.getHBaseCluster().getMaster(); 092 } 093 } 094 095 @AfterClass 096 public static void tearDown() throws Exception { 097 hbaseTestingUtility.shutdownMiniCluster(); 098 } 099 100 /** 101 * Check if the number of compaction threads changes online 102 */ 103 @Test 104 public void testNumCompactionThreadsOnlineChange() { 105 assertNotNull(rs1.getCompactSplitThread()); 106 int newNumSmallThreads = rs1.getCompactSplitThread().getSmallCompactionThreadNum() + 1; 107 int newNumLargeThreads = rs1.getCompactSplitThread().getLargeCompactionThreadNum() + 1; 108 109 conf.setInt("hbase.regionserver.thread.compaction.small", newNumSmallThreads); 110 conf.setInt("hbase.regionserver.thread.compaction.large", newNumLargeThreads); 111 rs1.getConfigurationManager().notifyAllObservers(conf); 112 113 assertEquals(newNumSmallThreads, rs1.getCompactSplitThread().getSmallCompactionThreadNum()); 114 assertEquals(newNumLargeThreads, rs1.getCompactSplitThread().getLargeCompactionThreadNum()); 115 } 116 117 /** 118 * Test that the configurations in the CompactionConfiguration class change properly. 119 */ 120 @Test 121 public void testCompactionConfigurationOnlineChange() throws IOException { 122 String strPrefix = "hbase.hstore.compaction."; 123 Store s = r1.getStore(COLUMN_FAMILY1); 124 if (!(s instanceof HStore)) { 125 LOG.error("Can't test the compaction configuration of HStore class. " 126 + "Got a different implementation other than HStore"); 127 return; 128 } 129 HStore hstore = (HStore) s; 130 131 // Set the new compaction ratio to a different value. 132 double newCompactionRatio = 133 hstore.getStoreEngine().getCompactionPolicy().getConf().getCompactionRatio() + 0.1; 134 conf.setFloat(strPrefix + "ratio", (float) newCompactionRatio); 135 136 // Notify all the observers, which includes the Store object. 137 rs1.getConfigurationManager().notifyAllObservers(conf); 138 139 // Check if the compaction ratio got updated in the Compaction Configuration 140 assertEquals(newCompactionRatio, 141 hstore.getStoreEngine().getCompactionPolicy().getConf().getCompactionRatio(), 0.00001); 142 143 // Check if the off peak compaction ratio gets updated. 144 double newOffPeakCompactionRatio = 145 hstore.getStoreEngine().getCompactionPolicy().getConf().getCompactionRatioOffPeak() + 0.1; 146 conf.setFloat(strPrefix + "ratio.offpeak", (float) newOffPeakCompactionRatio); 147 rs1.getConfigurationManager().notifyAllObservers(conf); 148 assertEquals(newOffPeakCompactionRatio, 149 hstore.getStoreEngine().getCompactionPolicy().getConf().getCompactionRatioOffPeak(), 0.00001); 150 151 // Check if the throttle point gets updated. 152 long newThrottlePoint = 153 hstore.getStoreEngine().getCompactionPolicy().getConf().getThrottlePoint() + 10; 154 conf.setLong("hbase.regionserver.thread.compaction.throttle", newThrottlePoint); 155 rs1.getConfigurationManager().notifyAllObservers(conf); 156 assertEquals(newThrottlePoint, 157 hstore.getStoreEngine().getCompactionPolicy().getConf().getThrottlePoint()); 158 159 // Check if the minFilesToCompact gets updated. 160 int newMinFilesToCompact = 161 hstore.getStoreEngine().getCompactionPolicy().getConf().getMinFilesToCompact() + 1; 162 conf.setLong(strPrefix + "min", newMinFilesToCompact); 163 rs1.getConfigurationManager().notifyAllObservers(conf); 164 assertEquals(newMinFilesToCompact, 165 hstore.getStoreEngine().getCompactionPolicy().getConf().getMinFilesToCompact()); 166 167 // Check if the maxFilesToCompact gets updated. 168 int newMaxFilesToCompact = 169 hstore.getStoreEngine().getCompactionPolicy().getConf().getMaxFilesToCompact() + 1; 170 conf.setLong(strPrefix + "max", newMaxFilesToCompact); 171 rs1.getConfigurationManager().notifyAllObservers(conf); 172 assertEquals(newMaxFilesToCompact, 173 hstore.getStoreEngine().getCompactionPolicy().getConf().getMaxFilesToCompact()); 174 175 // Check OffPeak hours is updated in an online fashion. 176 conf.setLong(CompactionConfiguration.HBASE_HSTORE_OFFPEAK_START_HOUR, 6); 177 conf.setLong(CompactionConfiguration.HBASE_HSTORE_OFFPEAK_END_HOUR, 7); 178 rs1.getConfigurationManager().notifyAllObservers(conf); 179 assertFalse(hstore.getOffPeakHours().isOffPeakHour(4)); 180 181 // Check if the minCompactSize gets updated. 182 long newMinCompactSize = 183 hstore.getStoreEngine().getCompactionPolicy().getConf().getMinCompactSize() + 1; 184 conf.setLong(strPrefix + "min.size", newMinCompactSize); 185 rs1.getConfigurationManager().notifyAllObservers(conf); 186 assertEquals(newMinCompactSize, 187 hstore.getStoreEngine().getCompactionPolicy().getConf().getMinCompactSize()); 188 189 // Check if the maxCompactSize gets updated. 190 long newMaxCompactSize = 191 hstore.getStoreEngine().getCompactionPolicy().getConf().getMaxCompactSize() - 1; 192 conf.setLong(strPrefix + "max.size", newMaxCompactSize); 193 rs1.getConfigurationManager().notifyAllObservers(conf); 194 assertEquals(newMaxCompactSize, 195 hstore.getStoreEngine().getCompactionPolicy().getConf().getMaxCompactSize()); 196 // Check if the offPeakMaxCompactSize gets updated. 197 long newOffpeakMaxCompactSize = 198 hstore.getStoreEngine().getCompactionPolicy().getConf().getOffPeakMaxCompactSize() - 1; 199 conf.setLong(CompactionConfiguration.HBASE_HSTORE_COMPACTION_MAX_SIZE_OFFPEAK_KEY, 200 newOffpeakMaxCompactSize); 201 rs1.getConfigurationManager().notifyAllObservers(conf); 202 assertEquals(newOffpeakMaxCompactSize, 203 hstore.getStoreEngine().getCompactionPolicy().getConf().getOffPeakMaxCompactSize()); 204 205 // Check if majorCompactionPeriod gets updated. 206 long newMajorCompactionPeriod = 207 hstore.getStoreEngine().getCompactionPolicy().getConf().getMajorCompactionPeriod() + 10; 208 conf.setLong(HConstants.MAJOR_COMPACTION_PERIOD, newMajorCompactionPeriod); 209 rs1.getConfigurationManager().notifyAllObservers(conf); 210 assertEquals(newMajorCompactionPeriod, 211 hstore.getStoreEngine().getCompactionPolicy().getConf().getMajorCompactionPeriod()); 212 213 // Check if majorCompactionJitter gets updated. 214 float newMajorCompactionJitter = 215 hstore.getStoreEngine().getCompactionPolicy().getConf().getMajorCompactionJitter() + 0.02F; 216 conf.setFloat("hbase.hregion.majorcompaction.jitter", newMajorCompactionJitter); 217 rs1.getConfigurationManager().notifyAllObservers(conf); 218 assertEquals(newMajorCompactionJitter, 219 hstore.getStoreEngine().getCompactionPolicy().getConf().getMajorCompactionJitter(), 0.00001); 220 } 221 222 @Test 223 public void testStoreConfigurationOnlineChange() { 224 rs1.getConfigurationManager().notifyAllObservers(conf); 225 long actualMaxFileSize = r1.getStore(COLUMN_FAMILY1).getReadOnlyConfiguration() 226 .getLong(TableDescriptorBuilder.MAX_FILESIZE, -1); 227 assertEquals(MAX_FILE_SIZE, actualMaxFileSize); 228 } 229 230 @Test 231 public void testCoprocessorConfigurationOnlineChange() { 232 assertNull(rs1.getRegionServerCoprocessorHost().findCoprocessor(JMXListener.class.getName())); 233 conf.set(CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY, JMXListener.class.getName()); 234 rs1.getConfigurationManager().notifyAllObservers(conf); 235 assertNotNull( 236 rs1.getRegionServerCoprocessorHost().findCoprocessor(JMXListener.class.getName())); 237 } 238 239 @Test 240 public void testCoprocessorConfigurationOnlineChangeOnMaster() { 241 assertNull(hMaster.getMasterCoprocessorHost().findCoprocessor(JMXListener.class.getName())); 242 conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, JMXListener.class.getName()); 243 assertFalse(hMaster.isInMaintenanceMode()); 244 hMaster.getConfigurationManager().notifyAllObservers(conf); 245 assertNotNull(hMaster.getMasterCoprocessorHost().findCoprocessor(JMXListener.class.getName())); 246 } 247 248}