Skip to content

Commit b59b96c

Browse files
committed
HBASE-25549 Provide lazy mode when modifying table to avoid RIT storm
1 parent d6d67d1 commit b59b96c

19 files changed

Lines changed: 332 additions & 28 deletions

File tree

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,25 @@ default void modifyTable(TableDescriptor td) throws IOException {
10331033
* @return the result of the async modify. You can use Future.get(long, TimeUnit) to wait on the
10341034
* operation to complete
10351035
*/
1036-
Future<Void> modifyTableAsync(TableDescriptor td) throws IOException;
1036+
default Future<Void> modifyTableAsync(TableDescriptor td) throws IOException{
1037+
return modifyTableAsync(td, false);
1038+
}
1039+
1040+
/**
1041+
* Same as {@link #modifyTableAsync(TableDescriptor td)}. except
1042+
* {@code lazyMode} will control whether user lazy mode to modify a table
1043+
* @param td description of the table
1044+
* @param lazyMode When the lazy mode is enabled, the modification will not
1045+
* reopen any regions of the table so as to avoid RIT.
1046+
* A region would not aware of this modification till it reopened
1047+
* by another procedure(e.g. balance, move).
1048+
* Note that it temporarily lead to inconsistencies
1049+
* in the configuration of regions
1050+
* @throws IOException if a remote or network exception occurs
1051+
* @return the result of the async modify. You can use Future.get(long, TimeUnit) to wait on the
1052+
* operation to complete
1053+
*/
1054+
Future<Void> modifyTableAsync(TableDescriptor td, boolean lazyMode) throws IOException;
10371055

10381056
/**
10391057
* Shuts down the HBase cluster.

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,12 @@ public Future<Void> splitRegionAsync(byte[] regionName, byte[] splitPoint) throw
467467

468468
@Override
469469
public Future<Void> modifyTableAsync(TableDescriptor td) throws IOException {
470-
return admin.modifyTable(td);
470+
return modifyTableAsync(td, false);
471+
}
472+
473+
@Override
474+
public Future<Void> modifyTableAsync(TableDescriptor td, boolean lazyMode) throws IOException {
475+
return admin.modifyTable(td, lazyMode);
471476
}
472477

473478
@Override

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,21 @@ CompletableFuture<Void> createTable(TableDescriptor desc, byte[] startKey, byte[
180180
* Modify an existing table, more IRB friendly version.
181181
* @param desc modified description of the table
182182
*/
183-
CompletableFuture<Void> modifyTable(TableDescriptor desc);
183+
default CompletableFuture<Void> modifyTable(TableDescriptor desc){
184+
return modifyTable(desc, false);
185+
}
186+
187+
/**
188+
* Modify an existing table, more IRB friendly version.
189+
* @param desc description of the table
190+
* @param lazyMode When the lazy mode is enabled, the modification will not
191+
* reopen any regions of the table so as to avoid RIT.
192+
* A region would not aware of this modification till it reopened
193+
* by another procedure(e.g. balance, move).
194+
* Note that it temporarily lead to inconsistencies in the configuration of regions
195+
*/
196+
CompletableFuture<Void> modifyTable(TableDescriptor desc, boolean lazyMode);
197+
184198

185199
/**
186200
* Deletes a table.

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
@@ -143,7 +143,12 @@ public CompletableFuture<Void> createTable(TableDescriptor desc, byte[][] splitK
143143

144144
@Override
145145
public CompletableFuture<Void> modifyTable(TableDescriptor desc) {
146-
return wrap(rawAdmin.modifyTable(desc));
146+
return modifyTable(desc, false);
147+
}
148+
149+
@Override
150+
public CompletableFuture<Void> modifyTable(TableDescriptor desc, boolean lazyMode) {
151+
return wrap(rawAdmin.modifyTable(desc, lazyMode));
147152
}
148153

149154
@Override

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,9 +656,14 @@ private CompletableFuture<Void> createTable(TableName tableName, CreateTableRequ
656656

657657
@Override
658658
public CompletableFuture<Void> modifyTable(TableDescriptor desc) {
659+
return modifyTable(desc, false);
660+
}
661+
662+
@Override
663+
public CompletableFuture<Void> modifyTable(TableDescriptor desc, boolean lazyMode) {
659664
return this.<ModifyTableRequest, ModifyTableResponse> procedureCall(desc.getTableName(),
660665
RequestConverter.buildModifyTableRequest(desc.getTableName(), desc, ng.getNonceGroup(),
661-
ng.newNonce()), (s, c, req, done) -> s.modifyTable(c, req, done),
666+
ng.newNonce(), lazyMode), (s, c, req, done) -> s.modifyTable(c, req, done),
662667
(resp) -> resp.getProcId(), new ModifyTableProcedureBiConsumer(this, desc.getTableName()));
663668
}
664669

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,22 +54,37 @@ public interface TableDescriptor {
5454
if (result != 0) {
5555
return result;
5656
}
57+
result = getColumnFamilyComparator(cfComparator).compare(lhs, rhs);
58+
if (result != 0){
59+
return result;
60+
}
61+
// punt on comparison for ordering, just calculate difference
62+
return Integer.compare(lhs.getValues().hashCode(), rhs.getValues().hashCode());
63+
};
64+
}
65+
66+
/**
67+
* This comparator only compare ColumnFamilyDescriptor between two tables
68+
*/
69+
static Comparator<TableDescriptor>
70+
getColumnFamilyComparator(
71+
Comparator<ColumnFamilyDescriptor> cfComparator) {
72+
return (TableDescriptor lhs, TableDescriptor rhs) -> {
5773
Collection<ColumnFamilyDescriptor> lhsFamilies = Arrays.asList(lhs.getColumnFamilies());
5874
Collection<ColumnFamilyDescriptor> rhsFamilies = Arrays.asList(rhs.getColumnFamilies());
59-
result = Integer.compare(lhsFamilies.size(), rhsFamilies.size());
75+
int result = Integer.compare(lhsFamilies.size(), rhsFamilies.size());
6076
if (result != 0) {
6177
return result;
6278
}
6379

6480
for (Iterator<ColumnFamilyDescriptor> it = lhsFamilies.iterator(), it2 =
65-
rhsFamilies.iterator(); it.hasNext();) {
81+
rhsFamilies.iterator(); it.hasNext();) {
6682
result = cfComparator.compare(it.next(), it2.next());
6783
if (result != 0) {
6884
return result;
6985
}
7086
}
71-
// punt on comparison for ordering, just calculate difference
72-
return Integer.compare(lhs.getValues().hashCode(), rhs.getValues().hashCode());
87+
return 0;
7388
};
7489
}
7590

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,15 +1203,17 @@ public static CreateTableRequest buildCreateTableRequest(
12031203
* @return a ModifyTableRequest
12041204
*/
12051205
public static ModifyTableRequest buildModifyTableRequest(
1206-
final TableName tableName,
1207-
final TableDescriptor tableDesc,
1208-
final long nonceGroup,
1209-
final long nonce) {
1206+
final TableName tableName,
1207+
final TableDescriptor tableDesc,
1208+
final long nonceGroup,
1209+
final long nonce,
1210+
final boolean lazyMode) {
12101211
ModifyTableRequest.Builder builder = ModifyTableRequest.newBuilder();
12111212
builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
12121213
builder.setTableSchema(ProtobufUtil.toTableSchema(tableDesc));
12131214
builder.setNonceGroup(nonceGroup);
12141215
builder.setNonce(nonce);
1216+
builder.setLazyMode(lazyMode);
12151217
return builder.build();
12161218
}
12171219

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ message ModifyTableRequest {
194194
required TableSchema table_schema = 2;
195195
optional uint64 nonce_group = 3 [default = 0];
196196
optional uint64 nonce = 4 [default = 0];
197+
optional bool lazy_mode = 5 [default = false];
197198
}
198199

199200
message ModifyTableResponse {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ message ModifyTableStateData {
8282
required TableSchema modified_table_schema = 3;
8383
required bool delete_column_family_in_modify = 4;
8484
optional bool should_check_descriptor = 5;
85+
optional bool lazy_mode = 6;
8586
}
8687

8788
enum TruncateTableState {

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2353,9 +2353,15 @@ protected String getDescription() {
23532353
});
23542354
}
23552355

2356+
private long modifyTable(final TableName tableName,
2357+
final TableDescriptorGetter newDescriptorGetter, final long nonceGroup, final long nonce,
2358+
final boolean lazyMode) throws IOException{
2359+
return modifyTable(tableName,newDescriptorGetter, nonceGroup, nonce, lazyMode, true);
2360+
}
2361+
23562362
private long modifyTable(final TableName tableName,
23572363
final TableDescriptorGetter newDescriptorGetter, final long nonceGroup, final long nonce,
2358-
final boolean shouldCheckDescriptor) throws IOException {
2364+
final boolean shouldCheckDescriptor, final boolean lazyMode) throws IOException {
23592365
return MasterProcedureUtil
23602366
.submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {
23612367
@Override
@@ -2374,7 +2380,7 @@ protected void run() throws IOException {
23742380
// checks. This will block only the beginning of the procedure. See HBASE-19953.
23752381
ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();
23762382
submitProcedure(new ModifyTableProcedure(procedureExecutor.getEnvironment(),
2377-
newDescriptor, latch, oldDescriptor, shouldCheckDescriptor));
2383+
newDescriptor, latch, oldDescriptor, shouldCheckDescriptor, lazyMode));
23782384
latch.await();
23792385

23802386
getMaster().getMasterCoprocessorHost().postModifyTable(tableName, oldDescriptor,
@@ -2391,14 +2397,14 @@ protected String getDescription() {
23912397

23922398
@Override
23932399
public long modifyTable(final TableName tableName, final TableDescriptor newDescriptor,
2394-
final long nonceGroup, final long nonce) throws IOException {
2400+
final long nonceGroup, final long nonce, final boolean lazyMode) throws IOException {
23952401
checkInitialized();
23962402
return modifyTable(tableName, new TableDescriptorGetter() {
23972403
@Override
23982404
public TableDescriptor get() throws IOException {
23992405
return newDescriptor;
24002406
}
2401-
}, nonceGroup, nonce, false);
2407+
}, nonceGroup, nonce, false, lazyMode);
24022408

24032409
}
24042410

0 commit comments

Comments
 (0)