Skip to content

Commit 0335733

Browse files
committed
HBASE-24627 Normalize one table at a time
Introduce an additional method to our Admin interface that allow an operator to selectivly run the normalizer. The IPC protocol supports general table name select via compound filter.
1 parent d2afda3 commit 0335733

File tree

17 files changed

+389
-66
lines changed

17 files changed

+389
-66
lines changed

hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -856,11 +856,23 @@ void unassign(byte[] regionName, boolean force)
856856
* the request was submitted successfully. We need to check logs for the details of which regions
857857
* were split/merged.
858858
*
859-
* @return <code>true</code> if region normalizer ran, <code>false</code> otherwise.
859+
* @return {@code true} if region normalizer ran, {@code false} otherwise.
860860
* @throws IOException if a remote or network exception occurs
861861
*/
862862
boolean normalize() throws IOException;
863863

864+
/**
865+
* Invoke region normalizer. Can NOT run for various reasons. Check logs.
866+
* This is a non-blocking invocation to region normalizer. If return value is true, it means
867+
* the request was submitted successfully. We need to check logs for the details of which regions
868+
* were split/merged.
869+
*
870+
* @param ntfp limit to tables matching the specified filter.
871+
* @return {@code true} if region normalizer ran, {@code false} otherwise.
872+
* @throws IOException if a remote or network exception occurs
873+
*/
874+
boolean normalize(NormalizeTableFilterParams ntfp) throws IOException;
875+
864876
/**
865877
* Query the current state of the region normalizer.
866878
*

hbase-client/src/main/java/org/apache/hadoop/hbase/client/AdminOverAsyncAdmin.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,11 @@ public boolean normalize() throws IOException {
399399
return get(admin.normalize());
400400
}
401401

402+
@Override
403+
public boolean normalize(NormalizeTableFilterParams ntfp) throws IOException {
404+
return get(admin.normalize(ntfp));
405+
}
406+
402407
@Override
403408
public boolean isNormalizerEnabled() throws IOException {
404409
return get(admin.isNormalizerEnabled());

hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/**
1+
/*
22
* Licensed to the Apache Software Foundation (ASF) under one
33
* or more contributor license agreements. See the NOTICE file
44
* distributed with this work for additional information
@@ -1281,6 +1281,14 @@ default CompletableFuture<Boolean> balance() {
12811281
*/
12821282
CompletableFuture<Boolean> normalize();
12831283

1284+
/**
1285+
* Invoke region normalizer. Can NOT run for various reasons. Check logs.
1286+
* @param ntfp limit to tables matching the specified filter.
1287+
* @return true if region normalizer ran, false otherwise. The return value will be wrapped by a
1288+
* {@link CompletableFuture}
1289+
*/
1290+
CompletableFuture<Boolean> normalize(NormalizeTableFilterParams ntfp);
1291+
12841292
/**
12851293
* Turn the cleaner chore on/off.
12861294
* @param on

hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/**
1+
/*
22
* Licensed to the Apache Software Foundation (ASF) under one
33
* or more contributor license agreements. See the NOTICE file
44
* distributed with this work for additional information
@@ -713,6 +713,11 @@ public CompletableFuture<Boolean> normalize() {
713713
return wrap(rawAdmin.normalize());
714714
}
715715

716+
@Override
717+
public CompletableFuture<Boolean> normalize(NormalizeTableFilterParams ntfp) {
718+
return wrap(rawAdmin.normalize(ntfp));
719+
}
720+
716721
@Override
717722
public CompletableFuture<Boolean> cleanerChoreSwitch(boolean enabled) {
718723
return wrap(rawAdmin.cleanerChoreSwitch(enabled));
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.hadoop.hbase.client;
19+
20+
import java.util.List;
21+
import org.apache.hadoop.hbase.TableName;
22+
import org.apache.yetus.audience.InterfaceAudience;
23+
import org.apache.yetus.audience.InterfaceStability;
24+
25+
/**
26+
* A collection of criteria used for table selection.
27+
*/
28+
@InterfaceAudience.Public
29+
@InterfaceStability.Evolving
30+
public class NormalizeTableFilterParams {
31+
private final List<TableName> tableNames;
32+
private final String regex;
33+
private final String namespace;
34+
35+
public NormalizeTableFilterParams(
36+
final List<TableName> tableNames,
37+
final String regex,
38+
final String namespace
39+
) {
40+
this.tableNames = tableNames;
41+
this.regex = regex;
42+
this.namespace = namespace;
43+
}
44+
45+
public List<TableName> getTableNames() {
46+
return tableNames;
47+
}
48+
49+
public String getRegex() {
50+
return regex;
51+
}
52+
53+
public String getNamespace() {
54+
return namespace;
55+
}
56+
57+
/**
58+
* Used to instantiate an instance of {@link NormalizeTableFilterParams}.
59+
*/
60+
public static class Builder {
61+
private List<TableName> tableNames;
62+
private String regex;
63+
private String namespace;
64+
65+
public Builder tableFilterParams(final NormalizeTableFilterParams ntfp) {
66+
this.tableNames = ntfp.getTableNames();
67+
this.regex = ntfp.getRegex();
68+
this.namespace = ntfp.getNamespace();
69+
return this;
70+
}
71+
72+
public Builder tableNames(final List<TableName> tableNames) {
73+
this.tableNames = tableNames;
74+
return this;
75+
}
76+
77+
public Builder regex(final String regex) {
78+
this.regex = regex;
79+
return this;
80+
}
81+
82+
public Builder namespace(final String namespace) {
83+
this.namespace = namespace;
84+
return this;
85+
}
86+
87+
public NormalizeTableFilterParams build() {
88+
return new NormalizeTableFilterParams(tableNames, regex, namespace);
89+
}
90+
}
91+
}

hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3287,13 +3287,22 @@ public CompletableFuture<Boolean> isNormalizerEnabled() {
32873287

32883288
@Override
32893289
public CompletableFuture<Boolean> normalize() {
3290+
return normalize(RequestConverter.buildNormalizeRequest());
3291+
}
3292+
3293+
@Override
3294+
public CompletableFuture<Boolean> normalize(NormalizeTableFilterParams ntfp) {
3295+
return normalize(RequestConverter.buildNormalizeRequest(ntfp));
3296+
}
3297+
3298+
private CompletableFuture<Boolean> normalize(NormalizeRequest request) {
32903299
return this
3291-
.<Boolean> newMasterCaller()
3292-
.action(
3293-
(controller, stub) -> this.<NormalizeRequest, NormalizeResponse, Boolean> call(
3294-
controller, stub, RequestConverter.buildNormalizeRequest(),
3295-
(s, c, req, done) -> s.normalize(c, req, done), (resp) -> resp.getNormalizerRan()))
3296-
.call();
3300+
.<Boolean> newMasterCaller()
3301+
.action(
3302+
(controller, stub) -> this.<NormalizeRequest, NormalizeResponse, Boolean> call(
3303+
controller, stub, request, MasterService.Interface::normalize,
3304+
NormalizeResponse::getNormalizerRan))
3305+
.call();
32973306
}
32983307

32993308
@Override

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,6 +2293,13 @@ public static HBaseProtos.TableName toProtoTableName(TableName tableName) {
22932293
.setQualifier(UnsafeByteOperations.unsafeWrap(tableName.getQualifier())).build();
22942294
}
22952295

2296+
public static List<HBaseProtos.TableName> toProtoTableNameList(List<TableName> tableNameList) {
2297+
if (tableNameList == null) {
2298+
return new ArrayList<>();
2299+
}
2300+
return tableNameList.stream().map(ProtobufUtil::toProtoTableName).collect(Collectors.toList());
2301+
}
2302+
22962303
public static List<TableName> toTableNameList(List<HBaseProtos.TableName> tableNamesList) {
22972304
if (tableNamesList == null) {
22982305
return new ArrayList<>();

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/**
1+
/*
22
* Licensed to the Apache Software Foundation (ASF) under one
33
* or more contributor license agreements. See the NOTICE file
44
* distributed with this work for additional information
@@ -46,6 +46,7 @@
4646
import org.apache.hadoop.hbase.client.LogQueryFilter;
4747
import org.apache.hadoop.hbase.client.MasterSwitchType;
4848
import org.apache.hadoop.hbase.client.Mutation;
49+
import org.apache.hadoop.hbase.client.NormalizeTableFilterParams;
4950
import org.apache.hadoop.hbase.client.Put;
5051
import org.apache.hadoop.hbase.client.RegionCoprocessorServiceExec;
5152
import org.apache.hadoop.hbase.client.RegionInfo;
@@ -1480,6 +1481,25 @@ public static NormalizeRequest buildNormalizeRequest() {
14801481
return NormalizeRequest.newBuilder().build();
14811482
}
14821483

1484+
/**
1485+
* Creates a protocol buffer NormalizeRequest
1486+
*
1487+
* @return a NormalizeRequest
1488+
*/
1489+
public static NormalizeRequest buildNormalizeRequest(NormalizeTableFilterParams ntfp) {
1490+
final NormalizeRequest.Builder builder = NormalizeRequest.newBuilder();
1491+
if (ntfp.getTableNames() != null) {
1492+
builder.addAllTableNames(ProtobufUtil.toProtoTableNameList(ntfp.getTableNames()));
1493+
}
1494+
if (ntfp.getRegex() != null) {
1495+
builder.setRegex(ntfp.getRegex());
1496+
}
1497+
if (ntfp.getNamespace() != null) {
1498+
builder.setNamespace(ntfp.getNamespace());
1499+
}
1500+
return builder.build();
1501+
}
1502+
14831503
/**
14841504
* Creates a protocol buffer IsNormalizerEnabledRequest
14851505
*

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,9 @@ message IsSplitOrMergeEnabledResponse {
354354
}
355355

356356
message NormalizeRequest {
357+
repeated TableName table_names = 1;
358+
optional string regex = 2;
359+
optional string namespace = 3;
357360
}
358361

359362
message NormalizeResponse {

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

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import static org.apache.hadoop.hbase.HConstants.HBASE_MASTER_LOGCLEANER_PLUGINS;
2222
import static org.apache.hadoop.hbase.HConstants.HBASE_SPLIT_WAL_COORDINATED_BY_ZK;
2323
import static org.apache.hadoop.hbase.util.DNS.MASTER_HOSTNAME_KEY;
24-
2524
import java.io.IOException;
2625
import java.io.InterruptedIOException;
2726
import java.lang.reflect.Constructor;
@@ -38,6 +37,7 @@
3837
import java.util.EnumSet;
3938
import java.util.HashMap;
4039
import java.util.Iterator;
40+
import java.util.LinkedList;
4141
import java.util.List;
4242
import java.util.Map;
4343
import java.util.Objects;
@@ -80,9 +80,9 @@
8080
import org.apache.hadoop.hbase.TableNotDisabledException;
8181
import org.apache.hadoop.hbase.TableNotFoundException;
8282
import org.apache.hadoop.hbase.UnknownRegionException;
83-
import org.apache.hadoop.hbase.client.Admin;
8483
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
8584
import org.apache.hadoop.hbase.client.MasterSwitchType;
85+
import org.apache.hadoop.hbase.client.NormalizeTableFilterParams;
8686
import org.apache.hadoop.hbase.client.RegionInfo;
8787
import org.apache.hadoop.hbase.client.RegionInfoBuilder;
8888
import org.apache.hadoop.hbase.client.RegionStatesCount;
@@ -227,14 +227,13 @@
227227
import org.eclipse.jetty.webapp.WebAppContext;
228228
import org.slf4j.Logger;
229229
import org.slf4j.LoggerFactory;
230-
231230
import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;
232231
import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
233232
import org.apache.hbase.thirdparty.com.google.common.collect.Maps;
233+
import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
234234
import org.apache.hbase.thirdparty.com.google.protobuf.Descriptors;
235235
import org.apache.hbase.thirdparty.com.google.protobuf.Service;
236236
import org.apache.hbase.thirdparty.org.apache.commons.collections4.CollectionUtils;
237-
238237
import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
239238
import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter;
240239
import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetRegionInfoResponse.CompactionState;
@@ -1910,14 +1909,18 @@ public RegionNormalizer getRegionNormalizer() {
19101909
return this.normalizer;
19111910
}
19121911

1912+
public boolean normalizeRegions() throws IOException {
1913+
return normalizeRegions(new NormalizeTableFilterParams.Builder().build());
1914+
}
1915+
19131916
/**
1914-
* Perform normalization of cluster (invoked by {@link RegionNormalizerChore}).
1917+
* Perform normalization of cluster.
19151918
*
19161919
* @return true if an existing normalization was already in progress, or if a new normalization
19171920
* was performed successfully; false otherwise (specifically, if HMaster finished initializing
19181921
* or normalization is globally disabled).
19191922
*/
1920-
public boolean normalizeRegions() throws IOException {
1923+
public boolean normalizeRegions(final NormalizeTableFilterParams ntfp) throws IOException {
19211924
final long startTime = EnvironmentEdgeManager.currentTime();
19221925
if (regionNormalizerTracker == null || !regionNormalizerTracker.isNormalizerOn()) {
19231926
LOG.debug("Region normalization is disabled, don't run region normalizer.");
@@ -1938,12 +1941,19 @@ public boolean normalizeRegions() throws IOException {
19381941

19391942
int affectedTables = 0;
19401943
try {
1941-
final List<TableName> allEnabledTables =
1942-
new ArrayList<>(tableStateManager.getTablesInStates(TableState.State.ENABLED));
1943-
Collections.shuffle(allEnabledTables);
1944+
final Set<TableName> matchingTables = getTableDescriptors(new LinkedList<>(),
1945+
ntfp.getNamespace(), ntfp.getRegex(), ntfp.getTableNames(), false)
1946+
.stream()
1947+
.map(TableDescriptor::getTableName)
1948+
.collect(Collectors.toSet());
1949+
final Set<TableName> allEnabledTables =
1950+
tableStateManager.getTablesInStates(TableState.State.ENABLED);
1951+
final List<TableName> targetTables =
1952+
new ArrayList<>(Sets.intersection(matchingTables, allEnabledTables));
1953+
Collections.shuffle(targetTables);
19441954

19451955
final List<Long> submittedPlanProcIds = new ArrayList<>();
1946-
for (TableName table : allEnabledTables) {
1956+
for (TableName table : targetTables) {
19471957
if (table.isSystemTable()) {
19481958
continue;
19491959
}

0 commit comments

Comments
 (0)