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 protected void setFlushSizeLowerBounds(HRegion region) { 047 int familyNumber = region.getTableDescriptor().getColumnFamilyCount(); 048 // For multiple families, lower bound is the "average flush size" by default 049 // unless setting in configuration is larger. 050 flushSizeLowerBound = region.getMemStoreFlushSize() / familyNumber; 051 long minimumLowerBound = 052 getConf().getLong(HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND_MIN, 053 DEFAULT_HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND_MIN); 054 if (minimumLowerBound > flushSizeLowerBound) { 055 flushSizeLowerBound = minimumLowerBound; 056 } 057 // use the setting in table description if any 058 String flushedSizeLowerBoundString = 059 region.getTableDescriptor().getValue(HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND); 060 if (flushedSizeLowerBoundString == null) { 061 LOG.debug("No {} set in table {} descriptor;" 062 + "using region.getMemStoreFlushHeapSize/# of families ({}) " 063 + "instead." 064 , HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND 065 , region.getTableDescriptor().getTableName() 066 , StringUtils.humanSize(flushSizeLowerBound) 067 + ")"); 068 } else { 069 try { 070 flushSizeLowerBound = Long.parseLong(flushedSizeLowerBoundString); 071 } catch (NumberFormatException nfe) { 072 // fall back for fault setting 073 LOG.warn("Number format exception parsing {} for table {}: {}, {}; " 074 + "using region.getMemStoreFlushHeapSize/# of families ({}) " 075 + "and region.getMemStoreFlushOffHeapSize/# of families ({}) " 076 + "instead." 077 , HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND 078 , region.getTableDescriptor().getTableName() 079 , flushedSizeLowerBoundString 080 , nfe 081 , flushSizeLowerBound 082 ); 083 084 } 085 } 086 } 087 088 protected boolean shouldFlush(HStore store) { 089 if (store.getMemStoreSize().getHeapSize() 090 + store.getMemStoreSize().getOffHeapSize() > this.flushSizeLowerBound) { 091 LOG.debug("Flush {} of {}; " 092 + "heap memstoreSize={} +" 093 + "off heap memstoreSize={} > memstore lowerBound={}" 094 , store.getColumnFamilyName() 095 , region.getRegionInfo().getEncodedName() 096 , store.getMemStoreSize().getHeapSize() 097 , store.getMemStoreSize().getOffHeapSize() 098 , this.flushSizeLowerBound 099 ); 100 return true; 101 } 102 return false; 103 } 104}