001/** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package org.apache.hadoop.hbase.regionserver; 020 021import org.apache.yetus.audience.InterfaceAudience; 022import org.slf4j.Logger; 023import org.slf4j.LoggerFactory; 024import org.apache.hadoop.conf.Configuration; 025import org.apache.hadoop.hbase.regionserver.compactions.CompactionConfiguration; 026 027/** 028 * Configuration class for stripe store and compactions. 029 * See {@link StripeStoreFileManager} for general documentation. 030 * See getters for the description of each setting. 031 */ 032@InterfaceAudience.Private 033public class StripeStoreConfig { 034 private static final Logger LOG = LoggerFactory.getLogger(StripeStoreConfig.class); 035 036 /** The maximum number of files to compact within a stripe; same as for regular compaction. */ 037 public static final String MAX_FILES_KEY = "hbase.store.stripe.compaction.maxFiles"; 038 /** The minimum number of files to compact within a stripe; same as for regular compaction. */ 039 public static final String MIN_FILES_KEY = "hbase.store.stripe.compaction.minFiles"; 040 041 /** The minimum number of files to compact when compacting L0; same as minFiles for regular 042 * compaction. Given that L0 causes unnecessary overwriting of the data, should be higher than 043 * regular minFiles. */ 044 public static final String MIN_FILES_L0_KEY = "hbase.store.stripe.compaction.minFilesL0"; 045 046 /** The size the stripe should achieve to be considered for splitting into multiple stripes. 047 Stripe will be split when it can be fully compacted, and it is above this size. */ 048 public static final String SIZE_TO_SPLIT_KEY = "hbase.store.stripe.sizeToSplit"; 049 /** The target count of new stripes to produce when splitting a stripe. A floating point 050 number, default is 2. Values less than 1 will be converted to 1/x. Non-whole numbers will 051 produce unbalanced splits, which may be good for some cases. In this case the "smaller" of 052 the new stripes will always be the rightmost one. If the stripe is bigger than sizeToSplit 053 when splitting, this will be adjusted by a whole increment. */ 054 public static final String SPLIT_PARTS_KEY = "hbase.store.stripe.splitPartCount"; 055 /** The initial stripe count to create. If the row distribution is roughly the same over time, 056 it's good to set this to a count of stripes that is expected to be achieved in most regions, 057 to get this count from the outset and prevent unnecessary splitting. */ 058 public static final String INITIAL_STRIPE_COUNT_KEY = "hbase.store.stripe.initialStripeCount"; 059 060 /** Whether to flush memstore to L0 files, or directly to stripes. */ 061 public static final String FLUSH_TO_L0_KEY = "hbase.store.stripe.compaction.flushToL0"; 062 063 /** When splitting region, the maximum size imbalance to allow in an attempt to split at a 064 stripe boundary, so that no files go to both regions. Most users won't need to change that. */ 065 public static final String MAX_REGION_SPLIT_IMBALANCE_KEY = 066 "hbase.store.stripe.region.split.max.imbalance"; 067 068 069 private final float maxRegionSplitImbalance; 070 private final int level0CompactMinFiles; 071 private final int stripeCompactMinFiles; 072 private final int stripeCompactMaxFiles; 073 074 private final int initialCount; 075 private final long sizeToSplitAt; 076 private final float splitPartCount; 077 private final boolean flushIntoL0; 078 private final long splitPartSize; // derived from sizeToSplitAt and splitPartCount 079 080 private static final double EPSILON = 0.001; // good enough for this, not a real epsilon. 081 public StripeStoreConfig(Configuration config, StoreConfigInformation sci) { 082 this.level0CompactMinFiles = config.getInt(MIN_FILES_L0_KEY, 4); 083 this.flushIntoL0 = config.getBoolean(FLUSH_TO_L0_KEY, false); 084 int minMinFiles = flushIntoL0 ? 3 : 4; // make sure not to compact tiny files too often. 085 int minFiles = config.getInt(CompactionConfiguration.HBASE_HSTORE_COMPACTION_MIN_KEY, -1); 086 this.stripeCompactMinFiles = config.getInt(MIN_FILES_KEY, Math.max(minMinFiles, minFiles)); 087 this.stripeCompactMaxFiles = config.getInt(MAX_FILES_KEY, 088 config.getInt(CompactionConfiguration.HBASE_HSTORE_COMPACTION_MAX_KEY, 10)); 089 this.maxRegionSplitImbalance = getFloat(config, MAX_REGION_SPLIT_IMBALANCE_KEY, 1.5f, true); 090 091 float splitPartCount = getFloat(config, SPLIT_PARTS_KEY, 2f, true); 092 if (Math.abs(splitPartCount - 1.0) < EPSILON) { 093 LOG.error("Split part count cannot be 1 (" + splitPartCount + "), using the default"); 094 splitPartCount = 2f; 095 } 096 this.splitPartCount = splitPartCount; 097 // Arbitrary default split size - 4 times the size of one L0 compaction. 098 // If we flush into L0 there's no split compaction, but for default value it is ok. 099 double flushSize = sci.getMemStoreFlushSize(); 100 if (flushSize == 0) { 101 flushSize = 128 * 1024 * 1024; 102 } 103 long defaultSplitSize = (long)(flushSize * getLevel0MinFiles() * 4 * splitPartCount); 104 this.sizeToSplitAt = config.getLong(SIZE_TO_SPLIT_KEY, defaultSplitSize); 105 int initialCount = config.getInt(INITIAL_STRIPE_COUNT_KEY, 1); 106 if (initialCount == 0) { 107 LOG.error("Initial stripe count is 0, using the default"); 108 initialCount = 1; 109 } 110 this.initialCount = initialCount; 111 this.splitPartSize = (long)(this.sizeToSplitAt / this.splitPartCount); 112 } 113 114 private static float getFloat( 115 Configuration config, String key, float defaultValue, boolean moreThanOne) { 116 float value = config.getFloat(key, defaultValue); 117 if (value < EPSILON) { 118 LOG.warn(String.format( 119 "%s is set to 0 or negative; using default value of %f", key, defaultValue)); 120 value = defaultValue; 121 } else if ((value > 1f) != moreThanOne) { 122 value = 1f / value; 123 } 124 return value; 125 } 126 127 public float getMaxSplitImbalance() { 128 return this.maxRegionSplitImbalance; 129 } 130 131 public int getLevel0MinFiles() { 132 return level0CompactMinFiles; 133 } 134 135 public int getStripeCompactMinFiles() { 136 return stripeCompactMinFiles; 137 } 138 139 public int getStripeCompactMaxFiles() { 140 return stripeCompactMaxFiles; 141 } 142 143 public boolean isUsingL0Flush() { 144 return flushIntoL0; 145 } 146 147 public long getSplitSize() { 148 return sizeToSplitAt; 149 } 150 151 public int getInitialCount() { 152 return initialCount; 153 } 154 155 public float getSplitCount() { 156 return splitPartCount; 157 } 158 159 /** 160 * @return the desired size of the target stripe when splitting, in bytes. 161 * Derived from {@link #getSplitSize()} and {@link #getSplitCount()}. 162 */ 163 public long getSplitPartSize() { 164 return splitPartSize; 165 } 166}