2222import java .lang .management .MemoryUsage ;
2323import org .apache .hadoop .conf .Configuration ;
2424import org .apache .hadoop .hbase .HConstants ;
25+ import org .apache .hadoop .hbase .StorageSize ;
26+ import org .apache .hadoop .hbase .StorageUnit ;
2527import org .apache .hadoop .hbase .regionserver .MemStoreLAB ;
2628import org .apache .hadoop .hbase .util .Pair ;
2729import org .apache .yetus .audience .InterfaceAudience ;
@@ -93,11 +95,16 @@ public static void checkForClusterFreeHeapMemoryLimit(Configuration conf) {
9395 ) {
9496 throw new RuntimeException ("Current heap configuration for MemStore and BlockCache exceeds "
9597 + "the threshold required for successful cluster operation. "
96- + "The combined value cannot exceed 0.8. Please check "
97- + "the settings for hbase.regionserver.global.memstore.size and "
98- + "hfile.block.cache.size in your configuration. "
99- + "hbase.regionserver.global.memstore.size is " + globalMemstoreSize
100- + " hfile.block.cache.size is " + blockCacheUpperLimit );
98+ + "The combined value cannot exceed 0.8. Please check " + "the settings for "
99+ + MEMSTORE_SIZE_KEY + " and either " + HConstants .HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY + " or "
100+ + HConstants .HFILE_BLOCK_CACHE_SIZE_KEY + " in your configuration. " + MEMSTORE_SIZE_KEY
101+ + "=" + globalMemstoreSize + ", " + HConstants .HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY + "="
102+ + conf .get (HConstants .HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY ) + ", "
103+ + HConstants .HFILE_BLOCK_CACHE_SIZE_KEY + "="
104+ + conf .get (HConstants .HFILE_BLOCK_CACHE_SIZE_KEY ) + ". (Note: If both "
105+ + HConstants .HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY + " and "
106+ + HConstants .HFILE_BLOCK_CACHE_SIZE_KEY + " are set, " + "the system will use "
107+ + HConstants .HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY + ")" );
101108 }
102109 }
103110
@@ -195,10 +202,30 @@ public static long getOnheapGlobalMemStoreSize(Configuration conf) {
195202 * Retrieve configured size for on heap block cache as percentage of total heap.
196203 */
197204 public static float getBlockCacheHeapPercent (final Configuration conf ) {
198- // L1 block cache is always on heap
199- float l1CachePercent = conf .getFloat (HConstants .HFILE_BLOCK_CACHE_SIZE_KEY ,
205+ // Check if an explicit block cache size is configured.
206+ long l1CacheSizeInBytes = getBlockCacheSizeInBytes (conf );
207+ if (l1CacheSizeInBytes > 0 ) {
208+ final MemoryUsage usage = safeGetHeapMemoryUsage ();
209+ return usage == null ? 0 : (float ) l1CacheSizeInBytes / usage .getMax ();
210+ }
211+
212+ return conf .getFloat (HConstants .HFILE_BLOCK_CACHE_SIZE_KEY ,
200213 HConstants .HFILE_BLOCK_CACHE_SIZE_DEFAULT );
201- return l1CachePercent ;
214+ }
215+
216+ /**
217+ * Retrieve an explicit block cache size in bytes in the configuration.
218+ * @param conf used to read cache configs
219+ * @return the number of bytes to use for LRU, negative if disabled.
220+ * @throws IllegalArgumentException if HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY format is invalid
221+ */
222+ public static long getBlockCacheSizeInBytes (Configuration conf ) {
223+ final String key = HConstants .HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY ;
224+ try {
225+ return Long .parseLong (conf .get (key ));
226+ } catch (NumberFormatException e ) {
227+ return (long ) StorageSize .getStorageSize (conf .get (key ), -1 , StorageUnit .BYTES );
228+ }
202229 }
203230
204231 /**
@@ -207,27 +234,30 @@ public static float getBlockCacheHeapPercent(final Configuration conf) {
207234 * @throws IllegalArgumentException if HFILE_BLOCK_CACHE_SIZE_KEY is > 1.0
208235 */
209236 public static long getOnHeapCacheSize (final Configuration conf ) {
210- float cachePercentage = conf .getFloat (HConstants .HFILE_BLOCK_CACHE_SIZE_KEY ,
211- HConstants .HFILE_BLOCK_CACHE_SIZE_DEFAULT );
237+ final float cachePercentage = getBlockCacheHeapPercent (conf );
212238 if (cachePercentage <= 0.0001f ) {
213239 return -1 ;
214240 }
215241 if (cachePercentage > 1.0 ) {
216242 throw new IllegalArgumentException (
217243 HConstants .HFILE_BLOCK_CACHE_SIZE_KEY + " must be between 0.0 and 1.0, and not > 1.0" );
218244 }
219- long max = - 1L ;
245+
220246 final MemoryUsage usage = safeGetHeapMemoryUsage ();
221- if (usage ! = null ) {
222- max = usage . getMax () ;
247+ if (usage = = null ) {
248+ return - 1 ;
223249 }
250+ final long heapMax = usage .getMax ();
224251 float onHeapCacheFixedSize =
225252 (float ) conf .getLong (HConstants .HFILE_ONHEAP_BLOCK_CACHE_FIXED_SIZE_KEY ,
226- HConstants .HFILE_ONHEAP_BLOCK_CACHE_FIXED_SIZE_DEFAULT ) / max ;
253+ HConstants .HFILE_ONHEAP_BLOCK_CACHE_FIXED_SIZE_DEFAULT ) / heapMax ;
227254 // Calculate the amount of heap to give the heap.
228- return (onHeapCacheFixedSize > 0 && onHeapCacheFixedSize < cachePercentage )
229- ? (long ) (max * onHeapCacheFixedSize )
230- : (long ) (max * cachePercentage );
255+ if (onHeapCacheFixedSize > 0 && onHeapCacheFixedSize < cachePercentage ) {
256+ return (long ) (heapMax * onHeapCacheFixedSize );
257+ } else {
258+ final long cacheSizeInBytes = getBlockCacheSizeInBytes (conf );
259+ return cacheSizeInBytes > 0 ? cacheSizeInBytes : (long ) (heapMax * cachePercentage );
260+ }
231261 }
232262
233263 /**
@@ -243,5 +273,4 @@ public static long getBucketCacheSize(final Configuration conf) {
243273 }
244274 return (long ) (bucketCacheSize * 1024 * 1024 );
245275 }
246-
247276}
0 commit comments