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.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertTrue; 022 023import java.util.Collection; 024import org.apache.hadoop.hbase.HBaseParameterizedTestTemplate; 025import org.apache.hadoop.hbase.HConstants; 026import org.apache.hadoop.hbase.regionserver.compactions.RatioBasedCompactionPolicy; 027import org.apache.hadoop.hbase.testclassification.LargeTests; 028import org.apache.hadoop.hbase.testclassification.RegionServerTests; 029import org.junit.jupiter.api.Tag; 030import org.junit.jupiter.api.TestTemplate; 031 032@Tag(RegionServerTests.TAG) 033@Tag(LargeTests.TAG) 034@HBaseParameterizedTestTemplate(name = "{index}: compType={0}") 035public class TestTimeBasedMajorCompaction extends MajorCompactionTestBase { 036 037 public TestTimeBasedMajorCompaction(String compType) { 038 super(compType); 039 } 040 041 @TestTemplate 042 public void testTimeBasedMajorCompaction() throws Exception { 043 // create 2 storefiles and force a major compaction to reset the time 044 int delay = 10 * 1000; // 10 sec 045 float jitterPct = 0.20f; // 20% 046 conf.setLong(HConstants.MAJOR_COMPACTION_PERIOD, delay); 047 conf.setFloat("hbase.hregion.majorcompaction.jitter", jitterPct); 048 049 HStore s = ((HStore) r.getStore(COLUMN_FAMILY)); 050 s.storeEngine.getCompactionPolicy().setConf(conf); 051 try { 052 createStoreFile(r); 053 createStoreFile(r); 054 r.compact(true); 055 056 // add one more file & verify that a regular compaction won't work 057 createStoreFile(r); 058 r.compact(false); 059 assertEquals(2, s.getStorefilesCount()); 060 061 // ensure that major compaction time is deterministic 062 RatioBasedCompactionPolicy c = 063 (RatioBasedCompactionPolicy) s.storeEngine.getCompactionPolicy(); 064 Collection<HStoreFile> storeFiles = s.getStorefiles(); 065 long mcTime = c.getNextMajorCompactTime(storeFiles); 066 for (int i = 0; i < 10; ++i) { 067 assertEquals(mcTime, c.getNextMajorCompactTime(storeFiles)); 068 } 069 070 // ensure that the major compaction time is within the variance 071 long jitter = Math.round(delay * jitterPct); 072 assertTrue(delay - jitter <= mcTime && mcTime <= delay + jitter); 073 074 // wait until the time-based compaction interval 075 Thread.sleep(mcTime); 076 077 // trigger a compaction request and ensure that it's upgraded to major 078 r.compact(false); 079 assertEquals(1, s.getStorefilesCount()); 080 } finally { 081 // reset the timed compaction settings 082 conf.setLong(HConstants.MAJOR_COMPACTION_PERIOD, 1000 * 60 * 60 * 24); 083 conf.setFloat("hbase.hregion.majorcompaction.jitter", 0.20F); 084 // run a major to reset the cache 085 createStoreFile(r); 086 r.compact(true); 087 assertEquals(1, s.getStorefilesCount()); 088 } 089 } 090}