From 546907462869d2107c270707de962f4700eb3aa9 Mon Sep 17 00:00:00 2001 From: chenheng Date: Wed, 19 Aug 2015 16:51:22 +0800 Subject: [PATCH] HBASE-14189 BlockCache options should consider CF Level BlockCacheEnabled setting --- .../org/apache/hadoop/hbase/HColumnDescriptor.java | 23 +++++++ .../apache/hadoop/hbase/io/hfile/CacheConfig.java | 75 ++++++++++++---------- .../hadoop/hbase/io/hfile/TestCacheOnWrite.java | 2 +- 3 files changed, 64 insertions(+), 36 deletions(-) diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/HColumnDescriptor.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/HColumnDescriptor.java index 4daf6ef..915c6b9 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/HColumnDescriptor.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/HColumnDescriptor.java @@ -79,10 +79,12 @@ public class HColumnDescriptor implements Comparable { * disabled. */ public static final String BLOCKCACHE = "BLOCKCACHE"; + public static final String CACHE_DATA_ON_READ = "CACHE_DATA_ON_READ"; public static final String CACHE_DATA_ON_WRITE = "CACHE_DATA_ON_WRITE"; public static final String CACHE_INDEX_ON_WRITE = "CACHE_INDEX_ON_WRITE"; public static final String CACHE_BLOOMS_ON_WRITE = "CACHE_BLOOMS_ON_WRITE"; public static final String EVICT_BLOCKS_ON_CLOSE = "EVICT_BLOCKS_ON_CLOSE"; + public static final String CACHE_DATA_BLOCKS_COMPRESSED = "CACHE_DATA_BLOCKS_COMPRESSED"; /** * 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: @@ -182,6 +184,7 @@ public class HColumnDescriptor implements Comparable { */ public static final boolean DEFAULT_BLOCKCACHE = true; + public static final boolean DEFAULT_CACHE_DATA_ON_READ = true; /** * Default setting for whether to cache data blocks on write if block caching * is enabled. @@ -201,6 +204,8 @@ public class HColumnDescriptor implements Comparable { */ public static final boolean DEFAULT_CACHE_INDEX_ON_WRITE = false; + public static final boolean DEFAULT_CACHE_DATA_BLOCKS_COMPRESSED = false; + /** * Default size of blocks in files stored to the filesytem (hfiles). */ @@ -260,12 +265,15 @@ public class HColumnDescriptor implements Comparable { DEFAULT_VALUES.put(BLOCKCACHE, String.valueOf(DEFAULT_BLOCKCACHE)); 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(CACHE_DATA_ON_READ, String.valueOf(DEFAULT_CACHE_DATA_ON_READ)); 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_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(PREFETCH_BLOCKS_ON_OPEN, String.valueOf(DEFAULT_PREFETCH_BLOCKS_ON_OPEN)); + DEFAULT_VALUES.put(CACHE_DATA_BLOCKS_COMPRESSED, + String.valueOf(DEFAULT_CACHE_DATA_BLOCKS_COMPRESSED)); for (String s : DEFAULT_VALUES.keySet()) { RESERVED_KEYWORDS.add(new Bytes(Bytes.toBytes(s))); } @@ -809,6 +817,13 @@ public class HColumnDescriptor implements Comparable { return setAndGetBoolean(CACHE_DATA_ON_WRITE, DEFAULT_CACHE_DATA_ON_WRITE); } + public boolean isCacheDataOnRead() { + return setAndGetBoolean(CACHE_DATA_ON_READ, DEFAULT_CACHE_DATA_ON_READ); + } + + public boolean isCacheDataBlockCompressed() { + return setAndGetBoolean(CACHE_DATA_BLOCKS_COMPRESSED, DEFAULT_CACHE_DATA_BLOCKS_COMPRESSED); + } /** * @param value true if we should cache data blocks on write * @return this (for chained invocation) @@ -817,6 +832,14 @@ public class HColumnDescriptor implements Comparable { return setValue(CACHE_DATA_ON_WRITE, Boolean.toString(value)); } + public HColumnDescriptor setCacheDataOnRead(boolean value) { + return setValue(CACHE_DATA_ON_READ, Boolean.toString(value)); + } + + public HColumnDescriptor setCacheDataBlockCompressed(boolean value) { + return setValue(CACHE_DATA_BLOCKS_COMPRESSED, Boolean.toString(value)); + } + /** * @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). diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheConfig.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheConfig.java index 7b4f530..e3b335f 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheConfig.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheConfig.java @@ -148,6 +148,7 @@ public class CacheConfig { } // Defaults + public static final boolean DEFAULT_CF_BLOCKCACHE_OPENED = true; public static final boolean DEFAULT_CACHE_DATA_ON_READ = true; public static final boolean DEFAULT_CACHE_DATA_ON_WRITE = false; public static final boolean DEFAULT_IN_MEMORY = false; @@ -160,6 +161,9 @@ public class CacheConfig { /** Local reference to the block cache, null if completely disabled */ private final BlockCache blockCache; + /** Block cache is opend on CF Level */ + private boolean cfBlockCacheEnabled; + /** * Whether blocks should be cached on read (default is on if there is a * cache but this can be turned off on a per-family or per-request basis). @@ -207,6 +211,7 @@ public class CacheConfig { public CacheConfig(Configuration conf, HColumnDescriptor family) { this(CacheConfig.instantiateBlockCache(conf), family.isBlockCacheEnabled(), + family.isCacheDataOnRead(), family.isInMemory(), // For the following flags we enable them regardless of per-schema settings // if they are enabled in the global configuration. @@ -218,7 +223,8 @@ public class CacheConfig { DEFAULT_CACHE_BLOOMS_ON_WRITE) || family.isCacheBloomsOnWrite(), conf.getBoolean(EVICT_BLOCKS_ON_CLOSE_KEY, DEFAULT_EVICT_ON_CLOSE) || family.isEvictBlocksOnClose(), - conf.getBoolean(CACHE_DATA_BLOCKS_COMPRESSED_KEY, DEFAULT_CACHE_DATA_COMPRESSED), + conf.getBoolean(CACHE_DATA_BLOCKS_COMPRESSED_KEY, DEFAULT_CACHE_DATA_COMPRESSED) || + family.isCacheDataBlockCompressed(), conf.getBoolean(PREFETCH_BLOCKS_ON_OPEN_KEY, DEFAULT_PREFETCH_ON_OPEN) || family.isPrefetchBlocksOnOpen(), conf.getBoolean(HColumnDescriptor.CACHE_DATA_IN_L1, @@ -234,6 +240,7 @@ public class CacheConfig { */ public CacheConfig(Configuration conf) { this(CacheConfig.instantiateBlockCache(conf), + DEFAULT_CF_BLOCKCACHE_OPENED, DEFAULT_CACHE_DATA_ON_READ, DEFAULT_IN_MEMORY, // This is a family-level setting so can't be set // strictly from conf @@ -265,13 +272,14 @@ public class CacheConfig { * @param cacheDataInL1 If more than one cache tier deployed, if true, cache this column families * data blocks up in the L1 tier. */ - CacheConfig(final BlockCache blockCache, + CacheConfig(final BlockCache blockCache, final boolean cfBlockCacheEnabled, final boolean cacheDataOnRead, final boolean inMemory, final boolean cacheDataOnWrite, final boolean cacheIndexesOnWrite, final boolean cacheBloomsOnWrite, final boolean evictOnClose, final boolean cacheDataCompressed, final boolean prefetchOnOpen, final boolean cacheDataInL1, final boolean dropBehindCompaction) { this.blockCache = blockCache; + this.cfBlockCacheEnabled = cfBlockCacheEnabled; this.cacheDataOnRead = cacheDataOnRead; this.inMemory = inMemory; this.cacheDataOnWrite = cacheDataOnWrite; @@ -290,10 +298,11 @@ public class CacheConfig { * @param cacheConf */ public CacheConfig(CacheConfig cacheConf) { - this(cacheConf.blockCache, cacheConf.cacheDataOnRead, cacheConf.inMemory, - cacheConf.cacheDataOnWrite, cacheConf.cacheIndexesOnWrite, - cacheConf.cacheBloomsOnWrite, cacheConf.evictOnClose, - cacheConf.cacheDataCompressed, cacheConf.prefetchOnOpen, + this(cacheConf.blockCache, cacheConf.cfBlockCacheEnabled, + cacheConf.cacheDataOnRead, cacheConf.inMemory, + cacheConf.cacheDataOnWrite, cacheConf.cacheIndexesOnWrite, + cacheConf.cacheBloomsOnWrite, cacheConf.evictOnClose, + cacheConf.cacheDataCompressed, cacheConf.prefetchOnOpen, cacheConf.cacheDataInL1, cacheConf.dropBehindCompaction); } @@ -304,6 +313,10 @@ public class CacheConfig { return this.blockCache != null; } + public boolean isCfBlockCacheEnabled() { + return isBlockCacheEnabled() && cfBlockCacheEnabled; + } + /** * Returns the block cache. * @return the block cache, or null if caching is completely disabled @@ -331,27 +344,31 @@ public class CacheConfig { * available. */ public boolean shouldCacheBlockOnRead(BlockCategory category) { - return isBlockCacheEnabled() - && (cacheDataOnRead || - category == BlockCategory.INDEX || + if (!isBlockCacheEnabled()) { + return false; + } + if (category == BlockCategory.INDEX || category == BlockCategory.BLOOM || (prefetchOnOpen && - (category != BlockCategory.META && - category != BlockCategory.UNKNOWN))); + (category != BlockCategory.META && + category != BlockCategory.UNKNOWN))) { + return true; + } + return shouldCacheDataOnRead(); } /** * @return true if blocks in this file should be flagged as in-memory */ public boolean isInMemory() { - return isBlockCacheEnabled() && this.inMemory; + return isCfBlockCacheEnabled() && 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 isCfBlockCacheEnabled() && this.cacheDataInL1; } /** @@ -359,7 +376,7 @@ public class CacheConfig { * written, false if not */ public boolean shouldCacheDataOnWrite() { - return isBlockCacheEnabled() && this.cacheDataOnWrite; + return isCfBlockCacheEnabled() && this.cacheDataOnWrite; } /** @@ -387,7 +404,7 @@ public class CacheConfig { * is written, false if not */ public boolean shouldCacheIndexesOnWrite() { - return isBlockCacheEnabled() && this.cacheIndexesOnWrite; + return isCfBlockCacheEnabled() && this.cacheIndexesOnWrite; } /** @@ -395,7 +412,7 @@ public class CacheConfig { * is written, false if not */ public boolean shouldCacheBloomsOnWrite() { - return isBlockCacheEnabled() && this.cacheBloomsOnWrite; + return isCfBlockCacheEnabled() && this.cacheBloomsOnWrite; } /** @@ -403,7 +420,7 @@ public class CacheConfig { * reader is closed, false if not */ public boolean shouldEvictOnClose() { - return isBlockCacheEnabled() && this.evictOnClose; + return isCfBlockCacheEnabled() && this.evictOnClose; } /** @@ -419,14 +436,14 @@ public class CacheConfig { * @return true if data blocks should be compressed in the cache, false if not */ public boolean shouldCacheDataCompressed() { - return isBlockCacheEnabled() && this.cacheDataCompressed; + return isCfBlockCacheEnabled() && this.cacheDataCompressed; } /** * @return true if this {@link BlockCategory} should be compressed in blockcache, false otherwise */ public boolean shouldCacheCompressed(BlockCategory category) { - if (!isBlockCacheEnabled()) return false; + if (!isCfBlockCacheEnabled()) return false; switch (category) { case DATA: return this.cacheDataCompressed; @@ -439,30 +456,17 @@ public class CacheConfig { * @return true if blocks should be prefetched into the cache on open, false if not */ public boolean shouldPrefetchOnOpen() { - return isBlockCacheEnabled() && this.prefetchOnOpen; + return isCfBlockCacheEnabled() && this.prefetchOnOpen; } /** * Return true if we may find this type of block in block cache. - *

- * TODO: today {@code family.isBlockCacheEnabled()} only means {@code cacheDataOnRead}, so here we - * consider lots of other configurations such as {@code cacheDataOnWrite}. We should fix this in - * the future, {@code cacheDataOnWrite} should honor the CF level {@code isBlockCacheEnabled} - * configuration. */ public boolean shouldReadBlockFromCache(BlockType blockType) { if (!isBlockCacheEnabled()) { return false; } - if (cacheDataOnRead) { - return true; - } - if (prefetchOnOpen) { - return true; - } - if (cacheDataOnWrite) { - return true; - } + //special blockType should skip CF BC checking. if (blockType == null) { return true; } @@ -470,7 +474,7 @@ public class CacheConfig { blockType.getCategory() == BlockCategory.INDEX) { return true; } - return false; + return isCfBlockCacheEnabled(); } /** @@ -490,6 +494,7 @@ public class CacheConfig { return "CacheConfig:disabled"; } return "blockCache=" + getBlockCache() + + ", cfBlockCacheEnabled=" + isCfBlockCacheEnabled() + ", cacheDataOnRead=" + shouldCacheDataOnRead() + ", cacheDataOnWrite=" + shouldCacheDataOnWrite() + ", cacheIndexesOnWrite=" + shouldCacheIndexesOnWrite() + diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestCacheOnWrite.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestCacheOnWrite.java index bfa5b87..9f0b968 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestCacheOnWrite.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestCacheOnWrite.java @@ -254,7 +254,7 @@ public class TestCacheOnWrite { fs = HFileSystem.get(conf); CacheConfig.GLOBAL_BLOCK_CACHE_INSTANCE = blockCache; cacheConf = - new CacheConfig(blockCache, true, true, cowType.shouldBeCached(BlockType.DATA), + new CacheConfig(blockCache, true, true, true, cowType.shouldBeCached(BlockType.DATA), cowType.shouldBeCached(BlockType.LEAF_INDEX), cowType.shouldBeCached(BlockType.BLOOM_CHUNK), false, cacheCompressedData, false, false, false); -- 1.9.3 (Apple Git-50)