Skip to content

Commit c0497ca

Browse files
mini666juke-mini666
authored andcommitted
HBASE-30058 Eliminate unnecessary connection creation in snapshot operations
Each snapshot operation created two short-lived connections in SnapshotDescriptionUtils.validate() — one for isSecurityAvailable() to check hbase:acl table existence, and another in writeAclToSnapshotDescription() to read ACL data. In Kerberos environments with ZKConnectionRegistry, each connection triggered a new ZK session with GSSAPI authentication and a TGS request to the KDC, causing excessive KDC load during batch snapshot operations. This patch reuses the caller's existing connection instead of creating new ones: - isSecurityAvailable() now accepts a Connection parameter - writeAclToSnapshotDescription() passes the shared connection's Table to PermissionStorage.getTablePermissions() - All callers (MasterRpcServices, RestoreSnapshotProcedure, CloneSnapshotProcedure) pass through their available connection Signed-off-by: JeongMin Ju <mini666@apache.org>
1 parent 0c11338 commit c0497ca

13 files changed

Lines changed: 37 additions & 25 deletions

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,8 +1792,8 @@ public SnapshotResponse snapshot(RpcController controller, SnapshotRequest reque
17921792
LOG.info(server.getClientIdAuditPrefix() + " snapshot request for:"
17931793
+ ClientSnapshotDescriptionUtils.toString(request.getSnapshot()));
17941794
// get the snapshot information
1795-
SnapshotDescription snapshot =
1796-
SnapshotDescriptionUtils.validate(request.getSnapshot(), server.getConfiguration());
1795+
SnapshotDescription snapshot = SnapshotDescriptionUtils.validate(server.getConnection(),
1796+
request.getSnapshot(), server.getConfiguration());
17971797
// send back the max amount of time the client should wait for the snapshot to complete
17981798
long waitTime = SnapshotDescriptionUtils.getMaxMasterTimeout(server.getConfiguration(),
17991799
snapshot.getType(), SnapshotDescriptionUtils.DEFAULT_MAX_WAIT_TIME);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ private void restoreSnapshotAcl(MasterProcedureEnv env) throws IOException {
133133
Configuration conf = env.getMasterServices().getConfiguration();
134134
if (
135135
restoreAcl && snapshot.hasUsersAndPermissions() && snapshot.getUsersAndPermissions() != null
136-
&& SnapshotDescriptionUtils.isSecurityAvailable(conf)
136+
&& SnapshotDescriptionUtils.isSecurityAvailable(env.getMasterServices().getConnection())
137137
) {
138138
RestoreSnapshotHelper.restoreSnapshotAcl(snapshot, tableDescriptor.getTableName(), conf);
139139
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ private void addRegionsToInMemoryStates(List<RegionInfo> regionInfos, MasterProc
556556
private void restoreSnapshotAcl(final MasterProcedureEnv env) throws IOException {
557557
if (
558558
restoreAcl && snapshot.hasUsersAndPermissions() && snapshot.getUsersAndPermissions() != null
559-
&& SnapshotDescriptionUtils.isSecurityAvailable(env.getMasterServices().getConfiguration())
559+
&& SnapshotDescriptionUtils.isSecurityAvailable(env.getMasterServices().getConnection())
560560
) {
561561
// restore acl of snapshot to table.
562562
RestoreSnapshotHelper.restoreSnapshotAcl(snapshot, TableName.valueOf(snapshot.getTable()),

hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/PermissionStorage.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,12 @@ public static ListMultimap<String, UserPermission> getTablePermissions(Configura
486486
null, false);
487487
}
488488

489+
public static ListMultimap<String, UserPermission> getTablePermissions(Configuration conf,
490+
TableName tableName, Table t) throws IOException {
491+
return getPermissions(conf, tableName != null ? tableName.getName() : null, t, null, null, null,
492+
false);
493+
}
494+
489495
public static ListMultimap<String, UserPermission> getNamespacePermissions(Configuration conf,
490496
String namespace) throws IOException {
491497
return getPermissions(conf, Bytes.toBytes(toNamespaceEntry(namespace)), null, null, null, null,

hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotDescriptionUtils.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
import org.apache.hadoop.hbase.TableName;
3434
import org.apache.hadoop.hbase.client.Admin;
3535
import org.apache.hadoop.hbase.client.Connection;
36-
import org.apache.hadoop.hbase.client.ConnectionFactory;
36+
import org.apache.hadoop.hbase.client.Table;
3737
import org.apache.hadoop.hbase.ipc.RpcServer;
3838
import org.apache.hadoop.hbase.security.User;
3939
import org.apache.hadoop.hbase.security.access.AccessChecker;
@@ -294,14 +294,16 @@ private static Path getDefaultWorkingSnapshotDir(final Path rootDir) {
294294
* Convert the passed snapshot description into a 'full' snapshot description based on default
295295
* parameters, if none have been supplied. This resolves any 'optional' parameters that aren't
296296
* supplied to their default values.
297+
* @param conn connection to use for reading ACL information. Can be null if security is not
298+
* enabled.
297299
* @param snapshot general snapshot descriptor
298300
* @param conf Configuration to read configured snapshot defaults if snapshot is not complete
299301
* @return a valid snapshot description
300302
* @throws IllegalArgumentException if the {@link SnapshotDescription} is not a complete
301303
* {@link SnapshotDescription}.
302304
*/
303-
public static SnapshotDescription validate(SnapshotDescription snapshot, Configuration conf)
304-
throws IllegalArgumentException, IOException {
305+
public static SnapshotDescription validate(Connection conn, SnapshotDescription snapshot,
306+
Configuration conf) throws IllegalArgumentException, IOException {
305307
if (!snapshot.hasTable()) {
306308
throw new IllegalArgumentException(
307309
"Descriptor doesn't apply to a table, so we can't build it.");
@@ -350,8 +352,8 @@ public static SnapshotDescription validate(SnapshotDescription snapshot, Configu
350352
snapshot = builder.build();
351353

352354
// set the acl to snapshot if security feature is enabled.
353-
if (isSecurityAvailable(conf)) {
354-
snapshot = writeAclToSnapshotDescription(snapshot, conf);
355+
if (isSecurityAvailable(conn)) {
356+
snapshot = writeAclToSnapshotDescription(conn, snapshot, conf);
355357
}
356358
return snapshot;
357359
}
@@ -474,21 +476,22 @@ public static boolean isSnapshotOwner(org.apache.hadoop.hbase.client.SnapshotDes
474476
return user.getShortName().equals(snapshot.getOwner());
475477
}
476478

477-
public static boolean isSecurityAvailable(Configuration conf) throws IOException {
478-
try (Connection conn = ConnectionFactory.createConnection(conf);
479-
Admin admin = conn.getAdmin()) {
479+
public static boolean isSecurityAvailable(Connection conn) throws IOException {
480+
try (Admin admin = conn.getAdmin()) {
480481
return admin.tableExists(PermissionStorage.ACL_TABLE_NAME);
481482
}
482483
}
483484

484-
private static SnapshotDescription writeAclToSnapshotDescription(SnapshotDescription snapshot,
485-
Configuration conf) throws IOException {
485+
private static SnapshotDescription writeAclToSnapshotDescription(Connection conn,
486+
SnapshotDescription snapshot, Configuration conf) throws IOException {
486487
ListMultimap<String, UserPermission> perms =
487488
User.runAsLoginUser(new PrivilegedExceptionAction<ListMultimap<String, UserPermission>>() {
488489
@Override
489490
public ListMultimap<String, UserPermission> run() throws Exception {
490-
return PermissionStorage.getTablePermissions(conf,
491-
TableName.valueOf(snapshot.getTable()));
491+
try (Table aclTable = conn.getTable(PermissionStorage.ACL_TABLE_NAME)) {
492+
return PermissionStorage.getTablePermissions(conf,
493+
TableName.valueOf(snapshot.getTable()), aclTable);
494+
}
492495
}
493496
});
494497
return snapshot.toBuilder()

hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ public void testMergingRegionWhileTakingSnapshot() throws Exception {
371371
new SnapshotDescription("SnapshotProcedureTest", tableName, SnapshotType.FLUSH);
372372
SnapshotProtos.SnapshotDescription snapshotProto =
373373
ProtobufUtil.createHBaseProtosSnapshotDesc(snapshot);
374-
snapshotProto = SnapshotDescriptionUtils.validate(snapshotProto,
374+
snapshotProto = SnapshotDescriptionUtils.validate(null, snapshotProto,
375375
UTIL.getHBaseCluster().getMaster().getConfiguration());
376376
long snapshotProcId = procExec.submitProcedure(
377377
new TestSnapshotProcedure.DelaySnapshotProcedure(procExec.getEnvironment(), snapshotProto));

hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestSplitTableRegionProcedure.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ public void testSplitRegionWhileTakingSnapshot() throws Exception {
549549
new SnapshotDescription("SnapshotProcedureTest", tableName, SnapshotType.FLUSH);
550550
SnapshotProtos.SnapshotDescription snapshotProto =
551551
ProtobufUtil.createHBaseProtosSnapshotDesc(snapshot);
552-
snapshotProto = SnapshotDescriptionUtils.validate(snapshotProto,
552+
snapshotProto = SnapshotDescriptionUtils.validate(null, snapshotProto,
553553
UTIL.getHBaseCluster().getMaster().getConfiguration());
554554
long snapshotProcId = procExec.submitProcedure(
555555
new TestSnapshotProcedure.DelaySnapshotProcedure(procExec.getEnvironment(), snapshotProto));

hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestSnapshotProcedure.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ public void setup() throws Exception {
117117
SNAPSHOT_NAME = "SnapshotProcedureTest";
118118
snapshot = new SnapshotDescription(SNAPSHOT_NAME, TABLE_NAME, SnapshotType.FLUSH);
119119
snapshotProto = ProtobufUtil.createHBaseProtosSnapshotDesc(snapshot);
120-
snapshotProto = SnapshotDescriptionUtils.validate(snapshotProto, master.getConfiguration());
120+
snapshotProto =
121+
SnapshotDescriptionUtils.validate(null, snapshotProto, master.getConfiguration());
121122
final byte[][] splitKeys = new RegionSplitter.HexStringSplit().split(10);
122123
Table table = TEST_UTIL.createTable(TABLE_NAME, CF, splitKeys);
123124
TEST_UTIL.loadTable(table, CF, false);

hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestSnapshotProcedureEarlyExpiration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ public void setup() throws Exception { // Copied from TestSnapshotProcedure with
8181
properties);
8282

8383
snapshotProto = ProtobufUtil.createHBaseProtosSnapshotDesc(snapshot);
84-
snapshotProto = SnapshotDescriptionUtils.validate(snapshotProto, master.getConfiguration());
84+
snapshotProto =
85+
SnapshotDescriptionUtils.validate(null, snapshotProto, master.getConfiguration());
8586
final byte[][] splitKeys = new RegionSplitter.HexStringSplit().split(10);
8687
Table table = TEST_UTIL.createTable(TABLE_NAME, CF, splitKeys);
8788
TEST_UTIL.loadTable(table, CF, false);

hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestSnapshotRegionProcedure.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ public void setup() throws Exception {
8989
SnapshotDescription snapshot =
9090
new SnapshotDescription(SNAPSHOT_NAME, tableName, SnapshotType.FLUSH);
9191
snapshotProto = ProtobufUtil.createHBaseProtosSnapshotDesc(snapshot);
92-
snapshotProto = SnapshotDescriptionUtils.validate(snapshotProto, master.getConfiguration());
92+
snapshotProto =
93+
SnapshotDescriptionUtils.validate(null, snapshotProto, master.getConfiguration());
9394
final byte[][] splitKeys = new RegionSplitter.HexStringSplit().split(10);
9495
Table table = TEST_UTIL.createTable(tableName, cf, splitKeys);
9596
TEST_UTIL.loadTable(table, cf, false);

0 commit comments

Comments
 (0)