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