Skip to content

Commit 01d9e80

Browse files
wchevreuilvirajjasani
authored andcommitted
HBASE-27474 Evict blocks on split/merge; Avoid caching reference/hlinks if compaction is enabled (apache#4868)
Signed-off-by: Peter Somogyi <[email protected]>
1 parent 4d38e01 commit 01d9e80

File tree

15 files changed

+191
-21
lines changed

15 files changed

+191
-21
lines changed

hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3004,6 +3004,19 @@ public static CloseRegionRequest buildCloseRegionRequest(ServerName server, byte
30043004
}
30053005

30063006
public static CloseRegionRequest buildCloseRegionRequest(ServerName server, byte[] regionName,
3007+
ServerName destinationServer, long closeProcId) {
3008+
return ProtobufUtil.getBuilder(server, regionName, destinationServer, closeProcId).build();
3009+
}
3010+
3011+
public static CloseRegionRequest buildCloseRegionRequest(ServerName server, byte[] regionName,
3012+
ServerName destinationServer, long closeProcId, boolean evictCache) {
3013+
CloseRegionRequest.Builder builder =
3014+
getBuilder(server, regionName, destinationServer, closeProcId);
3015+
builder.setEvictCache(evictCache);
3016+
return builder.build();
3017+
}
3018+
3019+
public static CloseRegionRequest.Builder getBuilder(ServerName server, byte[] regionName,
30073020
ServerName destinationServer, long closeProcId) {
30083021
CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
30093022
RegionSpecifier region =
@@ -3016,7 +3029,7 @@ public static CloseRegionRequest buildCloseRegionRequest(ServerName server, byte
30163029
builder.setServerStartCode(server.getStartcode());
30173030
}
30183031
builder.setCloseProcId(closeProcId);
3019-
return builder.build();
3032+
return builder;
30203033
}
30213034

30223035
public static ProcedureDescription buildProcedureDescription(String signature, String instance,

hbase-protocol-shaded/src/main/protobuf/server/master/MasterProcedure.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,8 @@ message RegionStateTransitionStateData {
604604
required RegionTransitionType type = 1;
605605
optional ServerName assign_candidate = 2;
606606
required bool force_new_plan = 3;
607+
optional bool is_split = 4 [default = false];
608+
optional bool evict_cache = 5 [default = false];
607609
}
608610

609611
enum RegionRemoteProcedureBaseState {
@@ -628,6 +630,7 @@ message OpenRegionProcedureStateData {
628630

629631
message CloseRegionProcedureStateData {
630632
optional ServerName assign_candidate = 1;
633+
optional bool evict_cache = 2 [default = false];
631634
}
632635

633636
enum SwitchRpcThrottleState {

hbase-protocol-shaded/src/main/protobuf/server/region/Admin.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ message CloseRegionRequest {
122122
// the intended server for this RPC.
123123
optional uint64 serverStartCode = 5;
124124
optional int64 close_proc_id = 6 [default = -1];
125+
optional bool evict_cache = 7 [default = false];
125126
}
126127

127128
message CloseRegionResponse {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public HFilePreadReader(ReaderContext context, HFileInfo fileInfo, CacheConfig c
3535
Configuration conf) throws IOException {
3636
super(context, fileInfo, cacheConf, conf);
3737
// Prefetch file blocks upon open if requested
38-
if (cacheConf.shouldPrefetchOnOpen()) {
38+
if (cacheConf.shouldPrefetchOnOpen() && cacheIfCompactionsOff()) {
3939
PrefetchExecutor.request(path, new Runnable() {
4040
@Override
4141
public void run() {
@@ -97,7 +97,7 @@ public void close(boolean evictOnClose) throws IOException {
9797
if (evictOnClose) {
9898
int numEvicted = cache.evictBlocksByHfileName(name);
9999
if (LOG.isTraceEnabled()) {
100-
LOG.trace("On close, file=" + name + " evicted=" + numEvicted + " block(s)");
100+
LOG.trace("On close, file= {} evicted= {} block(s)", name, numEvicted);
101101
}
102102
}
103103
});

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818
package org.apache.hadoop.hbase.io.hfile;
1919

20+
import static org.apache.hadoop.hbase.regionserver.CompactSplit.HBASE_REGION_SERVER_ENABLE_COMPACTION;
2021
import static org.apache.hadoop.hbase.trace.HBaseSemanticAttributes.BLOCK_CACHE_KEY_KEY;
2122

2223
import io.opentelemetry.api.common.Attributes;
@@ -40,12 +41,14 @@
4041
import org.apache.hadoop.hbase.SizeCachedKeyValue;
4142
import org.apache.hadoop.hbase.SizeCachedNoTagsByteBufferKeyValue;
4243
import org.apache.hadoop.hbase.SizeCachedNoTagsKeyValue;
44+
import org.apache.hadoop.hbase.io.HFileLink;
4345
import org.apache.hadoop.hbase.io.compress.Compression;
4446
import org.apache.hadoop.hbase.io.encoding.DataBlockEncoder;
4547
import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
4648
import org.apache.hadoop.hbase.io.encoding.HFileBlockDecodingContext;
4749
import org.apache.hadoop.hbase.nio.ByteBuff;
4850
import org.apache.hadoop.hbase.regionserver.KeyValueScanner;
51+
import org.apache.hadoop.hbase.regionserver.StoreFileInfo;
4952
import org.apache.hadoop.hbase.util.ByteBufferUtils;
5053
import org.apache.hadoop.hbase.util.Bytes;
5154
import org.apache.hadoop.hbase.util.IdLock;
@@ -1264,6 +1267,8 @@ public HFileBlock readBlock(long dataBlockOffset, long onDiskBlockSize, final bo
12641267
new BlockCacheKey(name, dataBlockOffset, this.isPrimaryReplicaReader(), expectedBlockType);
12651268
Attributes attributes = Attributes.of(BLOCK_CACHE_KEY_KEY, cacheKey.toString());
12661269

1270+
boolean cacheable = cacheBlock && cacheIfCompactionsOff();
1271+
12671272
boolean useLock = false;
12681273
IdLock.Entry lockEntry = null;
12691274
final Span span = Span.current();
@@ -1305,7 +1310,7 @@ public HFileBlock readBlock(long dataBlockOffset, long onDiskBlockSize, final bo
13051310
return cachedBlock;
13061311
}
13071312

1308-
if (!useLock && cacheBlock && cacheConf.shouldLockOnCacheMiss(expectedBlockType)) {
1313+
if (!useLock && cacheable && cacheConf.shouldLockOnCacheMiss(expectedBlockType)) {
13091314
// check cache again with lock
13101315
useLock = true;
13111316
continue;
@@ -1324,10 +1329,10 @@ public HFileBlock readBlock(long dataBlockOffset, long onDiskBlockSize, final bo
13241329

13251330
// Don't need the unpacked block back and we're storing the block in the cache compressed
13261331
if (cacheOnly && cacheCompressed && cacheOnRead) {
1327-
LOG.debug("Skipping decompression of block in prefetch");
1332+
LOG.debug("Skipping decompression of block {} in prefetch", cacheKey);
13281333
// Cache the block if necessary
13291334
cacheConf.getBlockCache().ifPresent(cache -> {
1330-
if (cacheBlock && cacheConf.shouldCacheBlockOnRead(category)) {
1335+
if (cacheable && cacheConf.shouldCacheBlockOnRead(category)) {
13311336
cache.cacheBlock(cacheKey, hfileBlock, cacheConf.isInMemory(), cacheOnly);
13321337
}
13331338
});
@@ -1340,7 +1345,7 @@ public HFileBlock readBlock(long dataBlockOffset, long onDiskBlockSize, final bo
13401345
HFileBlock unpacked = hfileBlock.unpack(hfileContext, fsBlockReader);
13411346
// Cache the block if necessary
13421347
cacheConf.getBlockCache().ifPresent(cache -> {
1343-
if (cacheBlock && cacheConf.shouldCacheBlockOnRead(category)) {
1348+
if (cacheable && cacheConf.shouldCacheBlockOnRead(category)) {
13441349
// Using the wait on cache during compaction and prefetching.
13451350
cache.cacheBlock(cacheKey, cacheCompressed ? hfileBlock : unpacked,
13461351
cacheConf.isInMemory(), cacheOnly);
@@ -1667,4 +1672,9 @@ public int getMajorVersion() {
16671672
public void unbufferStream() {
16681673
fsBlockReader.unbufferStream();
16691674
}
1675+
1676+
protected boolean cacheIfCompactionsOff() {
1677+
return (!StoreFileInfo.isReference(name) && !HFileLink.isHFileLink(name))
1678+
|| !conf.getBoolean(HBASE_REGION_SERVER_ENABLE_COMPACTION, true);
1679+
}
16701680
}

hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManagerUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ static TransitRegionStateProcedure[] createUnassignProceduresForSplitOrMerge(
105105
for (; i < procs.length; i++) {
106106
RegionStateNode regionNode = regionNodes.get(i);
107107
TransitRegionStateProcedure proc =
108-
TransitRegionStateProcedure.unassign(env, regionNode.getRegionInfo());
108+
TransitRegionStateProcedure.unassignSplitMerge(env, regionNode.getRegionInfo());
109109
if (regionNode.getProcedure() != null) {
110110
throw new HBaseIOException(
111111
"The parent region " + regionNode + " is currently in transition, give up");

hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/CloseRegionProcedure.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,17 @@ public class CloseRegionProcedure extends RegionRemoteProcedureBase {
4545
// wrong(but do not make it wrong intentionally). The client can handle this error.
4646
private ServerName assignCandidate;
4747

48+
private boolean evictCache;
49+
4850
public CloseRegionProcedure() {
4951
super();
5052
}
5153

5254
public CloseRegionProcedure(TransitRegionStateProcedure parent, RegionInfo region,
53-
ServerName targetServer, ServerName assignCandidate) {
55+
ServerName targetServer, ServerName assignCandidate, boolean evictCache) {
5456
super(parent, region, targetServer);
5557
this.assignCandidate = assignCandidate;
58+
this.evictCache = evictCache;
5659
}
5760

5861
@Override
@@ -62,7 +65,7 @@ public TableOperationType getTableOperationType() {
6265

6366
@Override
6467
public RemoteOperation newRemoteOperation() {
65-
return new RegionCloseOperation(this, region, getProcId(), assignCandidate);
68+
return new RegionCloseOperation(this, region, getProcId(), assignCandidate, evictCache);
6669
}
6770

6871
@Override
@@ -72,6 +75,7 @@ protected void serializeStateData(ProcedureStateSerializer serializer) throws IO
7275
if (assignCandidate != null) {
7376
builder.setAssignCandidate(ProtobufUtil.toServerName(assignCandidate));
7477
}
78+
builder.setEvictCache(evictCache);
7579
serializer.serialize(builder.build());
7680
}
7781

@@ -83,6 +87,7 @@ protected void deserializeStateData(ProcedureStateSerializer serializer) throws
8387
if (data.hasAssignCandidate()) {
8488
assignCandidate = ProtobufUtil.toServerName(data.getAssignCandidate());
8589
}
90+
evictCache = data.getEvictCache();
8691
}
8792

8893
@Override

hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
*/
1818
package org.apache.hadoop.hbase.master.assignment;
1919

20+
import static org.apache.hadoop.hbase.io.hfile.CacheConfig.DEFAULT_EVICT_ON_CLOSE;
21+
import static org.apache.hadoop.hbase.io.hfile.CacheConfig.EVICT_BLOCKS_ON_CLOSE_KEY;
2022
import static org.apache.hadoop.hbase.master.LoadBalancer.BOGUS_SERVER_NAME;
2123

2224
import edu.umd.cs.findbugs.annotations.Nullable;
@@ -120,6 +122,10 @@ public class TransitRegionStateProcedure
120122

121123
private RegionRemoteProcedureBase remoteProc;
122124

125+
private boolean evictCache;
126+
127+
private boolean isSplit;
128+
123129
public TransitRegionStateProcedure() {
124130
}
125131

@@ -155,6 +161,14 @@ protected TransitRegionStateProcedure(MasterProcedureEnv env, RegionInfo hri,
155161
if (type == TransitionType.REOPEN) {
156162
this.assignCandidate = getRegionStateNode(env).getRegionLocation();
157163
}
164+
evictCache =
165+
env.getMasterConfiguration().getBoolean(EVICT_BLOCKS_ON_CLOSE_KEY, DEFAULT_EVICT_ON_CLOSE);
166+
}
167+
168+
protected TransitRegionStateProcedure(MasterProcedureEnv env, RegionInfo hri,
169+
ServerName assignCandidate, boolean forceNewPlan, TransitionType type, boolean isSplit) {
170+
this(env, hri, assignCandidate, forceNewPlan, type);
171+
this.isSplit = isSplit;
158172
}
159173

160174
@Override
@@ -264,8 +278,12 @@ private void closeRegion(MasterProcedureEnv env, RegionStateNode regionNode) thr
264278
if (regionNode.isInState(State.OPEN, State.CLOSING, State.MERGING, State.SPLITTING)) {
265279
// this is the normal case
266280
env.getAssignmentManager().regionClosing(regionNode);
267-
addChildProcedure(new CloseRegionProcedure(this, getRegion(), regionNode.getRegionLocation(),
268-
assignCandidate));
281+
CloseRegionProcedure closeProc = isSplit
282+
? new CloseRegionProcedure(this, getRegion(), regionNode.getRegionLocation(),
283+
assignCandidate, true)
284+
: new CloseRegionProcedure(this, getRegion(), regionNode.getRegionLocation(),
285+
assignCandidate, evictCache);
286+
addChildProcedure(closeProc);
269287
setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED);
270288
} else {
271289
forceNewPlan = true;
@@ -504,8 +522,9 @@ private static RegionTransitionType convert(TransitionType type) {
504522
@Override
505523
protected void serializeStateData(ProcedureStateSerializer serializer) throws IOException {
506524
super.serializeStateData(serializer);
507-
RegionStateTransitionStateData.Builder builder = RegionStateTransitionStateData.newBuilder()
508-
.setType(convert(type)).setForceNewPlan(forceNewPlan);
525+
RegionStateTransitionStateData.Builder builder =
526+
RegionStateTransitionStateData.newBuilder().setType(convert(type))
527+
.setForceNewPlan(forceNewPlan).setEvictCache(evictCache).setIsSplit(isSplit);
509528
if (assignCandidate != null) {
510529
builder.setAssignCandidate(ProtobufUtil.toServerName(assignCandidate));
511530
}
@@ -523,6 +542,8 @@ protected void deserializeStateData(ProcedureStateSerializer serializer) throws
523542
if (data.hasAssignCandidate()) {
524543
assignCandidate = ProtobufUtil.toServerName(data.getAssignCandidate());
525544
}
545+
evictCache = data.getEvictCache();
546+
isSplit = data.getIsSplit();
526547
}
527548

528549
@Override
@@ -586,6 +607,12 @@ public static TransitRegionStateProcedure unassign(MasterProcedureEnv env, Regio
586607
new TransitRegionStateProcedure(env, region, null, false, TransitionType.UNASSIGN));
587608
}
588609

610+
public static TransitRegionStateProcedure unassignSplitMerge(MasterProcedureEnv env,
611+
RegionInfo region) {
612+
return setOwner(env,
613+
new TransitRegionStateProcedure(env, region, null, false, TransitionType.UNASSIGN, true));
614+
}
615+
589616
public static TransitRegionStateProcedure reopen(MasterProcedureEnv env, RegionInfo region) {
590617
return setOwner(env,
591618
new TransitRegionStateProcedure(env, region, null, false, TransitionType.REOPEN));

hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/RSProcedureDispatcher.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,11 +463,13 @@ public RegionOpenOperation(RemoteProcedure remoteProcedure, RegionInfo regionInf
463463

464464
public static class RegionCloseOperation extends RegionOperation {
465465
private final ServerName destinationServer;
466+
private boolean evictCache;
466467

467468
public RegionCloseOperation(RemoteProcedure remoteProcedure, RegionInfo regionInfo, long procId,
468-
ServerName destinationServer) {
469+
ServerName destinationServer, boolean evictCache) {
469470
super(remoteProcedure, regionInfo, procId);
470471
this.destinationServer = destinationServer;
472+
this.evictCache = evictCache;
471473
}
472474

473475
public ServerName getDestinationServer() {
@@ -476,7 +478,8 @@ public ServerName getDestinationServer() {
476478

477479
public CloseRegionRequest buildCloseRegionRequest(final ServerName serverName) {
478480
return ProtobufUtil.buildCloseRegionRequest(serverName, regionInfo.getRegionName(),
479-
getDestinationServer(), procId);
481+
getDestinationServer(), procId, evictCache);
482+
480483
}
481484
}
482485
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,7 @@ public boolean isCompactionsEnabled() {
849849

850850
public void setCompactionsEnabled(boolean compactionsEnabled) {
851851
this.compactionsEnabled = compactionsEnabled;
852-
this.conf.set(HBASE_REGION_SERVER_ENABLE_COMPACTION, String.valueOf(compactionsEnabled));
852+
this.conf.setBoolean(HBASE_REGION_SERVER_ENABLE_COMPACTION, compactionsEnabled);
853853
}
854854

855855
/** Returns the longCompactions thread pool executor */

0 commit comments

Comments
 (0)