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 org.apache.hadoop.hbase.HBaseInterfaceAudience; 021import org.apache.hadoop.hbase.procedure2.util.StringUtils; 022import org.apache.yetus.audience.InterfaceAudience; 023import org.slf4j.Logger; 024import org.slf4j.LoggerFactory; 025 026/** 027 * A {@link FlushPolicy} that only flushes store larger a given threshold. If no store is large 028 * enough, then all stores will be flushed. 029 */ 030@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG) 031public abstract class FlushLargeStoresPolicy extends FlushPolicy { 032 033 private static final Logger LOG = LoggerFactory.getLogger(FlushLargeStoresPolicy.class); 034 035 public static final String HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND = 036 "hbase.hregion.percolumnfamilyflush.size.lower.bound"; 037 038 public static final String HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND_MIN = 039 "hbase.hregion.percolumnfamilyflush.size.lower.bound.min"; 040 041 public static final long DEFAULT_HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND_MIN = 042 1024 * 1024 * 16L; 043 044 protected long flushSizeLowerBound = -1; 045 046 @Override 047 public String toString() { 048 return "FlushLargeStoresPolicy{" + "flushSizeLowerBound=" + flushSizeLowerBound + '}'; 049 } 050 051 protected void setFlushSizeLowerBounds(HRegion region) { 052 int familyNumber = region.getTableDescriptor().getColumnFamilyCount(); 053 // For multiple families, lower bound is the "average flush size" by default 054 // unless setting in configuration is larger. 055 flushSizeLowerBound = region.getMemStoreFlushSize() / familyNumber; 056 long minimumLowerBound = getConf().getLong(HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND_MIN, 057 DEFAULT_HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND_MIN); 058 if (minimumLowerBound > flushSizeLowerBound) { 059 flushSizeLowerBound = minimumLowerBound; 060 } 061 // use the setting in table description if any 062 String flushedSizeLowerBoundString = 063 region.getTableDescriptor().getValue(HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND); 064 if (flushedSizeLowerBoundString == null) { 065 LOG.debug( 066 "No {} set in table {} descriptor;" 067 + "using region.getMemStoreFlushHeapSize/# of families ({}) " + "instead.", 068 HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND, region.getTableDescriptor().getTableName(), 069 StringUtils.humanSize(flushSizeLowerBound) + ")"); 070 } else { 071 try { 072 flushSizeLowerBound = Long.parseLong(flushedSizeLowerBoundString); 073 } catch (NumberFormatException nfe) { 074 // fall back for fault setting 075 LOG.warn( 076 "Number format exception parsing {} for table {}: {}, {}; " 077 + "using region.getMemStoreFlushHeapSize/# of families ({}) " 078 + "and region.getMemStoreFlushOffHeapSize/# of families ({}) " + "instead.", 079 HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND, region.getTableDescriptor().getTableName(), 080 flushedSizeLowerBoundString, nfe, flushSizeLowerBound); 081 082 } 083 } 084 } 085 086 protected boolean shouldFlush(HStore store) { 087 if ( 088 store.getMemStoreSize().getHeapSize() + store.getMemStoreSize().getOffHeapSize() 089 > this.flushSizeLowerBound 090 ) { 091 LOG.debug( 092 "Flush {} of {}; " + "heap memstoreSize={} +" 093 + "off heap memstoreSize={} > memstore lowerBound={}", 094 store.getColumnFamilyName(), region.getRegionInfo().getEncodedName(), 095 store.getMemStoreSize().getHeapSize(), store.getMemStoreSize().getOffHeapSize(), 096 this.flushSizeLowerBound); 097 return true; 098 } 099 return false; 100 } 101}