2121import java .lang .management .MemoryType ;
2222import java .lang .management .MemoryUsage ;
2323import org .apache .hadoop .conf .Configuration ;
24+ import org .apache .hadoop .conf .StorageUnit ;
2425import org .apache .hadoop .hbase .HConstants ;
2526import org .apache .hadoop .hbase .regionserver .MemStoreLAB ;
2627import org .apache .hadoop .hbase .util .Pair ;
@@ -93,11 +94,16 @@ public static void checkForClusterFreeHeapMemoryLimit(Configuration conf) {
9394 ) {
9495 throw new RuntimeException ("Current heap configuration for MemStore and BlockCache exceeds "
9596 + "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 );
97+ + "The combined value cannot exceed 0.8. Please check " + "the settings for "
98+ + MEMSTORE_SIZE_KEY + " and either " + HConstants .HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY + " or "
99+ + HConstants .HFILE_BLOCK_CACHE_SIZE_KEY + " in your configuration. " + MEMSTORE_SIZE_KEY
100+ + "=" + globalMemstoreSize + ", " + HConstants .HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY + "="
101+ + conf .get (HConstants .HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY ) + ", "
102+ + HConstants .HFILE_BLOCK_CACHE_SIZE_KEY + "="
103+ + conf .get (HConstants .HFILE_BLOCK_CACHE_SIZE_KEY ) + ". (Note: If both "
104+ + HConstants .HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY + " and "
105+ + HConstants .HFILE_BLOCK_CACHE_SIZE_KEY + " are set, " + "the system will use "
106+ + HConstants .HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY + ")" );
101107 }
102108 }
103109
@@ -195,10 +201,30 @@ public static long getOnheapGlobalMemStoreSize(Configuration conf) {
195201 * Retrieve configured size for on heap block cache as percentage of total heap.
196202 */
197203 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 ,
204+ // Check if an explicit block cache size is configured.
205+ long l1CacheSizeInBytes = getBlockCacheSizeInBytes (conf );
206+ if (l1CacheSizeInBytes > 0 ) {
207+ final MemoryUsage usage = safeGetHeapMemoryUsage ();
208+ return usage == null ? 0 : (float ) l1CacheSizeInBytes / usage .getMax ();
209+ }
210+
211+ return conf .getFloat (HConstants .HFILE_BLOCK_CACHE_SIZE_KEY ,
200212 HConstants .HFILE_BLOCK_CACHE_SIZE_DEFAULT );
201- return l1CachePercent ;
213+ }
214+
215+ /**
216+ * Retrieve an explicit block cache size in bytes in the configuration.
217+ * @param conf used to read cache configs
218+ * @return the number of bytes to use for LRU, negative if disabled.
219+ * @throws IllegalArgumentException if HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY format is invalid
220+ */
221+ public static long getBlockCacheSizeInBytes (Configuration conf ) {
222+ final String key = HConstants .HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY ;
223+ try {
224+ return Long .parseLong (conf .get (key ));
225+ } catch (NumberFormatException e ) {
226+ return (long ) conf .getStorageSize (key , -1 , StorageUnit .BYTES );
227+ }
202228 }
203229
204230 /**
@@ -207,27 +233,30 @@ public static float getBlockCacheHeapPercent(final Configuration conf) {
207233 * @throws IllegalArgumentException if HFILE_BLOCK_CACHE_SIZE_KEY is > 1.0
208234 */
209235 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 );
236+ final float cachePercentage = getBlockCacheHeapPercent (conf );
212237 if (cachePercentage <= 0.0001f ) {
213238 return -1 ;
214239 }
215240 if (cachePercentage > 1.0 ) {
216241 throw new IllegalArgumentException (
217242 HConstants .HFILE_BLOCK_CACHE_SIZE_KEY + " must be between 0.0 and 1.0, and not > 1.0" );
218243 }
219- long max = - 1L ;
244+
220245 final MemoryUsage usage = safeGetHeapMemoryUsage ();
221- if (usage ! = null ) {
222- max = usage . getMax () ;
246+ if (usage = = null ) {
247+ return - 1 ;
223248 }
249+ final long heapMax = usage .getMax ();
224250 float onHeapCacheFixedSize =
225251 (float ) conf .getLong (HConstants .HFILE_ONHEAP_BLOCK_CACHE_FIXED_SIZE_KEY ,
226- HConstants .HFILE_ONHEAP_BLOCK_CACHE_FIXED_SIZE_DEFAULT ) / max ;
252+ HConstants .HFILE_ONHEAP_BLOCK_CACHE_FIXED_SIZE_DEFAULT ) / heapMax ;
227253 // Calculate the amount of heap to give the heap.
228- return (onHeapCacheFixedSize > 0 && onHeapCacheFixedSize < cachePercentage )
229- ? (long ) (max * onHeapCacheFixedSize )
230- : (long ) (max * cachePercentage );
254+ if (onHeapCacheFixedSize > 0 && onHeapCacheFixedSize < cachePercentage ) {
255+ return (long ) (heapMax * onHeapCacheFixedSize );
256+ } else {
257+ final long cacheSizeInBytes = getBlockCacheSizeInBytes (conf );
258+ return cacheSizeInBytes > 0 ? cacheSizeInBytes : (long ) (heapMax * cachePercentage );
259+ }
231260 }
232261
233262 /**
@@ -243,5 +272,4 @@ public static long getBucketCacheSize(final Configuration conf) {
243272 }
244273 return (long ) (bucketCacheSize * 1024 * 1024 );
245274 }
246-
247275}
0 commit comments