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 java.io.IOException; 021import java.util.HashMap; 022import java.util.Map; 023import org.apache.hadoop.hbase.HConstants; 024import org.apache.hadoop.hbase.regionserver.compactions.CompactionConfiguration; 025import org.apache.hadoop.hbase.regionserver.compactions.ExponentialCompactionWindowFactory; 026import org.apache.hadoop.hbase.testclassification.RegionServerTests; 027import org.apache.hadoop.hbase.testclassification.SmallTests; 028import org.junit.jupiter.api.Tag; 029import org.junit.jupiter.api.Test; 030 031@Tag(RegionServerTests.TAG) 032@Tag(SmallTests.TAG) 033public class TestDateTieredCompactionPolicyHeterogeneousStorage 034 extends AbstractTestDateTieredCompactionPolicy { 035 public static final String HOT_WINDOW_SP = "ALL_SSD"; 036 public static final String WARM_WINDOW_SP = "ONE_SSD"; 037 public static final String COLD_WINDOW_SP = "HOT"; 038 039 @Override 040 protected void config() { 041 super.config(); 042 043 // Set up policy 044 conf.set(StoreEngine.STORE_ENGINE_CLASS_KEY, 045 "org.apache.hadoop.hbase.regionserver.DateTieredStoreEngine"); 046 conf.setLong(CompactionConfiguration.DATE_TIERED_MAX_AGE_MILLIS_KEY, 100); 047 conf.setLong(CompactionConfiguration.DATE_TIERED_INCOMING_WINDOW_MIN_KEY, 3); 048 conf.setLong(ExponentialCompactionWindowFactory.BASE_WINDOW_MILLIS_KEY, 6); 049 conf.setInt(ExponentialCompactionWindowFactory.WINDOWS_PER_TIER_KEY, 4); 050 conf.setBoolean(CompactionConfiguration.DATE_TIERED_SINGLE_OUTPUT_FOR_MINOR_COMPACTION_KEY, 051 false); 052 053 // Special settings for compaction policy per window 054 this.conf.setInt(CompactionConfiguration.HBASE_HSTORE_COMPACTION_MIN_KEY, 2); 055 this.conf.setInt(CompactionConfiguration.HBASE_HSTORE_COMPACTION_MAX_KEY, 12); 056 this.conf.setFloat(CompactionConfiguration.HBASE_HSTORE_COMPACTION_RATIO_KEY, 1.2F); 057 058 conf.setInt(HStore.BLOCKING_STOREFILES_KEY, 20); 059 conf.setLong(HConstants.MAJOR_COMPACTION_PERIOD, 5); 060 061 // Set Storage Policy for different type window 062 conf.setBoolean(CompactionConfiguration.DATE_TIERED_STORAGE_POLICY_ENABLE_KEY, true); 063 conf.setLong(CompactionConfiguration.DATE_TIERED_HOT_WINDOW_AGE_MILLIS_KEY, 6); 064 conf.set(CompactionConfiguration.DATE_TIERED_HOT_WINDOW_STORAGE_POLICY_KEY, HOT_WINDOW_SP); 065 conf.setLong(CompactionConfiguration.DATE_TIERED_WARM_WINDOW_AGE_MILLIS_KEY, 12); 066 conf.set(CompactionConfiguration.DATE_TIERED_WARM_WINDOW_STORAGE_POLICY_KEY, WARM_WINDOW_SP); 067 conf.set(CompactionConfiguration.DATE_TIERED_COLD_WINDOW_STORAGE_POLICY_KEY, COLD_WINDOW_SP); 068 } 069 070 /** 071 * Test for minor compaction of incoming window. Incoming window start ts >= now - hot age. So it 072 * is HOT window, will use HOT_WINDOW_SP. 073 * @throws IOException with error 074 */ 075 @Test 076 public void testIncomingWindowHot() throws IOException { 077 long[] minTimestamps = new long[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 078 long[] maxTimestamps = new long[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; 079 long[] sizes = new long[] { 30, 31, 32, 33, 34, 20, 21, 22, 23, 24, 25, 10, 11, 12, 13 }; 080 Map<Long, String> expected = new HashMap<>(); 081 // expected DateTieredCompactionRequest boundaries = { Long.MIN_VALUE, 12 } 082 // test whether DateTieredCompactionRequest boundariesPolicies matches expected 083 expected.put(12L, HOT_WINDOW_SP); 084 compactEqualsStoragePolicy(16, sfCreate(minTimestamps, maxTimestamps, sizes), expected, false, 085 true); 086 } 087 088 /** 089 * Test for not incoming window. now - hot age > window start >= now - warm age, so this window 090 * and is WARM window, will use WARM_WINDOW_SP 091 * @throws IOException with error 092 */ 093 @Test 094 public void testNotIncomingWindowWarm() throws IOException { 095 long[] minTimestamps = new long[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 096 long[] maxTimestamps = new long[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; 097 long[] sizes = new long[] { 30, 31, 32, 33, 34, 20, 21, 22, 23, 24, 25, 10, 11 }; 098 Map<Long, String> expected = new HashMap<>(); 099 // expected DateTieredCompactionRequest boundaries = { Long.MIN_VALUE, 6 } 100 expected.put(6L, WARM_WINDOW_SP); 101 compactEqualsStoragePolicy(16, sfCreate(minTimestamps, maxTimestamps, sizes), expected, false, 102 true); 103 } 104 105 /** 106 * Test for not incoming window. this window start ts >= ow - hot age, So this incoming window and 107 * is HOT window. Use HOT_WINDOW_SP 108 * @throws IOException with error 109 */ 110 @Test 111 public void testNotIncomingWindowAndIsHot() throws IOException { 112 long[] minTimestamps = new long[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 113 long[] maxTimestamps = new long[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; 114 long[] sizes = new long[] { 30, 31, 32, 33, 34, 20, 21, 22, 23, 24, 25, 10, 11 }; 115 Map<Long, String> expected = new HashMap<>(); 116 // expected DateTieredCompactionRequest boundaries = { Long.MIN_VALUE, 6 } 117 expected.put(6L, HOT_WINDOW_SP); 118 compactEqualsStoragePolicy(12, sfCreate(minTimestamps, maxTimestamps, sizes), expected, false, 119 true); 120 } 121 122 /** 123 * Test for not incoming window. COLD window start timestamp < now - warm age, so use 124 * COLD_WINDOW_SP 125 * @throws IOException with error 126 */ 127 @Test 128 public void testColdWindow() throws IOException { 129 long[] minTimestamps = new long[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 130 long[] maxTimestamps = new long[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; 131 long[] sizes = new long[] { 30, 31, 32, 33, 34, 20, 21, 22, 23, 24, 25, 10 }; 132 Map<Long, String> expected = new HashMap<>(); 133 // expected DateTieredCompactionRequest boundaries = { Long.MIN_VALUE, 6 } 134 expected.put(6L, COLD_WINDOW_SP); 135 compactEqualsStoragePolicy(22, sfCreate(minTimestamps, maxTimestamps, sizes), expected, false, 136 true); 137 } 138 139 /** 140 * Test for not incoming window. but not all hfiles will be selected to compact. Apply exploring 141 * logic on non-incoming window. More than one hfile left in this window. this means minor compact 142 * single out is true. boundaries only contains Long.MIN_VALUE 143 * @throws IOException with error 144 */ 145 @Test 146 public void testRatioT0() throws IOException { 147 long[] minTimestamps = new long[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 148 long[] maxTimestamps = new long[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; 149 long[] sizes = new long[] { 30, 31, 32, 33, 34, 20, 21, 22, 280, 23, 24, 1 }; 150 Map<Long, String> expected = new HashMap<>(); 151 // window start = 6, expected DateTieredCompactionRequest boundaries = { Long.MIN_VALUE } 152 expected.put(Long.MIN_VALUE, WARM_WINDOW_SP); 153 compactEqualsStoragePolicy(16, sfCreate(minTimestamps, maxTimestamps, sizes), expected, false, 154 true); 155 } 156 157 /** 158 * Test for Major compaction. It will compact all files and create multi output files with 159 * different window storage policy. 160 * @throws IOException with error 161 */ 162 @Test 163 public void testMajorCompation() throws IOException { 164 long[] minTimestamps = new long[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 165 long[] maxTimestamps = new long[] { 44, 60, 61, 96, 100, 104, 105, 106, 113, 145, 157 }; 166 long[] sizes = new long[] { 0, 50, 51, 40, 41, 42, 33, 30, 31, 2, 1 }; 167 Map<Long, String> expected = new HashMap<>(); 168 expected.put(Long.MIN_VALUE, COLD_WINDOW_SP); 169 expected.put(24L, COLD_WINDOW_SP); 170 expected.put(48L, COLD_WINDOW_SP); 171 expected.put(72L, COLD_WINDOW_SP); 172 expected.put(96L, COLD_WINDOW_SP); 173 expected.put(120L, COLD_WINDOW_SP); 174 expected.put(144L, COLD_WINDOW_SP); 175 expected.put(150L, WARM_WINDOW_SP); 176 expected.put(156L, HOT_WINDOW_SP); 177 compactEquals(161, sfCreate(minTimestamps, maxTimestamps, sizes), 178 new long[] { 0, 50, 51, 40, 41, 42, 33, 30, 31, 2, 1 }, 179 new long[] { Long.MIN_VALUE, 24, 48, 72, 96, 120, 144, 150, 156 }, true, true); 180 compactEqualsStoragePolicy(161, sfCreate(minTimestamps, maxTimestamps, sizes), expected, true, 181 true); 182 } 183}