Skip to content

Commit 5441716

Browse files
committed
HBASE-28292 Make Delay prefetch property to be dynamically configured
1 parent 6106ec4 commit 5441716

3 files changed

Lines changed: 16 additions & 30 deletions

File tree

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,6 +1659,11 @@ public boolean prefetchComplete() {
16591659
return PrefetchExecutor.isCompleted(path);
16601660
}
16611661

1662+
/**
1663+
* Returns true if block prefetching was started after waiting for specified delay, false
1664+
* otherwise
1665+
*/
1666+
@Override
16621667
public boolean prefetchStarted() {
16631668
return PrefetchExecutor.isPrefetchStarted();
16641669
}

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

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,6 @@ public Thread newThread(Runnable r) {
8888
+ Path.SEPARATOR_CHAR + ")|(" + Path.SEPARATOR_CHAR
8989
+ HConstants.HREGION_COMPACTIONDIR_NAME.replace(".", "\\.") + Path.SEPARATOR_CHAR + ")");
9090

91-
// For tests. Contains computed prefetch delay
92-
private static long computedPrefetchDelay;
93-
9491
public static void request(Path path, Runnable runnable) {
9592
if (!prefetchPathExclude.matcher(path.toString()).find()) {
9693
long delay;
@@ -102,7 +99,6 @@ public static void request(Path path, Runnable runnable) {
10299
delay = 0;
103100
}
104101
try {
105-
computedPrefetchDelay = delay;
106102
LOG.debug("Prefetch requested for {}, delay={} ms", path, delay);
107103
final Runnable tracedRunnable =
108104
TraceUtil.tracedRunnable(runnable, "PrefetchExecutor.request");
@@ -165,13 +161,6 @@ static ScheduledExecutorService getExecutorPool() {
165161
return prefetchExecutorPool;
166162
}
167163

168-
/* Visible for testing only */
169-
@RestrictedApi(explanation = "Should only be called in tests. This is a non thread safe "
170-
+ "variable that would not yield accurate values when multiple readers created and "
171-
+ "calling PrefetchExecutor.request concurrently", link = "",
172-
allowedOnPath = ".*/src/test/.*")
173-
public static long getComputedPrefetchDelay() {return computedPrefetchDelay;}
174-
175164
@RestrictedApi(explanation = "Should only be called in tests", link = "",
176165
allowedOnPath = ".*/src/test/.*")
177166
static Map<Path, Future<?>> getPrefetchFutures() {
@@ -208,9 +197,10 @@ public static int getPrefetchDelay() {
208197
public static void loadConfiguration(Configuration conf) {
209198
prefetchDelayMillis = conf.getInt(PREFETCH_DELAY, 1000);
210199
prefetchFutures.forEach((k, v) -> {
211-
// Do not cancel the task which is about to complete
212200
ScheduledFuture sf = (ScheduledFuture) prefetchFutures.get(k);
213-
if (sf.getDelay(TimeUnit.MILLISECONDS) > prefetchDelayMillis) {
201+
if (!(sf.getDelay(TimeUnit.MILLISECONDS) > 0)) {
202+
//the thread is still pending delay expiration and has not started to run yet, so can be
203+
// re-scheduled at no cost.
214204
interrupt(k);
215205
request(k, prefetchRunnable.get(k));
216206
}

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

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import static org.apache.hadoop.hbase.client.trace.hamcrest.SpanDataMatchers.hasParentSpanId;
2222
import static org.apache.hadoop.hbase.io.hfile.CacheConfig.CACHE_DATA_BLOCKS_COMPRESSED_KEY;
2323
import static org.apache.hadoop.hbase.io.hfile.PrefetchExecutor.PREFETCH_DELAY;
24-
import static org.apache.hadoop.hbase.io.hfile.PrefetchExecutor.getComputedPrefetchDelay;
2524
import static org.apache.hadoop.hbase.regionserver.CompactSplit.HBASE_REGION_SERVER_ENABLE_COMPACTION;
2625
import static org.hamcrest.MatcherAssert.assertThat;
2726
import static org.hamcrest.Matchers.allOf;
@@ -101,7 +100,6 @@ public class TestPrefetch {
101100
private static final int NUM_KV = 1000;
102101

103102
private long startTime;
104-
private long endTime;
105103
private boolean measureTiming;
106104

107105

@@ -314,11 +312,14 @@ private void readStoreFile(Path storeFilePath,
314312
// if prefetchFutures contains entry (which means it's not cancelled or completed)
315313
// and wait time remaining is below delay expiry watermark, it can be deduced that
316314
// the prefetch is not started yet.
317-
assertFalse("Prefetch Should not start at this point", reader.prefetchStarted());
318-
setComputeTiming(false);
315+
if (getElapsedTime() >= (conf.getLong(PREFETCH_DELAY, 1000))) {
316+
assertTrue("Prefetch should be started at this point", reader.prefetchStarted());
317+
setComputeTiming(false);
318+
} else {
319+
assertFalse("Prefetch Should not start at this point", reader.prefetchStarted());
320+
}
319321
}
320322
}
321-
endTimer();
322323
long offset = 0;
323324
while (offset < reader.getTrailer().getLoadOnOpenDataOffset()) {
324325
HFileBlock block = readFunction.apply(reader, offset);
@@ -374,7 +375,7 @@ public void testOnConfigurationChange() {
374375
@Test
375376
public void testPrefetchWithDelay() throws Exception {
376377
PrefetchExecutorNotifier prefetchExecutorNotifier = new PrefetchExecutorNotifier(conf);
377-
conf.setInt(PREFETCH_DELAY, 60000);
378+
conf.setInt(PREFETCH_DELAY, 35000);
378379
prefetchExecutorNotifier.onConfigurationChange(conf);
379380

380381
HFileContext context = new HFileContextBuilder().withCompression(Compression.Algorithm.GZ)
@@ -385,10 +386,6 @@ public void testPrefetchWithDelay() throws Exception {
385386
setComputeTiming(true);
386387

387388
readStoreFile(storeFile);
388-
//We apply delay variation to the provided delay and used the computed delay while scheduling
389-
//Using the computed delay for the comparison
390-
assertTrue("Total execution time is not more than delay duration",
391-
getElapsedTime() > PrefetchExecutor.getComputedPrefetchDelay());
392389
resetTiming();
393390

394391
conf.setInt(PREFETCH_DELAY, 1000);
@@ -551,7 +548,6 @@ public static KeyValue.Type generateKeyType(Random rand) {
551548

552549
private void resetTiming() {
553550
startTime = 0;
554-
endTime = 0;
555551
measureTiming = false;
556552
}
557553

@@ -561,13 +557,8 @@ private void startTimer() {
561557
}
562558
}
563559

564-
private void endTimer() {
565-
if (startTime > 0)
566-
endTime = System.currentTimeMillis();
567-
}
568-
569560
private long getElapsedTime() {
570-
return endTime - startTime;
561+
return System.currentTimeMillis() - startTime;
571562
}
572563

573564
private void setComputeTiming(boolean status) {

0 commit comments

Comments
 (0)