HBASE-19357 Bucket cache no longer L2 for LRU cache.

This commit is contained in:
anoopsamjohn 2017-12-06 11:25:08 +05:30
parent ed60e4518d
commit d34e30cad3
25 changed files with 159 additions and 378 deletions

View File

@ -52,7 +52,7 @@ public class HColumnDescriptor implements ColumnFamilyDescriptor, Comparable<HCo
public static final String CACHE_INDEX_ON_WRITE = ColumnFamilyDescriptorBuilder.CACHE_INDEX_ON_WRITE; public static final String CACHE_INDEX_ON_WRITE = ColumnFamilyDescriptorBuilder.CACHE_INDEX_ON_WRITE;
public static final String CACHE_BLOOMS_ON_WRITE = ColumnFamilyDescriptorBuilder.CACHE_BLOOMS_ON_WRITE; public static final String CACHE_BLOOMS_ON_WRITE = ColumnFamilyDescriptorBuilder.CACHE_BLOOMS_ON_WRITE;
public static final String EVICT_BLOCKS_ON_CLOSE = ColumnFamilyDescriptorBuilder.EVICT_BLOCKS_ON_CLOSE; public static final String EVICT_BLOCKS_ON_CLOSE = ColumnFamilyDescriptorBuilder.EVICT_BLOCKS_ON_CLOSE;
public static final String CACHE_DATA_IN_L1 = ColumnFamilyDescriptorBuilder.CACHE_DATA_IN_L1; public static final String CACHE_DATA_IN_L1 = "CACHE_DATA_IN_L1";
public static final String PREFETCH_BLOCKS_ON_OPEN = ColumnFamilyDescriptorBuilder.PREFETCH_BLOCKS_ON_OPEN; public static final String PREFETCH_BLOCKS_ON_OPEN = ColumnFamilyDescriptorBuilder.PREFETCH_BLOCKS_ON_OPEN;
public static final String BLOCKSIZE = ColumnFamilyDescriptorBuilder.BLOCKSIZE; public static final String BLOCKSIZE = ColumnFamilyDescriptorBuilder.BLOCKSIZE;
public static final String LENGTH = "LENGTH"; public static final String LENGTH = "LENGTH";
@ -87,7 +87,7 @@ public class HColumnDescriptor implements ColumnFamilyDescriptor, Comparable<HCo
public static final KeepDeletedCells DEFAULT_KEEP_DELETED = ColumnFamilyDescriptorBuilder.DEFAULT_KEEP_DELETED; public static final KeepDeletedCells DEFAULT_KEEP_DELETED = ColumnFamilyDescriptorBuilder.DEFAULT_KEEP_DELETED;
public static final boolean DEFAULT_BLOCKCACHE = ColumnFamilyDescriptorBuilder.DEFAULT_BLOCKCACHE; public static final boolean DEFAULT_BLOCKCACHE = ColumnFamilyDescriptorBuilder.DEFAULT_BLOCKCACHE;
public static final boolean DEFAULT_CACHE_DATA_ON_WRITE = ColumnFamilyDescriptorBuilder.DEFAULT_CACHE_DATA_ON_WRITE; public static final boolean DEFAULT_CACHE_DATA_ON_WRITE = ColumnFamilyDescriptorBuilder.DEFAULT_CACHE_DATA_ON_WRITE;
public static final boolean DEFAULT_CACHE_DATA_IN_L1 = ColumnFamilyDescriptorBuilder.DEFAULT_CACHE_DATA_IN_L1; public static final boolean DEFAULT_CACHE_DATA_IN_L1 = false;
public static final boolean DEFAULT_CACHE_INDEX_ON_WRITE = ColumnFamilyDescriptorBuilder.DEFAULT_CACHE_INDEX_ON_WRITE; public static final boolean DEFAULT_CACHE_INDEX_ON_WRITE = ColumnFamilyDescriptorBuilder.DEFAULT_CACHE_INDEX_ON_WRITE;
public static final int DEFAULT_BLOCKSIZE = ColumnFamilyDescriptorBuilder.DEFAULT_BLOCKSIZE; public static final int DEFAULT_BLOCKSIZE = ColumnFamilyDescriptorBuilder.DEFAULT_BLOCKSIZE;
public static final String DEFAULT_BLOOMFILTER = ColumnFamilyDescriptorBuilder.DEFAULT_BLOOMFILTER.name(); public static final String DEFAULT_BLOOMFILTER = ColumnFamilyDescriptorBuilder.DEFAULT_BLOOMFILTER.name();
@ -534,18 +534,16 @@ public class HColumnDescriptor implements ColumnFamilyDescriptor, Comparable<HCo
return this; return this;
} }
@Override
public boolean isCacheDataInL1() {
return delegatee.isCacheDataInL1();
}
/** /**
* @param value true if we should cache data blocks in the L1 cache (if block cache deploy * This is a noop call from HBase 2.0 onwards
* has more than one tier; e.g. we are using CombinedBlockCache). *
* @return this (for chained invocation) * @return this (for chained invocation)
* @deprecated Since 2.0 and will be removed in 3.0 with out any replacement. Caching data in on
* heap Cache, when there are both on heap LRU Cache and Bucket Cache will no longer
* be supported from 2.0.
*/ */
@Deprecated
public HColumnDescriptor setCacheDataInL1(boolean value) { public HColumnDescriptor setCacheDataInL1(boolean value) {
getDelegateeForModification().setCacheDataInL1(value);
return this; return this;
} }

View File

@ -202,11 +202,7 @@ public interface ColumnFamilyDescriptor {
* @return true if we should cache bloomfilter blocks on write * @return true if we should cache bloomfilter blocks on write
*/ */
boolean isCacheBloomsOnWrite(); boolean isCacheBloomsOnWrite();
/**
* @return true if we should cache data blocks in the L1 cache (if block cache deploy has more
* than one tier; e.g. we are using CombinedBlockCache).
*/
boolean isCacheDataInL1();
/** /**
* @return true if we should cache data blocks on write * @return true if we should cache data blocks on write
*/ */

View File

@ -98,14 +98,6 @@ public class ColumnFamilyDescriptorBuilder {
@InterfaceAudience.Private @InterfaceAudience.Private
public static final String EVICT_BLOCKS_ON_CLOSE = "EVICT_BLOCKS_ON_CLOSE"; public static final String EVICT_BLOCKS_ON_CLOSE = "EVICT_BLOCKS_ON_CLOSE";
private static final Bytes EVICT_BLOCKS_ON_CLOSE_BYTES = new Bytes(Bytes.toBytes(EVICT_BLOCKS_ON_CLOSE)); private static final Bytes EVICT_BLOCKS_ON_CLOSE_BYTES = new Bytes(Bytes.toBytes(EVICT_BLOCKS_ON_CLOSE));
/**
* Key for cache data into L1 if cache is set up with more than one tier. To
* set in the shell, do something like this: <code>hbase(main):003:0&gt; create 't',
* {NAME =&gt; 't', CONFIGURATION =&gt; {CACHE_DATA_IN_L1 =&gt; 'true'}}</code>
*/
@InterfaceAudience.Private
public static final String CACHE_DATA_IN_L1 = "CACHE_DATA_IN_L1";
private static final Bytes CACHE_DATA_IN_L1_BYTES = new Bytes(Bytes.toBytes(CACHE_DATA_IN_L1));
/** /**
* Key for the PREFETCH_BLOCKS_ON_OPEN attribute. If set, all INDEX, BLOOM, * Key for the PREFETCH_BLOCKS_ON_OPEN attribute. If set, all INDEX, BLOOM,
@ -228,13 +220,6 @@ public class ColumnFamilyDescriptorBuilder {
*/ */
public static final boolean DEFAULT_CACHE_DATA_ON_WRITE = false; public static final boolean DEFAULT_CACHE_DATA_ON_WRITE = false;
/**
* Default setting for whether to cache data blocks in L1 tier. Only makes
* sense if more than one tier in operations: i.e. if we have an L1 and a L2.
* This will be the cases if we are using BucketCache.
*/
public static final boolean DEFAULT_CACHE_DATA_IN_L1 = false;
/** /**
* Default setting for whether to cache index blocks on write if block caching * Default setting for whether to cache index blocks on write if block caching
* is enabled. * is enabled.
@ -310,7 +295,6 @@ public class ColumnFamilyDescriptorBuilder {
DEFAULT_VALUES.put(KEEP_DELETED_CELLS, String.valueOf(DEFAULT_KEEP_DELETED)); DEFAULT_VALUES.put(KEEP_DELETED_CELLS, String.valueOf(DEFAULT_KEEP_DELETED));
DEFAULT_VALUES.put(DATA_BLOCK_ENCODING, String.valueOf(DEFAULT_DATA_BLOCK_ENCODING)); DEFAULT_VALUES.put(DATA_BLOCK_ENCODING, String.valueOf(DEFAULT_DATA_BLOCK_ENCODING));
DEFAULT_VALUES.put(CACHE_DATA_ON_WRITE, String.valueOf(DEFAULT_CACHE_DATA_ON_WRITE)); DEFAULT_VALUES.put(CACHE_DATA_ON_WRITE, String.valueOf(DEFAULT_CACHE_DATA_ON_WRITE));
DEFAULT_VALUES.put(CACHE_DATA_IN_L1, String.valueOf(DEFAULT_CACHE_DATA_IN_L1));
DEFAULT_VALUES.put(CACHE_INDEX_ON_WRITE, String.valueOf(DEFAULT_CACHE_INDEX_ON_WRITE)); DEFAULT_VALUES.put(CACHE_INDEX_ON_WRITE, String.valueOf(DEFAULT_CACHE_INDEX_ON_WRITE));
DEFAULT_VALUES.put(CACHE_BLOOMS_ON_WRITE, String.valueOf(DEFAULT_CACHE_BLOOMS_ON_WRITE)); DEFAULT_VALUES.put(CACHE_BLOOMS_ON_WRITE, String.valueOf(DEFAULT_CACHE_BLOOMS_ON_WRITE));
DEFAULT_VALUES.put(EVICT_BLOCKS_ON_CLOSE, String.valueOf(DEFAULT_EVICT_BLOCKS_ON_CLOSE)); DEFAULT_VALUES.put(EVICT_BLOCKS_ON_CLOSE, String.valueOf(DEFAULT_EVICT_BLOCKS_ON_CLOSE));
@ -444,11 +428,6 @@ public class ColumnFamilyDescriptorBuilder {
return this; return this;
} }
public ColumnFamilyDescriptorBuilder setCacheDataInL1(boolean value) {
desc.setCacheDataInL1(value);
return this;
}
public ColumnFamilyDescriptorBuilder setCacheDataOnWrite(boolean value) { public ColumnFamilyDescriptorBuilder setCacheDataOnWrite(boolean value) {
desc.setCacheDataOnWrite(value); desc.setCacheDataOnWrite(value);
return this; return this;
@ -1010,21 +989,6 @@ public class ColumnFamilyDescriptorBuilder {
return setValue(CACHE_DATA_ON_WRITE_BYTES, Boolean.toString(value)); return setValue(CACHE_DATA_ON_WRITE_BYTES, Boolean.toString(value));
} }
@Override
public boolean isCacheDataInL1() {
return getStringOrDefault(CACHE_DATA_IN_L1_BYTES, Boolean::valueOf, DEFAULT_CACHE_DATA_IN_L1);
}
/**
* @param value true if we should cache data blocks in the L1 cache (if
* block cache deploy has more than one tier; e.g. we are using
* CombinedBlockCache).
* @return this (for chained invocation)
*/
public ModifyableColumnFamilyDescriptor setCacheDataInL1(boolean value) {
return setValue(CACHE_DATA_IN_L1_BYTES, Boolean.toString(value));
}
@Override @Override
public boolean isCacheIndexesOnWrite() { public boolean isCacheIndexesOnWrite() {
return getStringOrDefault(CACHE_INDEX_ON_WRITE_BYTES, Boolean::valueOf, DEFAULT_CACHE_INDEX_ON_WRITE); return getStringOrDefault(CACHE_INDEX_ON_WRITE_BYTES, Boolean::valueOf, DEFAULT_CACHE_INDEX_ON_WRITE);

View File

@ -226,9 +226,6 @@ public class TableDescriptorBuilder {
.setInMemory(true) .setInMemory(true)
.setBlocksize(8 * 1024) .setBlocksize(8 * 1024)
.setScope(HConstants.REPLICATION_SCOPE_LOCAL) .setScope(HConstants.REPLICATION_SCOPE_LOCAL)
// Enable cache of data blocks in L1 if more than one caching tier deployed:
// e.g. if using CombinedBlockCache (BucketCache).
.setCacheDataInL1(true)
.build()) .build())
.build(); .build();
private final ModifyableTableDescriptor desc; private final ModifyableTableDescriptor desc;

View File

@ -45,8 +45,7 @@ public class TestColumnFamilyDescriptorBuilder {
= ColumnFamilyDescriptorBuilder.newBuilder(HConstants.CATALOG_FAMILY) = ColumnFamilyDescriptorBuilder.newBuilder(HConstants.CATALOG_FAMILY)
.setInMemory(true) .setInMemory(true)
.setScope(HConstants.REPLICATION_SCOPE_LOCAL) .setScope(HConstants.REPLICATION_SCOPE_LOCAL)
.setBloomFilterType(BloomType.NONE) .setBloomFilterType(BloomType.NONE);
.setCacheDataInL1(true);
final int v = 123; final int v = 123;
builder.setBlocksize(v); builder.setBlocksize(v);
builder.setTimeToLive(v); builder.setTimeToLive(v);

View File

@ -51,7 +51,6 @@ public class TestImmutableHColumnDescriptor {
hcd -> hcd.setBlocksize(10), hcd -> hcd.setBlocksize(10),
hcd -> hcd.setBloomFilterType(BloomType.NONE), hcd -> hcd.setBloomFilterType(BloomType.NONE),
hcd -> hcd.setCacheBloomsOnWrite(false), hcd -> hcd.setCacheBloomsOnWrite(false),
hcd -> hcd.setCacheDataInL1(true),
hcd -> hcd.setCacheDataOnWrite(true), hcd -> hcd.setCacheDataOnWrite(true),
hcd -> hcd.setCacheIndexesOnWrite(true), hcd -> hcd.setCacheIndexesOnWrite(true),
hcd -> hcd.setCompactionCompressionType(Compression.Algorithm.LZO), hcd -> hcd.setCompactionCompressionType(Compression.Algorithm.LZO),

View File

@ -900,13 +900,6 @@ possible configurations would overwhelm and obscure the important.
See http://hbase.apache.org/book.html#offheap.blockcache for more information. See http://hbase.apache.org/book.html#offheap.blockcache for more information.
</description> </description>
</property> </property>
<property>
<name>hbase.bucketcache.combinedcache.enabled</name>
<value>true</value>
<description>Whether or not the bucketcache is used in league with the LRU
on-heap block cache. In this mode, indices and blooms are kept in the LRU
blockcache and the data blocks are kept in the bucketcache.</description>
</property>
<property> <property>
<name>hbase.bucketcache.size</name> <name>hbase.bucketcache.size</name>
<value></value> <value></value>

View File

@ -110,10 +110,7 @@ public class MemcachedBlockCache implements BlockCache {
} }
@Override @Override
public void cacheBlock(BlockCacheKey cacheKey, public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory) {
Cacheable buf,
boolean inMemory,
boolean cacheDataInL1) {
cacheBlock(cacheKey, buf); cacheBlock(cacheKey, buf);
} }
@ -288,10 +285,4 @@ public class MemcachedBlockCache implements BlockCache {
return MAX_SIZE; return MAX_SIZE;
} }
} }
@Override
public void returnBlock(BlockCacheKey cacheKey, Cacheable block) {
// Not doing reference counting. All blocks here are EXCLUSIVE
}
} }

View File

@ -34,11 +34,8 @@ public interface BlockCache extends Iterable<CachedBlock> {
* @param cacheKey The block's cache key. * @param cacheKey The block's cache key.
* @param buf The block contents wrapped in a ByteBuffer. * @param buf The block contents wrapped in a ByteBuffer.
* @param inMemory Whether block should be treated as in-memory * @param inMemory Whether block should be treated as in-memory
* @param cacheDataInL1 If multi-tier block cache deploy -- i.e. has an L1 and L2 tier -- then
* if this flag is true, cache data blocks up in the L1 tier (meta blocks are probably being
* cached in L1 already).
*/ */
void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory, boolean cacheDataInL1); void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory);
/** /**
* Add block to cache (defaults to not in-memory). * Add block to cache (defaults to not in-memory).
@ -146,5 +143,5 @@ public interface BlockCache extends Iterable<CachedBlock> {
* @param cacheKey the cache key of the block * @param cacheKey the cache key of the block
* @param block the hfileblock to be returned * @param block the hfileblock to be returned
*/ */
void returnBlock(BlockCacheKey cacheKey, Cacheable block); default void returnBlock(BlockCacheKey cacheKey, Cacheable block){};
} }

View File

@ -28,7 +28,6 @@ import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor; import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
import org.apache.hadoop.hbase.io.hfile.BlockType.BlockCategory; import org.apache.hadoop.hbase.io.hfile.BlockType.BlockCategory;
import org.apache.hadoop.hbase.io.hfile.bucket.BucketCache; import org.apache.hadoop.hbase.io.hfile.bucket.BucketCache;
import org.apache.hadoop.hbase.io.util.MemorySizeUtil; import org.apache.hadoop.hbase.io.util.MemorySizeUtil;
@ -109,14 +108,6 @@ public class CacheConfig {
public static final String BUCKET_CACHE_PERSISTENT_PATH_KEY = public static final String BUCKET_CACHE_PERSISTENT_PATH_KEY =
"hbase.bucketcache.persistent.path"; "hbase.bucketcache.persistent.path";
/**
* If the bucket cache is used in league with the lru on-heap block cache (meta blocks such
* as indices and blooms are kept in the lru blockcache and the data blocks in the
* bucket cache).
*/
public static final String BUCKET_CACHE_COMBINED_KEY =
"hbase.bucketcache.combinedcache.enabled";
public static final String BUCKET_CACHE_WRITER_THREADS_KEY = "hbase.bucketcache.writer.threads"; public static final String BUCKET_CACHE_WRITER_THREADS_KEY = "hbase.bucketcache.writer.threads";
public static final String BUCKET_CACHE_WRITER_QUEUE_KEY = public static final String BUCKET_CACHE_WRITER_QUEUE_KEY =
"hbase.bucketcache.writer.queuelength"; "hbase.bucketcache.writer.queuelength";
@ -129,7 +120,6 @@ public class CacheConfig {
/** /**
* Defaults for Bucket cache * Defaults for Bucket cache
*/ */
public static final boolean DEFAULT_BUCKET_CACHE_COMBINED = true;
public static final int DEFAULT_BUCKET_CACHE_WRITER_THREADS = 3; public static final int DEFAULT_BUCKET_CACHE_WRITER_THREADS = 3;
public static final int DEFAULT_BUCKET_CACHE_WRITER_QUEUE = 64; public static final int DEFAULT_BUCKET_CACHE_WRITER_QUEUE = 64;
@ -218,13 +208,6 @@ public class CacheConfig {
/** Whether data blocks should be prefetched into the cache */ /** Whether data blocks should be prefetched into the cache */
private final boolean prefetchOnOpen; private final boolean prefetchOnOpen;
/**
* If true and if more than one tier in this cache deploy -- e.g. CombinedBlockCache has an L1
* and an L2 tier -- then cache data blocks up in the L1 tier (The meta blocks are likely being
* cached up in L1 already. At least this is the case if CombinedBlockCache).
*/
private boolean cacheDataInL1;
private final boolean dropBehindCompaction; private final boolean dropBehindCompaction;
/** /**
@ -251,8 +234,6 @@ public class CacheConfig {
conf.getBoolean(CACHE_DATA_BLOCKS_COMPRESSED_KEY, DEFAULT_CACHE_DATA_COMPRESSED), conf.getBoolean(CACHE_DATA_BLOCKS_COMPRESSED_KEY, DEFAULT_CACHE_DATA_COMPRESSED),
conf.getBoolean(PREFETCH_BLOCKS_ON_OPEN_KEY, conf.getBoolean(PREFETCH_BLOCKS_ON_OPEN_KEY,
DEFAULT_PREFETCH_ON_OPEN) || family.isPrefetchBlocksOnOpen(), DEFAULT_PREFETCH_ON_OPEN) || family.isPrefetchBlocksOnOpen(),
conf.getBoolean(ColumnFamilyDescriptorBuilder.CACHE_DATA_IN_L1,
ColumnFamilyDescriptorBuilder.DEFAULT_CACHE_DATA_IN_L1) || family.isCacheDataInL1(),
conf.getBoolean(DROP_BEHIND_CACHE_COMPACTION_KEY, DROP_BEHIND_CACHE_COMPACTION_DEFAULT) conf.getBoolean(DROP_BEHIND_CACHE_COMPACTION_KEY, DROP_BEHIND_CACHE_COMPACTION_DEFAULT)
); );
LOG.info("Created cacheConfig for " + family.getNameAsString() + ": " + this); LOG.info("Created cacheConfig for " + family.getNameAsString() + ": " + this);
@ -276,8 +257,6 @@ public class CacheConfig {
conf.getBoolean(EVICT_BLOCKS_ON_CLOSE_KEY, DEFAULT_EVICT_ON_CLOSE), conf.getBoolean(EVICT_BLOCKS_ON_CLOSE_KEY, DEFAULT_EVICT_ON_CLOSE),
conf.getBoolean(CACHE_DATA_BLOCKS_COMPRESSED_KEY, DEFAULT_CACHE_DATA_COMPRESSED), conf.getBoolean(CACHE_DATA_BLOCKS_COMPRESSED_KEY, DEFAULT_CACHE_DATA_COMPRESSED),
conf.getBoolean(PREFETCH_BLOCKS_ON_OPEN_KEY, DEFAULT_PREFETCH_ON_OPEN), conf.getBoolean(PREFETCH_BLOCKS_ON_OPEN_KEY, DEFAULT_PREFETCH_ON_OPEN),
conf.getBoolean(ColumnFamilyDescriptorBuilder.CACHE_DATA_IN_L1,
ColumnFamilyDescriptorBuilder.DEFAULT_CACHE_DATA_IN_L1),
conf.getBoolean(DROP_BEHIND_CACHE_COMPACTION_KEY, DROP_BEHIND_CACHE_COMPACTION_DEFAULT) conf.getBoolean(DROP_BEHIND_CACHE_COMPACTION_KEY, DROP_BEHIND_CACHE_COMPACTION_DEFAULT)
); );
LOG.info("Created cacheConfig: " + this); LOG.info("Created cacheConfig: " + this);
@ -305,7 +284,7 @@ public class CacheConfig {
final boolean cacheDataOnWrite, final boolean cacheIndexesOnWrite, final boolean cacheDataOnWrite, final boolean cacheIndexesOnWrite,
final boolean cacheBloomsOnWrite, final boolean evictOnClose, final boolean cacheBloomsOnWrite, final boolean evictOnClose,
final boolean cacheDataCompressed, final boolean prefetchOnOpen, final boolean cacheDataCompressed, final boolean prefetchOnOpen,
final boolean cacheDataInL1, final boolean dropBehindCompaction) { final boolean dropBehindCompaction) {
this.blockCache = blockCache; this.blockCache = blockCache;
this.cacheDataOnRead = cacheDataOnRead; this.cacheDataOnRead = cacheDataOnRead;
this.inMemory = inMemory; this.inMemory = inMemory;
@ -315,7 +294,6 @@ public class CacheConfig {
this.evictOnClose = evictOnClose; this.evictOnClose = evictOnClose;
this.cacheDataCompressed = cacheDataCompressed; this.cacheDataCompressed = cacheDataCompressed;
this.prefetchOnOpen = prefetchOnOpen; this.prefetchOnOpen = prefetchOnOpen;
this.cacheDataInL1 = cacheDataInL1;
this.dropBehindCompaction = dropBehindCompaction; this.dropBehindCompaction = dropBehindCompaction;
} }
@ -328,12 +306,11 @@ public class CacheConfig {
cacheConf.cacheDataOnWrite, cacheConf.cacheIndexesOnWrite, cacheConf.cacheDataOnWrite, cacheConf.cacheIndexesOnWrite,
cacheConf.cacheBloomsOnWrite, cacheConf.evictOnClose, cacheConf.cacheBloomsOnWrite, cacheConf.evictOnClose,
cacheConf.cacheDataCompressed, cacheConf.prefetchOnOpen, cacheConf.cacheDataCompressed, cacheConf.prefetchOnOpen,
cacheConf.cacheDataInL1, cacheConf.dropBehindCompaction); cacheConf.dropBehindCompaction);
} }
private CacheConfig() { private CacheConfig() {
this(null, false, false, false, false, false, this(null, false, false, false, false, false, false, false, false, false);
false, false, false, false, false);
} }
/** /**
@ -386,13 +363,6 @@ public class CacheConfig {
return isBlockCacheEnabled() && this.inMemory; return isBlockCacheEnabled() && this.inMemory;
} }
/**
* @return True if cache data blocks in L1 tier (if more than one tier in block cache deploy).
*/
public boolean isCacheDataInL1() {
return isBlockCacheEnabled() && this.cacheDataInL1;
}
/** /**
* @return true if data blocks should be written to the cache when an HFile is * @return true if data blocks should be written to the cache when an HFile is
* written, false if not * written, false if not
@ -411,16 +381,6 @@ public class CacheConfig {
this.cacheDataOnWrite = cacheDataOnWrite; this.cacheDataOnWrite = cacheDataOnWrite;
} }
/**
* Only used for testing.
* @param cacheDataInL1 Whether to cache data blocks up in l1 (if a multi-tier cache
* implementation).
*/
@VisibleForTesting
public void setCacheDataInL1(boolean cacheDataInL1) {
this.cacheDataInL1 = cacheDataInL1;
}
/** /**
* @return true if index blocks should be written to the cache when an HFile * @return true if index blocks should be written to the cache when an HFile
* is written, false if not * is written, false if not
@ -547,8 +507,8 @@ public class CacheConfig {
// Clear this if in tests you'd make more than one block cache instance. // Clear this if in tests you'd make more than one block cache instance.
@VisibleForTesting @VisibleForTesting
static BlockCache GLOBAL_BLOCK_CACHE_INSTANCE; static BlockCache GLOBAL_BLOCK_CACHE_INSTANCE;
private static LruBlockCache GLOBAL_L1_CACHE_INSTANCE = null; private static LruBlockCache ONHEAP_CACHE_INSTANCE = null;
private static BlockCache GLOBAL_L2_CACHE_INSTANCE = null; private static BlockCache L2_CACHE_INSTANCE = null;// Can be BucketCache or External cache.
/** Boolean whether we have disabled the block cache entirely. */ /** Boolean whether we have disabled the block cache entirely. */
@VisibleForTesting @VisibleForTesting
@ -558,20 +518,20 @@ public class CacheConfig {
* @param c Configuration to use. * @param c Configuration to use.
* @return An L1 instance. Currently an instance of LruBlockCache. * @return An L1 instance. Currently an instance of LruBlockCache.
*/ */
public static LruBlockCache getL1(final Configuration c) { public static LruBlockCache getOnHeapCache(final Configuration c) {
return getL1Internal(c); return getOnHeapCacheInternal(c);
} }
public CacheStats getL1Stats() { public CacheStats getOnHeapCacheStats() {
if (GLOBAL_L1_CACHE_INSTANCE != null) { if (ONHEAP_CACHE_INSTANCE != null) {
return GLOBAL_L1_CACHE_INSTANCE.getStats(); return ONHEAP_CACHE_INSTANCE.getStats();
} }
return null; return null;
} }
public CacheStats getL2Stats() { public CacheStats getL2CacheStats() {
if (GLOBAL_L2_CACHE_INSTANCE != null) { if (L2_CACHE_INSTANCE != null) {
return GLOBAL_L2_CACHE_INSTANCE.getStats(); return L2_CACHE_INSTANCE.getStats();
} }
return null; return null;
} }
@ -580,43 +540,26 @@ public class CacheConfig {
* @param c Configuration to use. * @param c Configuration to use.
* @return An L1 instance. Currently an instance of LruBlockCache. * @return An L1 instance. Currently an instance of LruBlockCache.
*/ */
private synchronized static LruBlockCache getL1Internal(final Configuration c) { private synchronized static LruBlockCache getOnHeapCacheInternal(final Configuration c) {
if (GLOBAL_L1_CACHE_INSTANCE != null) return GLOBAL_L1_CACHE_INSTANCE; if (ONHEAP_CACHE_INSTANCE != null) {
final long lruCacheSize = MemorySizeUtil.getLruCacheSize(c); return ONHEAP_CACHE_INSTANCE;
if (lruCacheSize < 0) { }
final long cacheSize = MemorySizeUtil.getOnHeapCacheSize(c);
if (cacheSize < 0) {
blockCacheDisabled = true; blockCacheDisabled = true;
} }
if (blockCacheDisabled) return null; if (blockCacheDisabled) return null;
int blockSize = c.getInt(BLOCKCACHE_BLOCKSIZE_KEY, HConstants.DEFAULT_BLOCKSIZE); int blockSize = c.getInt(BLOCKCACHE_BLOCKSIZE_KEY, HConstants.DEFAULT_BLOCKSIZE);
LOG.info("Allocating LruBlockCache size=" + LOG.info("Allocating On heap LruBlockCache size=" +
StringUtils.byteDesc(lruCacheSize) + ", blockSize=" + StringUtils.byteDesc(blockSize)); StringUtils.byteDesc(cacheSize) + ", blockSize=" + StringUtils.byteDesc(blockSize));
GLOBAL_L1_CACHE_INSTANCE = new LruBlockCache(lruCacheSize, blockSize, true, c); ONHEAP_CACHE_INSTANCE = new LruBlockCache(cacheSize, blockSize, true, c);
return GLOBAL_L1_CACHE_INSTANCE; return ONHEAP_CACHE_INSTANCE;
}
/**
* @param c Configuration to use.
* @return Returns L2 block cache instance (for now it is BucketCache BlockCache all the time)
* or null if not supposed to be a L2.
*/
@VisibleForTesting
static BlockCache getL2(final Configuration c) {
final boolean useExternal = c.getBoolean(EXTERNAL_BLOCKCACHE_KEY, EXTERNAL_BLOCKCACHE_DEFAULT);
if (LOG.isDebugEnabled()) {
LOG.debug("Trying to use " + (useExternal?" External":" Internal") + " l2 cache");
}
// If we want to use an external block cache then create that.
if (useExternal) {
GLOBAL_L2_CACHE_INSTANCE = getExternalBlockcache(c);
} else {
// otherwise use the bucket cache.
GLOBAL_L2_CACHE_INSTANCE = getBucketCache(c);
}
return GLOBAL_L2_CACHE_INSTANCE;
} }
private static BlockCache getExternalBlockcache(Configuration c) { private static BlockCache getExternalBlockcache(Configuration c) {
if (LOG.isDebugEnabled()) {
LOG.debug("Trying to use External l2 cache");
}
Class klass = null; Class klass = null;
// Get the class, from the config. s // Get the class, from the config. s
@ -642,7 +585,8 @@ public class CacheConfig {
} }
private static BlockCache getBucketCache(Configuration c) { @VisibleForTesting
static BucketCache getBucketCache(Configuration c) {
// Check for L2. ioengine name must be non-null. // Check for L2. ioengine name must be non-null.
String bucketCacheIOEngineName = c.get(BUCKET_CACHE_IOENGINE_KEY, null); String bucketCacheIOEngineName = c.get(BUCKET_CACHE_IOENGINE_KEY, null);
if (bucketCacheIOEngineName == null || bucketCacheIOEngineName.length() <= 0) return null; if (bucketCacheIOEngineName == null || bucketCacheIOEngineName.length() <= 0) return null;
@ -705,30 +649,25 @@ public class CacheConfig {
public static synchronized BlockCache instantiateBlockCache(Configuration conf) { public static synchronized BlockCache instantiateBlockCache(Configuration conf) {
if (GLOBAL_BLOCK_CACHE_INSTANCE != null) return GLOBAL_BLOCK_CACHE_INSTANCE; if (GLOBAL_BLOCK_CACHE_INSTANCE != null) return GLOBAL_BLOCK_CACHE_INSTANCE;
if (blockCacheDisabled) return null; if (blockCacheDisabled) return null;
LruBlockCache l1 = getL1Internal(conf); LruBlockCache onHeapCache = getOnHeapCacheInternal(conf);
// blockCacheDisabled is set as a side-effect of getL1Internal(), so check it again after the call. // blockCacheDisabled is set as a side-effect of getL1Internal(), so check it again after the
// call.
if (blockCacheDisabled) return null; if (blockCacheDisabled) return null;
BlockCache l2 = getL2(conf); boolean useExternal = conf.getBoolean(EXTERNAL_BLOCKCACHE_KEY, EXTERNAL_BLOCKCACHE_DEFAULT);
if (l2 == null) { if (useExternal) {
GLOBAL_BLOCK_CACHE_INSTANCE = l1; L2_CACHE_INSTANCE = getExternalBlockcache(conf);
GLOBAL_BLOCK_CACHE_INSTANCE = L2_CACHE_INSTANCE == null ? onHeapCache
: new InclusiveCombinedBlockCache(onHeapCache, L2_CACHE_INSTANCE);
} else { } else {
boolean useExternal = conf.getBoolean(EXTERNAL_BLOCKCACHE_KEY, EXTERNAL_BLOCKCACHE_DEFAULT); // otherwise use the bucket cache.
boolean combinedWithLru = conf.getBoolean(BUCKET_CACHE_COMBINED_KEY, L2_CACHE_INSTANCE = getBucketCache(conf);
DEFAULT_BUCKET_CACHE_COMBINED); if (!conf.getBoolean("hbase.bucketcache.combinedcache.enabled", true)) {
if (useExternal) { // Non combined mode is off from 2.0
GLOBAL_BLOCK_CACHE_INSTANCE = new InclusiveCombinedBlockCache(l1, l2); LOG.warn(
} else { "From HBase 2.0 onwards only combined mode of LRU cache and bucket cache is available");
if (combinedWithLru) {
GLOBAL_BLOCK_CACHE_INSTANCE = new CombinedBlockCache(l1, l2);
} else {
// L1 and L2 are not 'combined'. They are connected via the LruBlockCache victimhandler
// mechanism. It is a little ugly but works according to the following: when the
// background eviction thread runs, blocks evicted from L1 will go to L2 AND when we get
// a block from the L1 cache, if not in L1, we will search L2.
GLOBAL_BLOCK_CACHE_INSTANCE = l1;
}
} }
l1.setVictimCache(l2); GLOBAL_BLOCK_CACHE_INSTANCE = L2_CACHE_INSTANCE == null ? onHeapCache
: new CombinedBlockCache(onHeapCache, L2_CACHE_INSTANCE);
} }
return GLOBAL_BLOCK_CACHE_INSTANCE; return GLOBAL_BLOCK_CACHE_INSTANCE;
} }
@ -736,8 +675,8 @@ public class CacheConfig {
// Supposed to use only from tests. Some tests want to reinit the Global block cache instance // Supposed to use only from tests. Some tests want to reinit the Global block cache instance
@VisibleForTesting @VisibleForTesting
static synchronized void clearGlobalInstances() { static synchronized void clearGlobalInstances() {
GLOBAL_L1_CACHE_INSTANCE = null; ONHEAP_CACHE_INSTANCE = null;
GLOBAL_L2_CACHE_INSTANCE = null; L2_CACHE_INSTANCE = null;
GLOBAL_BLOCK_CACHE_INSTANCE = null; GLOBAL_BLOCK_CACHE_INSTANCE = null;
} }
} }

View File

@ -31,23 +31,21 @@ import org.apache.hadoop.hbase.shaded.com.google.common.annotations.VisibleForTe
/** /**
* CombinedBlockCache is an abstraction layer that combines * CombinedBlockCache is an abstraction layer that combines
* {@link LruBlockCache} and {@link BucketCache}. The smaller lruCache is used * {@link LruBlockCache} and {@link BucketCache}. The smaller lruCache is used
* to cache bloom blocks and index blocks. The larger l2Cache is used to * to cache bloom blocks and index blocks. The larger Cache is used to
* cache data blocks. {@link #getBlock(BlockCacheKey, boolean, boolean, boolean)} reads * cache data blocks. {@link #getBlock(BlockCacheKey, boolean, boolean, boolean)} reads
* first from the smaller lruCache before looking for the block in the l2Cache. Blocks evicted * first from the smaller lruCache before looking for the block in the l2Cache.
* from lruCache are put into the bucket cache.
* Metrics are the combined size and hits and misses of both caches. * Metrics are the combined size and hits and misses of both caches.
*
*/ */
@InterfaceAudience.Private @InterfaceAudience.Private
public class CombinedBlockCache implements ResizableBlockCache, HeapSize { public class CombinedBlockCache implements ResizableBlockCache, HeapSize {
protected final LruBlockCache lruCache; protected final LruBlockCache onHeapCache;
protected final BlockCache l2Cache; protected final BlockCache l2Cache;
protected final CombinedCacheStats combinedCacheStats; protected final CombinedCacheStats combinedCacheStats;
public CombinedBlockCache(LruBlockCache lruCache, BlockCache l2Cache) { public CombinedBlockCache(LruBlockCache onHeapCache, BlockCache l2Cache) {
this.lruCache = lruCache; this.onHeapCache = onHeapCache;
this.l2Cache = l2Cache; this.l2Cache = l2Cache;
this.combinedCacheStats = new CombinedCacheStats(lruCache.getStats(), this.combinedCacheStats = new CombinedCacheStats(onHeapCache.getStats(),
l2Cache.getStats()); l2Cache.getStats());
} }
@ -57,23 +55,22 @@ public class CombinedBlockCache implements ResizableBlockCache, HeapSize {
if (l2Cache instanceof HeapSize) { if (l2Cache instanceof HeapSize) {
l2size = ((HeapSize) l2Cache).heapSize(); l2size = ((HeapSize) l2Cache).heapSize();
} }
return lruCache.heapSize() + l2size; return onHeapCache.heapSize() + l2size;
} }
@Override @Override
public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory, public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory) {
final boolean cacheDataInL1) {
boolean metaBlock = buf.getBlockType().getCategory() != BlockCategory.DATA; boolean metaBlock = buf.getBlockType().getCategory() != BlockCategory.DATA;
if (metaBlock || cacheDataInL1) { if (metaBlock) {
lruCache.cacheBlock(cacheKey, buf, inMemory, cacheDataInL1); onHeapCache.cacheBlock(cacheKey, buf, inMemory);
} else { } else {
l2Cache.cacheBlock(cacheKey, buf, inMemory, false); l2Cache.cacheBlock(cacheKey, buf, inMemory);
} }
} }
@Override @Override
public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf) { public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf) {
cacheBlock(cacheKey, buf, false, false); cacheBlock(cacheKey, buf, false);
} }
@Override @Override
@ -81,19 +78,21 @@ public class CombinedBlockCache implements ResizableBlockCache, HeapSize {
boolean repeat, boolean updateCacheMetrics) { boolean repeat, boolean updateCacheMetrics) {
// TODO: is there a hole here, or just awkwardness since in the lruCache getBlock // TODO: is there a hole here, or just awkwardness since in the lruCache getBlock
// we end up calling l2Cache.getBlock. // we end up calling l2Cache.getBlock.
return lruCache.containsBlock(cacheKey)? // We are not in a position to exactly look at LRU cache or BC as BlockType may not be getting
lruCache.getBlock(cacheKey, caching, repeat, updateCacheMetrics): // passed always.
return onHeapCache.containsBlock(cacheKey)?
onHeapCache.getBlock(cacheKey, caching, repeat, updateCacheMetrics):
l2Cache.getBlock(cacheKey, caching, repeat, updateCacheMetrics); l2Cache.getBlock(cacheKey, caching, repeat, updateCacheMetrics);
} }
@Override @Override
public boolean evictBlock(BlockCacheKey cacheKey) { public boolean evictBlock(BlockCacheKey cacheKey) {
return lruCache.evictBlock(cacheKey) || l2Cache.evictBlock(cacheKey); return onHeapCache.evictBlock(cacheKey) || l2Cache.evictBlock(cacheKey);
} }
@Override @Override
public int evictBlocksByHfileName(String hfileName) { public int evictBlocksByHfileName(String hfileName) {
return lruCache.evictBlocksByHfileName(hfileName) return onHeapCache.evictBlocksByHfileName(hfileName)
+ l2Cache.evictBlocksByHfileName(hfileName); + l2Cache.evictBlocksByHfileName(hfileName);
} }
@ -104,43 +103,43 @@ public class CombinedBlockCache implements ResizableBlockCache, HeapSize {
@Override @Override
public void shutdown() { public void shutdown() {
lruCache.shutdown(); onHeapCache.shutdown();
l2Cache.shutdown(); l2Cache.shutdown();
} }
@Override @Override
public long size() { public long size() {
return lruCache.size() + l2Cache.size(); return onHeapCache.size() + l2Cache.size();
} }
@Override @Override
public long getMaxSize() { public long getMaxSize() {
return lruCache.getMaxSize() + l2Cache.getMaxSize(); return onHeapCache.getMaxSize() + l2Cache.getMaxSize();
} }
@Override @Override
public long getCurrentDataSize() { public long getCurrentDataSize() {
return lruCache.getCurrentDataSize() + l2Cache.getCurrentDataSize(); return onHeapCache.getCurrentDataSize() + l2Cache.getCurrentDataSize();
} }
@Override @Override
public long getFreeSize() { public long getFreeSize() {
return lruCache.getFreeSize() + l2Cache.getFreeSize(); return onHeapCache.getFreeSize() + l2Cache.getFreeSize();
} }
@Override @Override
public long getCurrentSize() { public long getCurrentSize() {
return lruCache.getCurrentSize() + l2Cache.getCurrentSize(); return onHeapCache.getCurrentSize() + l2Cache.getCurrentSize();
} }
@Override @Override
public long getBlockCount() { public long getBlockCount() {
return lruCache.getBlockCount() + l2Cache.getBlockCount(); return onHeapCache.getBlockCount() + l2Cache.getBlockCount();
} }
@Override @Override
public long getDataBlockCount() { public long getDataBlockCount() {
return lruCache.getDataBlockCount() + l2Cache.getDataBlockCount(); return onHeapCache.getDataBlockCount() + l2Cache.getDataBlockCount();
} }
public static class CombinedCacheStats extends CacheStats { public static class CombinedCacheStats extends CacheStats {
@ -363,12 +362,12 @@ public class CombinedBlockCache implements ResizableBlockCache, HeapSize {
@Override @Override
public BlockCache[] getBlockCaches() { public BlockCache[] getBlockCaches() {
return new BlockCache [] {this.lruCache, this.l2Cache}; return new BlockCache [] {this.onHeapCache, this.l2Cache};
} }
@Override @Override
public void setMaxSize(long size) { public void setMaxSize(long size) {
this.lruCache.setMaxSize(size); this.onHeapCache.setMaxSize(size);
} }
@Override @Override
@ -379,6 +378,7 @@ public class CombinedBlockCache implements ResizableBlockCache, HeapSize {
@VisibleForTesting @VisibleForTesting
public int getRefCount(BlockCacheKey cacheKey) { public int getRefCount(BlockCacheKey cacheKey) {
return ((BucketCache) this.l2Cache).getRefCount(cacheKey); return (this.l2Cache instanceof BucketCache)
? ((BucketCache) this.l2Cache).getRefCount(cacheKey) : 0;
} }
} }

View File

@ -1408,8 +1408,7 @@ public class HFileReaderImpl implements HFile.Reader, Configurable {
// Cache the block // Cache the block
if (cacheBlock) { if (cacheBlock) {
cacheConf.getBlockCache().cacheBlock(cacheKey, metaBlock, cacheConf.getBlockCache().cacheBlock(cacheKey, metaBlock, cacheConf.isInMemory());
cacheConf.isInMemory(), this.cacheConf.isCacheDataInL1());
} }
return metaBlock; return metaBlock;
@ -1495,7 +1494,7 @@ public class HFileReaderImpl implements HFile.Reader, Configurable {
if (cacheBlock && cacheConf.shouldCacheBlockOnRead(category)) { if (cacheBlock && cacheConf.shouldCacheBlockOnRead(category)) {
cacheConf.getBlockCache().cacheBlock(cacheKey, cacheConf.getBlockCache().cacheBlock(cacheKey,
cacheConf.shouldCacheCompressed(category) ? hfileBlock : unpacked, cacheConf.shouldCacheCompressed(category) ? hfileBlock : unpacked,
cacheConf.isInMemory(), this.cacheConf.isCacheDataInL1()); cacheConf.isInMemory());
} }
if (updateCacheMetrics && hfileBlock.getBlockType().isData()) { if (updateCacheMetrics && hfileBlock.getBlockType().isData()) {

View File

@ -19,13 +19,13 @@
package org.apache.hadoop.hbase.io.hfile; package org.apache.hadoop.hbase.io.hfile;
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG) @InterfaceAudience.Private
public class InclusiveCombinedBlockCache extends CombinedBlockCache implements BlockCache { public class InclusiveCombinedBlockCache extends CombinedBlockCache {
public InclusiveCombinedBlockCache(LruBlockCache l1, BlockCache l2) { public InclusiveCombinedBlockCache(LruBlockCache l1, BlockCache l2) {
super(l1,l2); super(l1,l2);
l1.setVictimCache(l2);
} }
@Override @Override
@ -34,7 +34,7 @@ public class InclusiveCombinedBlockCache extends CombinedBlockCache implements B
// On all external cache set ups the lru should have the l2 cache set as the victimHandler // On all external cache set ups the lru should have the l2 cache set as the victimHandler
// Because of that all requests that miss inside of the lru block cache will be // Because of that all requests that miss inside of the lru block cache will be
// tried in the l2 block cache. // tried in the l2 block cache.
return lruCache.getBlock(cacheKey, caching, repeat, updateCacheMetrics); return onHeapCache.getBlock(cacheKey, caching, repeat, updateCacheMetrics);
} }
/** /**
@ -43,16 +43,21 @@ public class InclusiveCombinedBlockCache extends CombinedBlockCache implements B
* @param buf The block contents wrapped in a ByteBuffer. * @param buf The block contents wrapped in a ByteBuffer.
* @param inMemory Whether block should be treated as in-memory. This parameter is only useful for * @param inMemory Whether block should be treated as in-memory. This parameter is only useful for
* the L1 lru cache. * the L1 lru cache.
* @param cacheDataInL1 This is totally ignored.
*/ */
@Override @Override
public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory, public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory) {
final boolean cacheDataInL1) {
// This is the inclusive part of the combined block cache. // This is the inclusive part of the combined block cache.
// Every block is placed into both block caches. // Every block is placed into both block caches.
lruCache.cacheBlock(cacheKey, buf, inMemory, true); onHeapCache.cacheBlock(cacheKey, buf, inMemory);
// This assumes that insertion into the L2 block cache is either async or very fast. // This assumes that insertion into the L2 block cache is either async or very fast.
l2Cache.cacheBlock(cacheKey, buf, inMemory, true); l2Cache.cacheBlock(cacheKey, buf, inMemory);
}
@Override
public boolean evictBlock(BlockCacheKey cacheKey) {
boolean l1Result = this.onHeapCache.evictBlock(cacheKey);
boolean l2Result = this.l2Cache.evictBlock(cacheKey);
return l1Result || l2Result;
} }
} }

View File

@ -40,7 +40,6 @@ import org.apache.hadoop.conf.Configuration;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
import org.apache.hadoop.hbase.io.HeapSize; import org.apache.hadoop.hbase.io.HeapSize;
import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding; import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
import org.apache.hadoop.hbase.io.hfile.bucket.BucketCache;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.ClassSize; import org.apache.hadoop.hbase.util.ClassSize;
import org.apache.hadoop.hbase.util.HasThread; import org.apache.hadoop.hbase.util.HasThread;
@ -223,7 +222,11 @@ public class LruBlockCache implements ResizableBlockCache, HeapSize {
/** Whether in-memory hfile's data block has higher priority when evicting */ /** Whether in-memory hfile's data block has higher priority when evicting */
private boolean forceInMemory; private boolean forceInMemory;
/** Where to send victims (blocks evicted/missing from the cache) */ /**
* Where to send victims (blocks evicted/missing from the cache). This is used only when we use an
* external cache as L2.
* Note: See org.apache.hadoop.hbase.io.hfile.MemcachedBlockCache
*/
private BlockCache victimHandler = null; private BlockCache victimHandler = null;
/** /**
@ -360,9 +363,7 @@ public class LruBlockCache implements ResizableBlockCache, HeapSize {
* @param inMemory if block is in-memory * @param inMemory if block is in-memory
*/ */
@Override @Override
public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory, public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory) {
final boolean cacheDataInL1) {
if (buf.heapSize() > maxBlockSize) { if (buf.heapSize() > maxBlockSize) {
// If there are a lot of blocks that are too // If there are a lot of blocks that are too
// big this can make the logs way too noisy. // big this can make the logs way too noisy.
@ -448,7 +449,7 @@ public class LruBlockCache implements ResizableBlockCache, HeapSize {
* @param buf block buffer * @param buf block buffer
*/ */
public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf) { public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf) {
cacheBlock(cacheKey, buf, false, false); cacheBlock(cacheKey, buf, false);
} }
/** /**
@ -499,7 +500,7 @@ public class LruBlockCache implements ResizableBlockCache, HeapSize {
if (result instanceof HFileBlock && ((HFileBlock) result).usesSharedMemory()) { if (result instanceof HFileBlock && ((HFileBlock) result).usesSharedMemory()) {
result = ((HFileBlock) result).deepClone(); result = ((HFileBlock) result).deepClone();
} }
cacheBlock(cacheKey, result, /* inMemory = */ false, /* cacheData = */ true); cacheBlock(cacheKey, result, /* inMemory = */ false);
} }
return result; return result;
} }
@ -577,14 +578,7 @@ public class LruBlockCache implements ResizableBlockCache, HeapSize {
// update the stats counter. // update the stats counter.
stats.evicted(block.getCachedTime(), block.getCacheKey().isPrimary()); stats.evicted(block.getCachedTime(), block.getCacheKey().isPrimary());
if (victimHandler != null) { if (victimHandler != null) {
if (victimHandler instanceof BucketCache) { victimHandler.cacheBlock(block.getCacheKey(), block.getBuffer());
boolean wait = getCurrentSize() < acceptableSize();
boolean inMemory = block.getPriority() == BlockPriority.MEMORY;
((BucketCache) victimHandler).cacheBlockWithWait(block.getCacheKey(), block.getBuffer(),
inMemory, true, wait);
} else {
victimHandler.cacheBlock(block.getCacheKey(), block.getBuffer());
}
} }
} }
return block.heapSize(); return block.heapSize();
@ -1179,10 +1173,6 @@ public class LruBlockCache implements ResizableBlockCache, HeapSize {
return map; return map;
} }
BlockCache getVictimHandler() {
return this.victimHandler;
}
@Override @Override
@JsonIgnore @JsonIgnore
public BlockCache[] getBlockCaches() { public BlockCache[] getBlockCaches() {
@ -1190,16 +1180,4 @@ public class LruBlockCache implements ResizableBlockCache, HeapSize {
return new BlockCache[] {this, this.victimHandler}; return new BlockCache[] {this, this.victimHandler};
return null; return null;
} }
@Override
public void returnBlock(BlockCacheKey cacheKey, Cacheable block) {
// There is no SHARED type here in L1. But the block might have been served from the Victim
// handler L2 cache. (when the Combined mode = false). So just try return this block to
// L2 victim handler cache.
// Note : In case of CombinedBlockCache, we will have this victimHandler configured for L1
// cache. But CombinedBlockCache will only call returnBlock on L2 cache.
if (this.victimHandler != null) {
this.victimHandler.returnBlock(cacheKey, block);
}
}
} }

View File

@ -397,7 +397,7 @@ public class BucketCache implements BlockCache, HeapSize {
*/ */
@Override @Override
public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf) { public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf) {
cacheBlock(cacheKey, buf, false, false); cacheBlock(cacheKey, buf, false);
} }
/** /**
@ -405,12 +405,10 @@ public class BucketCache implements BlockCache, HeapSize {
* @param cacheKey block's cache key * @param cacheKey block's cache key
* @param cachedItem block buffer * @param cachedItem block buffer
* @param inMemory if block is in-memory * @param inMemory if block is in-memory
* @param cacheDataInL1
*/ */
@Override @Override
public void cacheBlock(BlockCacheKey cacheKey, Cacheable cachedItem, boolean inMemory, public void cacheBlock(BlockCacheKey cacheKey, Cacheable cachedItem, boolean inMemory) {
final boolean cacheDataInL1) { cacheBlockWithWait(cacheKey, cachedItem, inMemory, wait_when_cache);
cacheBlockWithWait(cacheKey, cachedItem, inMemory, cacheDataInL1, wait_when_cache);
} }
/** /**
@ -421,23 +419,18 @@ public class BucketCache implements BlockCache, HeapSize {
* @param wait if true, blocking wait when queue is full * @param wait if true, blocking wait when queue is full
*/ */
public void cacheBlockWithWait(BlockCacheKey cacheKey, Cacheable cachedItem, boolean inMemory, public void cacheBlockWithWait(BlockCacheKey cacheKey, Cacheable cachedItem, boolean inMemory,
boolean cacheDataInL1, boolean wait) { boolean wait) {
if (LOG.isTraceEnabled()) LOG.trace("Caching key=" + cacheKey + ", item=" + cachedItem); if (LOG.isTraceEnabled()) LOG.trace("Caching key=" + cacheKey + ", item=" + cachedItem);
if (!cacheEnabled) { if (!cacheEnabled) {
return; return;
} }
if (backingMap.containsKey(cacheKey)) { if (backingMap.containsKey(cacheKey)) {
/* Cacheable existingBlock = getBlock(cacheKey, false, false, false);
* Compare already cached block only if lruBlockCache is not used to cache data blocks if (BlockCacheUtil.compareCacheBlock(cachedItem, existingBlock) != 0) {
*/ throw new RuntimeException("Cached block contents differ, which should not have happened."
if (!cacheDataInL1) { + "cacheKey:" + cacheKey);
Cacheable existingBlock = getBlock(cacheKey, false, false, false); }
if (BlockCacheUtil.compareCacheBlock(cachedItem, existingBlock) != 0) {
throw new RuntimeException("Cached block contents differ, which should not have happened."
+ "cacheKey:" + cacheKey);
}
}
String msg = "Caching an already cached block: " + cacheKey; String msg = "Caching an already cached block: " + cacheKey;
msg += ". This is harmless and can happen in rare cases (see HBASE-8547)"; msg += ". This is harmless and can happen in rare cases (see HBASE-8547)";
LOG.warn(msg); LOG.warn(msg);

View File

@ -213,7 +213,7 @@ public class MemorySizeUtil {
* @return the number of bytes to use for LRU, negative if disabled. * @return the number of bytes to use for LRU, negative if disabled.
* @throws IllegalArgumentException if HFILE_BLOCK_CACHE_SIZE_KEY is > 1.0 * @throws IllegalArgumentException if HFILE_BLOCK_CACHE_SIZE_KEY is > 1.0
*/ */
public static long getLruCacheSize(final Configuration conf) { public static long getOnHeapCacheSize(final Configuration conf) {
float cachePercentage = conf.getFloat(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY, float cachePercentage = conf.getFloat(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY,
HConstants.HFILE_BLOCK_CACHE_SIZE_DEFAULT); HConstants.HFILE_BLOCK_CACHE_SIZE_DEFAULT);
if (cachePercentage <= 0.0001f) { if (cachePercentage <= 0.0001f) {

View File

@ -107,9 +107,9 @@ public class HeapMemoryManager {
public static HeapMemoryManager create(Configuration conf, FlushRequester memStoreFlusher, public static HeapMemoryManager create(Configuration conf, FlushRequester memStoreFlusher,
Server server, RegionServerAccounting regionServerAccounting) { Server server, RegionServerAccounting regionServerAccounting) {
ResizableBlockCache l1Cache = CacheConfig.getL1(conf); ResizableBlockCache lruCache = CacheConfig.getOnHeapCache(conf);
if (l1Cache != null) { if (lruCache != null) {
return new HeapMemoryManager(l1Cache, memStoreFlusher, server, regionServerAccounting); return new HeapMemoryManager(lruCache, memStoreFlusher, server, regionServerAccounting);
} }
return null; return null;
} }

View File

@ -153,8 +153,8 @@ class MetricsRegionServerWrapperImpl
private synchronized void initBlockCache() { private synchronized void initBlockCache() {
CacheConfig cacheConfig = this.regionServer.cacheConfig; CacheConfig cacheConfig = this.regionServer.cacheConfig;
if (cacheConfig != null) { if (cacheConfig != null) {
l1Stats = cacheConfig.getL1Stats(); l1Stats = cacheConfig.getOnHeapCacheStats();
l2Stats = cacheConfig.getL2Stats(); l2Stats = cacheConfig.getL2CacheStats();
if (this.blockCache == null) { if (this.blockCache == null) {
this.blockCache = cacheConfig.getBlockCache(); this.blockCache = cacheConfig.getBlockCache();
} }

View File

@ -1326,10 +1326,7 @@ public class AccessController implements MasterCoprocessor, RegionCoprocessor,
setBlockCacheEnabled(true). setBlockCacheEnabled(true).
setBlocksize(8 * 1024). setBlocksize(8 * 1024).
setBloomFilterType(BloomType.NONE). setBloomFilterType(BloomType.NONE).
setScope(HConstants.REPLICATION_SCOPE_LOCAL). setScope(HConstants.REPLICATION_SCOPE_LOCAL).build();
// Set cache data blocks in L1 if more than one cache tier deployed; e.g. this will
// be the case if we are using CombinedBlockCache (Bucket Cache).
setCacheDataInL1(true).build();
TableDescriptor td = TableDescriptor td =
TableDescriptorBuilder.newBuilder(AccessControlLists.ACL_TABLE_NAME). TableDescriptorBuilder.newBuilder(AccessControlLists.ACL_TABLE_NAME).
addColumnFamily(cfd).build(); addColumnFamily(cfd).build();

View File

@ -155,9 +155,6 @@ public class FSTableDescriptors implements TableDescriptors {
.setScope(HConstants.REPLICATION_SCOPE_LOCAL) .setScope(HConstants.REPLICATION_SCOPE_LOCAL)
// Disable blooms for meta. Needs work. Seems to mess w/ getClosestOrBefore. // Disable blooms for meta. Needs work. Seems to mess w/ getClosestOrBefore.
.setBloomFilterType(BloomType.NONE) .setBloomFilterType(BloomType.NONE)
// Enable cache of data blocks in L1 if more than one caching tier deployed:
// e.g. if using CombinedBlockCache (BucketCache).
.setCacheDataInL1(true)
.build()) .build())
.addColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(HConstants.REPLICATION_BARRIER_FAMILY) .addColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(HConstants.REPLICATION_BARRIER_FAMILY)
.setMaxVersions(conf.getInt(HConstants.HBASE_META_VERSIONS, .setMaxVersions(conf.getInt(HConstants.HBASE_META_VERSIONS,
@ -168,9 +165,6 @@ public class FSTableDescriptors implements TableDescriptors {
.setScope(HConstants.REPLICATION_SCOPE_LOCAL) .setScope(HConstants.REPLICATION_SCOPE_LOCAL)
// Disable blooms for meta. Needs work. Seems to mess w/ getClosestOrBefore. // Disable blooms for meta. Needs work. Seems to mess w/ getClosestOrBefore.
.setBloomFilterType(BloomType.NONE) .setBloomFilterType(BloomType.NONE)
// Enable cache of data blocks in L1 if more than one caching tier deployed:
// e.g. if using CombinedBlockCache (BucketCache).
.setCacheDataInL1(true)
.build()) .build())
.addColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(HConstants.REPLICATION_POSITION_FAMILY) .addColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(HConstants.REPLICATION_POSITION_FAMILY)
.setMaxVersions(conf.getInt(HConstants.HBASE_META_VERSIONS, .setMaxVersions(conf.getInt(HConstants.HBASE_META_VERSIONS,
@ -181,9 +175,6 @@ public class FSTableDescriptors implements TableDescriptors {
.setScope(HConstants.REPLICATION_SCOPE_LOCAL) .setScope(HConstants.REPLICATION_SCOPE_LOCAL)
// Disable blooms for meta. Needs work. Seems to mess w/ getClosestOrBefore. // Disable blooms for meta. Needs work. Seems to mess w/ getClosestOrBefore.
.setBloomFilterType(BloomType.NONE) .setBloomFilterType(BloomType.NONE)
// Enable cache of data blocks in L1 if more than one caching tier deployed:
// e.g. if using CombinedBlockCache (BucketCache).
.setCacheDataInL1(true)
.build()) .build())
.addColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(HConstants.REPLICATION_META_FAMILY) .addColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(HConstants.REPLICATION_META_FAMILY)
.setMaxVersions(conf.getInt(HConstants.HBASE_META_VERSIONS, .setMaxVersions(conf.getInt(HConstants.HBASE_META_VERSIONS,
@ -194,9 +185,6 @@ public class FSTableDescriptors implements TableDescriptors {
.setScope(HConstants.REPLICATION_SCOPE_LOCAL) .setScope(HConstants.REPLICATION_SCOPE_LOCAL)
// Disable blooms for meta. Needs work. Seems to mess w/ getClosestOrBefore. // Disable blooms for meta. Needs work. Seems to mess w/ getClosestOrBefore.
.setBloomFilterType(BloomType.NONE) .setBloomFilterType(BloomType.NONE)
// Enable cache of data blocks in L1 if more than one caching tier deployed:
// e.g. if using CombinedBlockCache (BucketCache).
.setCacheDataInL1(true)
.build()) .build())
.addColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(HConstants.TABLE_FAMILY) .addColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(HConstants.TABLE_FAMILY)
// Ten is arbitrary number. Keep versions to help debugging. // Ten is arbitrary number. Keep versions to help debugging.
@ -206,9 +194,6 @@ public class FSTableDescriptors implements TableDescriptors {
.setScope(HConstants.REPLICATION_SCOPE_LOCAL) .setScope(HConstants.REPLICATION_SCOPE_LOCAL)
// Disable blooms for meta. Needs work. Seems to mess w/ getClosestOrBefore. // Disable blooms for meta. Needs work. Seems to mess w/ getClosestOrBefore.
.setBloomFilterType(BloomType.NONE) .setBloomFilterType(BloomType.NONE)
// Enable cache of data blocks in L1 if more than one caching tier deployed:
// e.g. if using CombinedBlockCache (BucketCache).
.setCacheDataInL1(true)
.build()) .build())
.addCoprocessor("org.apache.hadoop.hbase.coprocessor.MultiRowMutationEndpoint", .addCoprocessor("org.apache.hadoop.hbase.coprocessor.MultiRowMutationEndpoint",
null, Coprocessor.PRIORITY_SYSTEM, null); null, Coprocessor.PRIORITY_SYSTEM, null);

View File

@ -27,7 +27,6 @@ import java.io.IOException;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage; import java.lang.management.MemoryUsage;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Map;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -186,7 +185,7 @@ public class TestCacheConfig {
Cacheable c = new DataCacheEntry(); Cacheable c = new DataCacheEntry();
// Do asserts on block counting. // Do asserts on block counting.
long initialBlockCount = bc.getBlockCount(); long initialBlockCount = bc.getBlockCount();
bc.cacheBlock(bck, c, cc.isInMemory(), cc.isCacheDataInL1()); bc.cacheBlock(bck, c, cc.isInMemory());
assertEquals(doubling? 2: 1, bc.getBlockCount() - initialBlockCount); assertEquals(doubling? 2: 1, bc.getBlockCount() - initialBlockCount);
bc.evictBlock(bck); bc.evictBlock(bck);
assertEquals(initialBlockCount, bc.getBlockCount()); assertEquals(initialBlockCount, bc.getBlockCount());
@ -194,7 +193,7 @@ public class TestCacheConfig {
// buffers do lazy allocation so sizes are off on first go around. // buffers do lazy allocation so sizes are off on first go around.
if (sizing) { if (sizing) {
long originalSize = bc.getCurrentSize(); long originalSize = bc.getCurrentSize();
bc.cacheBlock(bck, c, cc.isInMemory(), cc.isCacheDataInL1()); bc.cacheBlock(bck, c, cc.isInMemory());
assertTrue(bc.getCurrentSize() > originalSize); assertTrue(bc.getCurrentSize() > originalSize);
bc.evictBlock(bck); bc.evictBlock(bck);
long size = bc.getCurrentSize(); long size = bc.getCurrentSize();
@ -202,19 +201,6 @@ public class TestCacheConfig {
} }
} }
/**
* @param cc
* @param filename
* @return
*/
private long cacheDataBlock(final CacheConfig cc, final String filename) {
BlockCacheKey bck = new BlockCacheKey(filename, 0);
Cacheable c = new DataCacheEntry();
// Do asserts on block counting.
cc.getBlockCache().cacheBlock(bck, c, cc.isInMemory(), cc.isCacheDataInL1());
return cc.getBlockCache().getBlockCount();
}
@Test @Test
public void testDisableCacheDataBlock() throws IOException { public void testDisableCacheDataBlock() throws IOException {
Configuration conf = HBaseConfiguration.create(); Configuration conf = HBaseConfiguration.create();
@ -324,7 +310,7 @@ public class TestCacheConfig {
BlockCache [] bcs = cbc.getBlockCaches(); BlockCache [] bcs = cbc.getBlockCaches();
assertTrue(bcs[0] instanceof LruBlockCache); assertTrue(bcs[0] instanceof LruBlockCache);
LruBlockCache lbc = (LruBlockCache)bcs[0]; LruBlockCache lbc = (LruBlockCache)bcs[0];
assertEquals(MemorySizeUtil.getLruCacheSize(this.conf), lbc.getMaxSize()); assertEquals(MemorySizeUtil.getOnHeapCacheSize(this.conf), lbc.getMaxSize());
assertTrue(bcs[1] instanceof BucketCache); assertTrue(bcs[1] instanceof BucketCache);
BucketCache bc = (BucketCache)bcs[1]; BucketCache bc = (BucketCache)bcs[1];
// getMaxSize comes back in bytes but we specified size in MB // getMaxSize comes back in bytes but we specified size in MB
@ -342,19 +328,19 @@ public class TestCacheConfig {
// from L1 happens, it does not fail because L2 can't take the eviction because block too big. // from L1 happens, it does not fail because L2 can't take the eviction because block too big.
this.conf.setFloat(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY, 0.001f); this.conf.setFloat(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY, 0.001f);
MemoryUsage mu = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); MemoryUsage mu = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
long lruExpectedSize = MemorySizeUtil.getLruCacheSize(this.conf); long lruExpectedSize = MemorySizeUtil.getOnHeapCacheSize(this.conf);
final int bcSize = 100; final int bcSize = 100;
long bcExpectedSize = 100 * 1024 * 1024; // MB. long bcExpectedSize = 100 * 1024 * 1024; // MB.
assertTrue(lruExpectedSize < bcExpectedSize); assertTrue(lruExpectedSize < bcExpectedSize);
this.conf.setInt(HConstants.BUCKET_CACHE_SIZE_KEY, bcSize); this.conf.setInt(HConstants.BUCKET_CACHE_SIZE_KEY, bcSize);
this.conf.setBoolean(CacheConfig.BUCKET_CACHE_COMBINED_KEY, false);
CacheConfig cc = new CacheConfig(this.conf); CacheConfig cc = new CacheConfig(this.conf);
basicBlockCacheOps(cc, false, false); basicBlockCacheOps(cc, false, false);
assertTrue(cc.getBlockCache() instanceof LruBlockCache); assertTrue(cc.getBlockCache() instanceof CombinedBlockCache);
// TODO: Assert sizes allocated are right and proportions. // TODO: Assert sizes allocated are right and proportions.
LruBlockCache lbc = (LruBlockCache)cc.getBlockCache(); CombinedBlockCache cbc = (CombinedBlockCache)cc.getBlockCache();
LruBlockCache lbc = cbc.onHeapCache;
assertEquals(lruExpectedSize, lbc.getMaxSize()); assertEquals(lruExpectedSize, lbc.getMaxSize());
BlockCache bc = lbc.getVictimHandler(); BlockCache bc = cbc.l2Cache;
// getMaxSize comes back in bytes but we specified size in MB // getMaxSize comes back in bytes but we specified size in MB
assertEquals(bcExpectedSize, ((BucketCache) bc).getMaxSize()); assertEquals(bcExpectedSize, ((BucketCache) bc).getMaxSize());
// Test the L1+L2 deploy works as we'd expect with blocks evicted from L1 going to L2. // Test the L1+L2 deploy works as we'd expect with blocks evicted from L1 going to L2.
@ -362,7 +348,7 @@ public class TestCacheConfig {
long initialL2BlockCount = bc.getBlockCount(); long initialL2BlockCount = bc.getBlockCount();
Cacheable c = new DataCacheEntry(); Cacheable c = new DataCacheEntry();
BlockCacheKey bck = new BlockCacheKey("bck", 0); BlockCacheKey bck = new BlockCacheKey("bck", 0);
lbc.cacheBlock(bck, c, false, false); lbc.cacheBlock(bck, c, false);
assertEquals(initialL1BlockCount + 1, lbc.getBlockCount()); assertEquals(initialL1BlockCount + 1, lbc.getBlockCount());
assertEquals(initialL2BlockCount, bc.getBlockCount()); assertEquals(initialL2BlockCount, bc.getBlockCount());
// Force evictions by putting in a block too big. // Force evictions by putting in a block too big.
@ -381,32 +367,6 @@ public class TestCacheConfig {
// The eviction thread in lrublockcache needs to run. // The eviction thread in lrublockcache needs to run.
while (initialL1BlockCount != lbc.getBlockCount()) Threads.sleep(10); while (initialL1BlockCount != lbc.getBlockCount()) Threads.sleep(10);
assertEquals(initialL1BlockCount, lbc.getBlockCount()); assertEquals(initialL1BlockCount, lbc.getBlockCount());
long count = bc.getBlockCount();
assertTrue(initialL2BlockCount + 1 <= count);
}
/**
* Test the cacheDataInL1 flag. When set, data blocks should be cached in the l1 tier, up in
* LruBlockCache when using CombinedBlockCcahe.
*/
@Test
public void testCacheDataInL1() {
this.conf.set(HConstants.BUCKET_CACHE_IOENGINE_KEY, "offheap");
this.conf.setInt(HConstants.BUCKET_CACHE_SIZE_KEY, 100);
CacheConfig cc = new CacheConfig(this.conf);
assertTrue(cc.getBlockCache() instanceof CombinedBlockCache);
CombinedBlockCache cbc = (CombinedBlockCache)cc.getBlockCache();
// Add a data block. Should go into L2, into the Bucket Cache, not the LruBlockCache.
cacheDataBlock(cc, "1");
LruBlockCache lrubc = (LruBlockCache)cbc.getBlockCaches()[0];
assertDataBlockCount(lrubc, 0);
// Enable our test flag.
cc.setCacheDataInL1(true);
cacheDataBlock(cc, "2");
assertDataBlockCount(lrubc, 1);
cc.setCacheDataInL1(false);
cacheDataBlock(cc, "3");
assertDataBlockCount(lrubc, 1);
} }
@Test @Test
@ -416,16 +376,9 @@ public class TestCacheConfig {
c.set(CacheConfig.BUCKET_CACHE_BUCKETS_KEY, "256,512,1024,2048,4000,4096"); c.set(CacheConfig.BUCKET_CACHE_BUCKETS_KEY, "256,512,1024,2048,4000,4096");
c.setFloat(HConstants.BUCKET_CACHE_SIZE_KEY, 1024); c.setFloat(HConstants.BUCKET_CACHE_SIZE_KEY, 1024);
try { try {
CacheConfig.getL2(c); CacheConfig.getBucketCache(c);
fail("Should throw IllegalArgumentException when passing illegal value for bucket size"); fail("Should throw IllegalArgumentException when passing illegal value for bucket size");
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
} }
} }
private void assertDataBlockCount(final LruBlockCache bc, final int expected) {
Map<BlockType, Integer> blocks = bc.getBlockTypeCountsForTest();
assertEquals(expected, blocks == null? 0:
blocks.get(BlockType.DATA) == null? 0:
blocks.get(BlockType.DATA).intValue());
}
} }

View File

@ -230,7 +230,7 @@ public class TestCacheOnWrite {
new CacheConfig(blockCache, true, true, cowType.shouldBeCached(BlockType.DATA), new CacheConfig(blockCache, true, true, cowType.shouldBeCached(BlockType.DATA),
cowType.shouldBeCached(BlockType.LEAF_INDEX), cowType.shouldBeCached(BlockType.LEAF_INDEX),
cowType.shouldBeCached(BlockType.BLOOM_CHUNK), false, cacheCompressedData, cowType.shouldBeCached(BlockType.BLOOM_CHUNK), false, cacheCompressedData,
false, false, false); false, false);
} }
@After @After

View File

@ -80,7 +80,7 @@ public class TestLruBlockCache {
for (int blockIndex = 0; blockIndex < blocksPerThread || (!cache.isEvictionInProgress()); ++blockIndex) { for (int blockIndex = 0; blockIndex < blocksPerThread || (!cache.isEvictionInProgress()); ++blockIndex) {
CachedItem block = new CachedItem(hfileName, (int) blockSize, blockCount.getAndIncrement()); CachedItem block = new CachedItem(hfileName, (int) blockSize, blockCount.getAndIncrement());
boolean inMemory = Math.random() > 0.5; boolean inMemory = Math.random() > 0.5;
cache.cacheBlock(block.cacheKey, block, inMemory, false); cache.cacheBlock(block.cacheKey, block, inMemory);
} }
cache.evictBlocksByHfileName(hfileName); cache.evictBlocksByHfileName(hfileName);
} }
@ -350,7 +350,7 @@ public class TestLruBlockCache {
cache.getBlock(multiBlocks[i].cacheKey, true, false, true); cache.getBlock(multiBlocks[i].cacheKey, true, false, true);
// Add memory blocks as such // Add memory blocks as such
cache.cacheBlock(memoryBlocks[i].cacheKey, memoryBlocks[i], true, false); cache.cacheBlock(memoryBlocks[i].cacheKey, memoryBlocks[i], true);
expectedCacheSize += memoryBlocks[i].cacheBlockHeapSize(); expectedCacheSize += memoryBlocks[i].cacheBlockHeapSize();
} }
@ -385,7 +385,7 @@ public class TestLruBlockCache {
assertEquals(null, cache.getBlock(multiBlocks[0].cacheKey, true, false, true)); assertEquals(null, cache.getBlock(multiBlocks[0].cacheKey, true, false, true));
// Insert another memory block // Insert another memory block
cache.cacheBlock(memoryBlocks[3].cacheKey, memoryBlocks[3], true, false); cache.cacheBlock(memoryBlocks[3].cacheKey, memoryBlocks[3], true);
// Three evictions, three evicted. // Three evictions, three evicted.
assertEquals(3, cache.getStats().getEvictionCount()); assertEquals(3, cache.getStats().getEvictionCount());
@ -423,7 +423,7 @@ public class TestLruBlockCache {
assertEquals(null, cache.getBlock(multiBlocks[2].cacheKey, true, false, true)); assertEquals(null, cache.getBlock(multiBlocks[2].cacheKey, true, false, true));
// Cache a big memory block // Cache a big memory block
cache.cacheBlock(bigBlocks[2].cacheKey, bigBlocks[2], true, false); cache.cacheBlock(bigBlocks[2].cacheKey, bigBlocks[2], true);
// Six evictions, twelve evicted (3 new) // Six evictions, twelve evicted (3 new)
assertEquals(6, cache.getStats().getEvictionCount()); assertEquals(6, cache.getStats().getEvictionCount());
@ -478,7 +478,7 @@ public class TestLruBlockCache {
assertEquals(expectedCacheSize, cache.heapSize()); assertEquals(expectedCacheSize, cache.heapSize());
// 1. Insert a memory block, oldest single should be evicted, si:mu:me = 4:4:1 // 1. Insert a memory block, oldest single should be evicted, si:mu:me = 4:4:1
cache.cacheBlock(memoryBlocks[0].cacheKey, memoryBlocks[0], true, false); cache.cacheBlock(memoryBlocks[0].cacheKey, memoryBlocks[0], true);
// Single eviction, one block evicted // Single eviction, one block evicted
assertEquals(1, cache.getStats().getEvictionCount()); assertEquals(1, cache.getStats().getEvictionCount());
assertEquals(1, cache.getStats().getEvictedCount()); assertEquals(1, cache.getStats().getEvictedCount());
@ -486,7 +486,7 @@ public class TestLruBlockCache {
assertEquals(null, cache.getBlock(singleBlocks[0].cacheKey, true, false, true)); assertEquals(null, cache.getBlock(singleBlocks[0].cacheKey, true, false, true));
// 2. Insert another memory block, another single evicted, si:mu:me = 3:4:2 // 2. Insert another memory block, another single evicted, si:mu:me = 3:4:2
cache.cacheBlock(memoryBlocks[1].cacheKey, memoryBlocks[1], true, false); cache.cacheBlock(memoryBlocks[1].cacheKey, memoryBlocks[1], true);
// Two evictions, two evicted. // Two evictions, two evicted.
assertEquals(2, cache.getStats().getEvictionCount()); assertEquals(2, cache.getStats().getEvictionCount());
assertEquals(2, cache.getStats().getEvictedCount()); assertEquals(2, cache.getStats().getEvictedCount());
@ -494,10 +494,10 @@ public class TestLruBlockCache {
assertEquals(null, cache.getBlock(singleBlocks[1].cacheKey, true, false, true)); assertEquals(null, cache.getBlock(singleBlocks[1].cacheKey, true, false, true));
// 3. Insert 4 memory blocks, 2 single and 2 multi evicted, si:mu:me = 1:2:6 // 3. Insert 4 memory blocks, 2 single and 2 multi evicted, si:mu:me = 1:2:6
cache.cacheBlock(memoryBlocks[2].cacheKey, memoryBlocks[2], true, false); cache.cacheBlock(memoryBlocks[2].cacheKey, memoryBlocks[2], true);
cache.cacheBlock(memoryBlocks[3].cacheKey, memoryBlocks[3], true, false); cache.cacheBlock(memoryBlocks[3].cacheKey, memoryBlocks[3], true);
cache.cacheBlock(memoryBlocks[4].cacheKey, memoryBlocks[4], true, false); cache.cacheBlock(memoryBlocks[4].cacheKey, memoryBlocks[4], true);
cache.cacheBlock(memoryBlocks[5].cacheKey, memoryBlocks[5], true, false); cache.cacheBlock(memoryBlocks[5].cacheKey, memoryBlocks[5], true);
// Three evictions, three evicted. // Three evictions, three evicted.
assertEquals(6, cache.getStats().getEvictionCount()); assertEquals(6, cache.getStats().getEvictionCount());
assertEquals(6, cache.getStats().getEvictedCount()); assertEquals(6, cache.getStats().getEvictedCount());
@ -509,9 +509,9 @@ public class TestLruBlockCache {
// 4. Insert 3 memory blocks, the remaining 1 single and 2 multi evicted // 4. Insert 3 memory blocks, the remaining 1 single and 2 multi evicted
// si:mu:me = 0:0:9 // si:mu:me = 0:0:9
cache.cacheBlock(memoryBlocks[6].cacheKey, memoryBlocks[6], true, false); cache.cacheBlock(memoryBlocks[6].cacheKey, memoryBlocks[6], true);
cache.cacheBlock(memoryBlocks[7].cacheKey, memoryBlocks[7], true, false); cache.cacheBlock(memoryBlocks[7].cacheKey, memoryBlocks[7], true);
cache.cacheBlock(memoryBlocks[8].cacheKey, memoryBlocks[8], true, false); cache.cacheBlock(memoryBlocks[8].cacheKey, memoryBlocks[8], true);
// Three evictions, three evicted. // Three evictions, three evicted.
assertEquals(9, cache.getStats().getEvictionCount()); assertEquals(9, cache.getStats().getEvictionCount());
assertEquals(9, cache.getStats().getEvictedCount()); assertEquals(9, cache.getStats().getEvictedCount());
@ -522,7 +522,7 @@ public class TestLruBlockCache {
// 5. Insert one memory block, the oldest memory evicted // 5. Insert one memory block, the oldest memory evicted
// si:mu:me = 0:0:9 // si:mu:me = 0:0:9
cache.cacheBlock(memoryBlocks[9].cacheKey, memoryBlocks[9], true, false); cache.cacheBlock(memoryBlocks[9].cacheKey, memoryBlocks[9], true);
// one eviction, one evicted. // one eviction, one evicted.
assertEquals(10, cache.getStats().getEvictionCount()); assertEquals(10, cache.getStats().getEvictionCount());
assertEquals(10, cache.getStats().getEvictedCount()); assertEquals(10, cache.getStats().getEvictedCount());
@ -679,7 +679,7 @@ public class TestLruBlockCache {
cache.getBlock(multiBlocks[i].cacheKey, true, false, true); cache.getBlock(multiBlocks[i].cacheKey, true, false, true);
// Add memory blocks as such // Add memory blocks as such
cache.cacheBlock(memoryBlocks[i].cacheKey, memoryBlocks[i], true, false); cache.cacheBlock(memoryBlocks[i].cacheKey, memoryBlocks[i], true);
} }
// Do not expect any evictions yet // Do not expect any evictions yet

View File

@ -104,12 +104,11 @@ public class TestBucketCache {
} }
@Override @Override
public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory, public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory) {
boolean cacheDataInL1) {
if (super.getBlock(cacheKey, true, false, true) != null) { if (super.getBlock(cacheKey, true, false, true) != null) {
throw new RuntimeException("Cached an already cached block"); throw new RuntimeException("Cached an already cached block");
} }
super.cacheBlock(cacheKey, buf, inMemory, cacheDataInL1); super.cacheBlock(cacheKey, buf, inMemory);
} }
@Override @Override

View File

@ -645,8 +645,7 @@ public class TestHeapMemoryManager {
} }
@Override @Override
public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory, public void cacheBlock(BlockCacheKey cacheKey, Cacheable buf, boolean inMemory) {
boolean cacheDataInL1) {
} }