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}