Skip to content

Commit eee9480

Browse files
authored
HBASE-23066 Allow cache on write during compactions when prefetching … (#935)
* HBASE-23066 Allow cache on write during compactions when prefetching is enabled * Fix checkstyle issues - recommit
1 parent ec317a6 commit eee9480

File tree

3 files changed

+100
-52
lines changed

3 files changed

+100
-52
lines changed

hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheConfig.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ public class CacheConfig {
8181
*/
8282
public static final String PREFETCH_BLOCKS_ON_OPEN_KEY = "hbase.rs.prefetchblocksonopen";
8383

84+
/**
85+
* Configuration key to cache blocks when a compacted file is written
86+
*/
87+
public static final String CACHE_COMPACTED_BLOCKS_ON_WRITE_KEY =
88+
"hbase.rs.cachecompactedblocksonwrite";
89+
8490
public static final String DROP_BEHIND_CACHE_COMPACTION_KEY =
8591
"hbase.hfile.drop.behind.compaction";
8692

@@ -93,6 +99,7 @@ public class CacheConfig {
9399
public static final boolean DEFAULT_EVICT_ON_CLOSE = false;
94100
public static final boolean DEFAULT_CACHE_DATA_COMPRESSED = false;
95101
public static final boolean DEFAULT_PREFETCH_ON_OPEN = false;
102+
public static final boolean DEFAULT_CACHE_COMPACTED_BLOCKS_ON_WRITE = false;
96103
public static final boolean DROP_BEHIND_CACHE_COMPACTION_DEFAULT = true;
97104

98105
/**
@@ -124,6 +131,11 @@ public class CacheConfig {
124131
/** Whether data blocks should be prefetched into the cache */
125132
private final boolean prefetchOnOpen;
126133

134+
/**
135+
* Whether data blocks should be cached when compacted file is written
136+
*/
137+
private final boolean cacheCompactedDataOnWrite;
138+
127139
private final boolean dropBehindCompaction;
128140

129141
// Local reference to the block cache
@@ -174,6 +186,8 @@ public CacheConfig(Configuration conf, ColumnFamilyDescriptor family, BlockCache
174186
(family == null ? false : family.isEvictBlocksOnClose());
175187
this.prefetchOnOpen = conf.getBoolean(PREFETCH_BLOCKS_ON_OPEN_KEY, DEFAULT_PREFETCH_ON_OPEN) ||
176188
(family == null ? false : family.isPrefetchBlocksOnOpen());
189+
this.cacheCompactedDataOnWrite = conf.getBoolean(CACHE_COMPACTED_BLOCKS_ON_WRITE_KEY,
190+
DEFAULT_CACHE_COMPACTED_BLOCKS_ON_WRITE);
177191
this.blockCache = blockCache;
178192
this.byteBuffAllocator = byteBuffAllocator;
179193
LOG.info("Created cacheConfig: " + this + (family == null ? "" : " for family " + family) +
@@ -193,6 +207,7 @@ public CacheConfig(CacheConfig cacheConf) {
193207
this.evictOnClose = cacheConf.evictOnClose;
194208
this.cacheDataCompressed = cacheConf.cacheDataCompressed;
195209
this.prefetchOnOpen = cacheConf.prefetchOnOpen;
210+
this.cacheCompactedDataOnWrite = cacheConf.cacheCompactedDataOnWrite;
196211
this.dropBehindCompaction = cacheConf.dropBehindCompaction;
197212
this.blockCache = cacheConf.blockCache;
198213
this.byteBuffAllocator = cacheConf.byteBuffAllocator;
@@ -207,6 +222,7 @@ private CacheConfig() {
207222
this.evictOnClose = false;
208223
this.cacheDataCompressed = false;
209224
this.prefetchOnOpen = false;
225+
this.cacheCompactedDataOnWrite = false;
210226
this.dropBehindCompaction = false;
211227
this.blockCache = null;
212228
this.byteBuffAllocator = ByteBuffAllocator.HEAP;
@@ -319,6 +335,13 @@ public boolean shouldPrefetchOnOpen() {
319335
return this.prefetchOnOpen;
320336
}
321337

338+
/**
339+
* @return true if blocks should be cached while writing during compaction, false if not
340+
*/
341+
public boolean shouldCacheCompactedBlocksOnWrite() {
342+
return this.cacheCompactedDataOnWrite;
343+
}
344+
322345
/**
323346
* Return true if we may find this type of block in block cache.
324347
* <p>

hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HStore.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,9 +1118,9 @@ public StoreFileWriter createWriterInTmp(long maxKeyCount, Compression.Algorithm
11181118
boolean shouldDropBehind) throws IOException {
11191119
final CacheConfig writerCacheConf;
11201120
if (isCompaction) {
1121-
// Don't cache data on write on compactions.
1121+
// Don't cache data on write on compactions, unless specifically configured to do so
11221122
writerCacheConf = new CacheConfig(cacheConf);
1123-
writerCacheConf.setCacheDataOnWrite(false);
1123+
writerCacheConf.setCacheDataOnWrite(cacheConf.shouldCacheCompactedBlocksOnWrite());
11241124
} else {
11251125
writerCacheConf = cacheConf;
11261126
}

hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestCacheOnWrite.java

Lines changed: 75 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -405,59 +405,84 @@ private void writeStoreFile(boolean useTags) throws IOException {
405405
storeFilePath = sfw.getPath();
406406
}
407407

408-
private void testNotCachingDataBlocksDuringCompactionInternals(boolean useTags)
409-
throws IOException, InterruptedException {
410-
// TODO: need to change this test if we add a cache size threshold for
411-
// compactions, or if we implement some other kind of intelligent logic for
412-
// deciding what blocks to cache-on-write on compaction.
413-
final String table = "CompactionCacheOnWrite";
414-
final String cf = "myCF";
415-
final byte[] cfBytes = Bytes.toBytes(cf);
416-
final int maxVersions = 3;
417-
ColumnFamilyDescriptor cfd =
418-
ColumnFamilyDescriptorBuilder.newBuilder(cfBytes).setCompressionType(compress)
419-
.setBloomFilterType(BLOOM_TYPE).setMaxVersions(maxVersions)
420-
.setDataBlockEncoding(NoOpDataBlockEncoder.INSTANCE.getDataBlockEncoding()).build();
421-
HRegion region = TEST_UTIL.createTestRegion(table, cfd, blockCache);
422-
int rowIdx = 0;
423-
long ts = EnvironmentEdgeManager.currentTime();
424-
for (int iFile = 0; iFile < 5; ++iFile) {
425-
for (int iRow = 0; iRow < 500; ++iRow) {
426-
String rowStr = "" + (rowIdx * rowIdx * rowIdx) + "row" + iFile + "_" +
427-
iRow;
428-
Put p = new Put(Bytes.toBytes(rowStr));
429-
++rowIdx;
430-
for (int iCol = 0; iCol < 10; ++iCol) {
431-
String qualStr = "col" + iCol;
432-
String valueStr = "value_" + rowStr + "_" + qualStr;
433-
for (int iTS = 0; iTS < 5; ++iTS) {
434-
if (useTags) {
435-
Tag t = new ArrayBackedTag((byte) 1, "visibility");
436-
Tag[] tags = new Tag[1];
437-
tags[0] = t;
438-
KeyValue kv = new KeyValue(Bytes.toBytes(rowStr), cfBytes, Bytes.toBytes(qualStr),
439-
HConstants.LATEST_TIMESTAMP, Bytes.toBytes(valueStr), tags);
440-
p.add(kv);
441-
} else {
442-
p.addColumn(cfBytes, Bytes.toBytes(qualStr), ts++, Bytes.toBytes(valueStr));
408+
private void testCachingDataBlocksDuringCompactionInternals(boolean useTags,
409+
boolean cacheBlocksOnCompaction) throws IOException, InterruptedException {
410+
// create a localConf
411+
boolean localValue = conf.getBoolean(CacheConfig.CACHE_COMPACTED_BLOCKS_ON_WRITE_KEY,
412+
false);
413+
try {
414+
// Set the conf if testing caching compacted blocks on write
415+
conf.setBoolean(CacheConfig.CACHE_COMPACTED_BLOCKS_ON_WRITE_KEY,
416+
cacheBlocksOnCompaction);
417+
418+
// TODO: need to change this test if we add a cache size threshold for
419+
// compactions, or if we implement some other kind of intelligent logic for
420+
// deciding what blocks to cache-on-write on compaction.
421+
final String table = "CompactionCacheOnWrite";
422+
final String cf = "myCF";
423+
final byte[] cfBytes = Bytes.toBytes(cf);
424+
final int maxVersions = 3;
425+
ColumnFamilyDescriptor cfd = ColumnFamilyDescriptorBuilder.newBuilder(cfBytes)
426+
.setCompressionType(compress).setBloomFilterType(BLOOM_TYPE).setMaxVersions(maxVersions)
427+
.setDataBlockEncoding(NoOpDataBlockEncoder.INSTANCE.getDataBlockEncoding()).build();
428+
HRegion region = TEST_UTIL.createTestRegion(table, cfd, blockCache);
429+
int rowIdx = 0;
430+
long ts = EnvironmentEdgeManager.currentTime();
431+
for (int iFile = 0; iFile < 5; ++iFile) {
432+
for (int iRow = 0; iRow < 500; ++iRow) {
433+
String rowStr = "" + (rowIdx * rowIdx * rowIdx) + "row" + iFile + "_" + iRow;
434+
Put p = new Put(Bytes.toBytes(rowStr));
435+
++rowIdx;
436+
for (int iCol = 0; iCol < 10; ++iCol) {
437+
String qualStr = "col" + iCol;
438+
String valueStr = "value_" + rowStr + "_" + qualStr;
439+
for (int iTS = 0; iTS < 5; ++iTS) {
440+
if (useTags) {
441+
Tag t = new ArrayBackedTag((byte) 1, "visibility");
442+
Tag[] tags = new Tag[1];
443+
tags[0] = t;
444+
KeyValue kv = new KeyValue(Bytes.toBytes(rowStr), cfBytes, Bytes.toBytes(qualStr),
445+
HConstants.LATEST_TIMESTAMP, Bytes.toBytes(valueStr), tags);
446+
p.add(kv);
447+
} else {
448+
p.addColumn(cfBytes, Bytes.toBytes(qualStr), ts++, Bytes.toBytes(valueStr));
449+
}
443450
}
444451
}
452+
p.setDurability(Durability.ASYNC_WAL);
453+
region.put(p);
454+
}
455+
region.flush(true);
456+
}
457+
458+
clearBlockCache(blockCache);
459+
assertEquals(0, blockCache.getBlockCount());
460+
461+
region.compact(false);
462+
LOG.debug("compactStores() returned");
463+
464+
boolean dataBlockCached = false;
465+
for (CachedBlock block : blockCache) {
466+
if (BlockType.ENCODED_DATA.equals(block.getBlockType())
467+
|| BlockType.DATA.equals(block.getBlockType())) {
468+
dataBlockCached = true;
469+
break;
445470
}
446-
p.setDurability(Durability.ASYNC_WAL);
447-
region.put(p);
448471
}
449-
region.flush(true);
450-
}
451-
clearBlockCache(blockCache);
452-
assertEquals(0, blockCache.getBlockCount());
453-
region.compact(false);
454-
LOG.debug("compactStores() returned");
455472

456-
for (CachedBlock block: blockCache) {
457-
assertNotEquals(BlockType.ENCODED_DATA, block.getBlockType());
458-
assertNotEquals(BlockType.DATA, block.getBlockType());
473+
// Data blocks should be cached in instances where we are caching blocks on write. In the case
474+
// of testing
475+
// BucketCache, we cannot verify block type as it is not stored in the cache.
476+
assertTrue(
477+
"\nTest description: " + testDescription + "\ncacheBlocksOnCompaction: "
478+
+ cacheBlocksOnCompaction + "\n",
479+
(cacheBlocksOnCompaction && !(blockCache instanceof BucketCache)) == dataBlockCached);
480+
481+
region.close();
482+
} finally {
483+
// reset back
484+
conf.setBoolean(CacheConfig.CACHE_COMPACTED_BLOCKS_ON_WRITE_KEY, localValue);
459485
}
460-
region.close();
461486
}
462487

463488
@Test
@@ -467,8 +492,8 @@ public void testStoreFileCacheOnWrite() throws IOException {
467492
}
468493

469494
@Test
470-
public void testNotCachingDataBlocksDuringCompaction() throws IOException, InterruptedException {
471-
testNotCachingDataBlocksDuringCompactionInternals(false);
472-
testNotCachingDataBlocksDuringCompactionInternals(true);
495+
public void testCachingDataBlocksDuringCompaction() throws IOException, InterruptedException {
496+
testCachingDataBlocksDuringCompactionInternals(false, false);
497+
testCachingDataBlocksDuringCompactionInternals(true, true);
473498
}
474499
}

0 commit comments

Comments
 (0)