Skip to content

Commit 0ee15e0

Browse files
ndimidukjoshelser
andcommitted
HBASE-26474 Implement connection-level attributes (#4014)
Add support for `db.system`, `db.connection_string`, `db.user`. Signed-off-by: Duo Zhang <zhangduo@apache.org> Signed-off-by: Huaxiang Sun <huaxiangsun@apache.org> Co-authored-by: Josh Elser <josh.elser@gmail.com>
1 parent 5d14589 commit 0ee15e0

26 files changed

+733
-175
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,11 @@ public CompletableFuture<ServerName> getActiveMaster() {
272272
getClass().getSimpleName() + ".getActiveMaster");
273273
}
274274

275+
@Override
276+
public String getConnectionString() {
277+
return "unimplemented";
278+
}
279+
275280
@Override
276281
public void close() {
277282
trace(() -> {

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
* The implementation of AsyncConnection.
7272
*/
7373
@InterfaceAudience.Private
74-
class AsyncConnectionImpl implements AsyncConnection {
74+
public class AsyncConnectionImpl implements AsyncConnection {
7575

7676
private static final Logger LOG = LoggerFactory.getLogger(AsyncConnectionImpl.class);
7777

@@ -191,6 +191,14 @@ synchronized ChoreService getChoreService() {
191191
return choreService;
192192
}
193193

194+
public User getUser() {
195+
return user;
196+
}
197+
198+
public ConnectionRegistry getConnectionRegistry() {
199+
return registry;
200+
}
201+
194202
@Override
195203
public Configuration getConfiguration() {
196204
return conf;

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

Lines changed: 48 additions & 21 deletions
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
@@ -20,24 +20,27 @@
2020
import static org.apache.hadoop.hbase.TableName.META_TABLE_NAME;
2121
import static org.apache.hadoop.hbase.trace.HBaseSemanticAttributes.REGION_NAMES_KEY;
2222
import static org.apache.hadoop.hbase.trace.HBaseSemanticAttributes.SERVER_NAME_KEY;
23-
import static org.apache.hadoop.hbase.trace.TraceUtil.createSpan;
24-
import static org.apache.hadoop.hbase.trace.TraceUtil.createTableSpan;
2523
import static org.apache.hadoop.hbase.util.FutureUtils.addListener;
2624

2725
import io.opentelemetry.api.trace.Span;
2826
import io.opentelemetry.api.trace.StatusCode;
2927
import io.opentelemetry.context.Scope;
30-
import java.util.ArrayList;
3128
import java.util.Arrays;
29+
import java.util.Collections;
3230
import java.util.List;
31+
import java.util.Objects;
32+
import java.util.Optional;
3333
import java.util.concurrent.CompletableFuture;
3434
import java.util.concurrent.TimeUnit;
3535
import java.util.function.Function;
3636
import java.util.function.Supplier;
37+
import java.util.stream.Collectors;
3738
import org.apache.hadoop.hbase.HRegionLocation;
3839
import org.apache.hadoop.hbase.RegionLocations;
3940
import org.apache.hadoop.hbase.ServerName;
4041
import org.apache.hadoop.hbase.TableName;
42+
import org.apache.hadoop.hbase.client.trace.ConnectionSpanBuilder;
43+
import org.apache.hadoop.hbase.client.trace.TableSpanBuilder;
4144
import org.apache.hadoop.hbase.exceptions.TimeoutIOException;
4245
import org.apache.hadoop.hbase.trace.TraceUtil;
4346
import org.apache.hadoop.hbase.util.Bytes;
@@ -95,9 +98,12 @@ private boolean isMeta(TableName tableName) {
9598
return TableName.isMetaTableName(tableName);
9699
}
97100

98-
private <T> CompletableFuture<T> tracedLocationFuture(Supplier<CompletableFuture<T>> action,
99-
Function<T, List<String>> getRegionNames, TableName tableName, String methodName) {
100-
Span span = createTableSpan("AsyncRegionLocator." + methodName, tableName);
101+
private <T> CompletableFuture<T> tracedLocationFuture(
102+
Supplier<CompletableFuture<T>> action,
103+
Function<T, List<String>> getRegionNames,
104+
Supplier<Span> spanSupplier
105+
) {
106+
final Span span = spanSupplier.get();
101107
try (Scope scope = span.makeCurrent()) {
102108
CompletableFuture<T> future = action.get();
103109
FutureUtils.addListener(future, (resp, error) -> {
@@ -116,18 +122,30 @@ private <T> CompletableFuture<T> tracedLocationFuture(Supplier<CompletableFuture
116122
}
117123
}
118124

119-
private List<String> getRegionName(RegionLocations locs) {
120-
List<String> names = new ArrayList<>();
121-
for (HRegionLocation loc : locs.getRegionLocations()) {
122-
if (loc != null) {
123-
names.add(loc.getRegion().getRegionNameAsString());
124-
}
125+
static List<String> getRegionNames(RegionLocations locs) {
126+
if (locs == null || locs.getRegionLocations() == null) {
127+
return Collections.emptyList();
125128
}
126-
return names;
129+
return Arrays.stream(locs.getRegionLocations())
130+
.filter(Objects::nonNull)
131+
.map(HRegionLocation::getRegion)
132+
.map(RegionInfo::getRegionNameAsString)
133+
.collect(Collectors.toList());
134+
}
135+
136+
static List<String> getRegionNames(HRegionLocation location) {
137+
return Optional.ofNullable(location)
138+
.map(HRegionLocation::getRegion)
139+
.map(RegionInfo::getRegionNameAsString)
140+
.map(Collections::singletonList)
141+
.orElseGet(Collections::emptyList);
127142
}
128143

129144
CompletableFuture<RegionLocations> getRegionLocations(TableName tableName, byte[] row,
130145
RegionLocateType type, boolean reload, long timeoutNs) {
146+
final Supplier<Span> supplier = new TableSpanBuilder(conn)
147+
.setName("AsyncRegionLocator.getRegionLocations")
148+
.setTableName(tableName);
131149
return tracedLocationFuture(() -> {
132150
CompletableFuture<RegionLocations> future = isMeta(tableName) ?
133151
metaRegionLocator.getRegionLocations(RegionReplicaUtil.DEFAULT_REPLICA_ID, reload) :
@@ -137,11 +155,14 @@ CompletableFuture<RegionLocations> getRegionLocations(TableName tableName, byte[
137155
() -> "Timeout(" + TimeUnit.NANOSECONDS.toMillis(timeoutNs) +
138156
"ms) waiting for region locations for " + tableName + ", row='" +
139157
Bytes.toStringBinary(row) + "'");
140-
}, this::getRegionName, tableName, "getRegionLocations");
158+
}, AsyncRegionLocator::getRegionNames, supplier);
141159
}
142160

143161
CompletableFuture<HRegionLocation> getRegionLocation(TableName tableName, byte[] row,
144162
int replicaId, RegionLocateType type, boolean reload, long timeoutNs) {
163+
final Supplier<Span> supplier = new TableSpanBuilder(conn)
164+
.setName("AsyncRegionLocator.getRegionLocation")
165+
.setTableName(tableName);
145166
return tracedLocationFuture(() -> {
146167
// meta region can not be split right now so we always call the same method.
147168
// Change it later if the meta table can have more than one regions.
@@ -172,8 +193,7 @@ CompletableFuture<HRegionLocation> getRegionLocation(TableName tableName, byte[]
172193
() -> "Timeout(" + TimeUnit.NANOSECONDS.toMillis(timeoutNs) +
173194
"ms) waiting for region location for " + tableName + ", row='" +
174195
Bytes.toStringBinary(row) + "', replicaId=" + replicaId);
175-
}, loc -> Arrays.asList(loc.getRegion().getRegionNameAsString()), tableName,
176-
"getRegionLocation");
196+
}, AsyncRegionLocator::getRegionNames, supplier);
177197
}
178198

179199
CompletableFuture<HRegionLocation> getRegionLocation(TableName tableName, byte[] row,
@@ -201,31 +221,38 @@ void updateCachedLocationOnError(HRegionLocation loc, Throwable exception) {
201221
}
202222

203223
void clearCache(TableName tableName) {
224+
Supplier<Span> supplier = new TableSpanBuilder(conn)
225+
.setName("AsyncRegionLocator.clearCache")
226+
.setTableName(tableName);
204227
TraceUtil.trace(() -> {
205228
LOG.debug("Clear meta cache for {}", tableName);
206229
if (tableName.equals(META_TABLE_NAME)) {
207230
metaRegionLocator.clearCache();
208231
} else {
209232
nonMetaRegionLocator.clearCache(tableName);
210233
}
211-
}, () -> createTableSpan("AsyncRegionLocator.clearCache", tableName));
234+
}, supplier);
212235
}
213236

214237
void clearCache(ServerName serverName) {
238+
Supplier<Span> supplier = new ConnectionSpanBuilder(conn)
239+
.setName("AsyncRegionLocator.clearCache")
240+
.addAttribute(SERVER_NAME_KEY, serverName.getServerName());
215241
TraceUtil.trace(() -> {
216242
LOG.debug("Clear meta cache for {}", serverName);
217243
metaRegionLocator.clearCache(serverName);
218244
nonMetaRegionLocator.clearCache(serverName);
219245
conn.getConnectionMetrics().ifPresent(MetricsConnection::incrMetaCacheNumClearServer);
220-
}, () -> createSpan("AsyncRegionLocator.clearCache").setAttribute(SERVER_NAME_KEY,
221-
serverName.getServerName()));
246+
}, supplier);
222247
}
223248

224249
void clearCache() {
250+
Supplier<Span> supplier = new ConnectionSpanBuilder(conn)
251+
.setName("AsyncRegionLocator.clearCache");
225252
TraceUtil.trace(() -> {
226253
metaRegionLocator.clearCache();
227254
nonMetaRegionLocator.clearCache();
228-
}, "AsyncRegionLocator.clearCache");
255+
}, supplier);
229256
}
230257

231258
AsyncNonMetaRegionLocator getNonMetaRegionLocator() {

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
3232
import org.apache.hadoop.hbase.client.backoff.ClientBackoffPolicy;
3333
import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
34+
import org.apache.hadoop.hbase.security.User;
3435
import org.apache.yetus.audience.InterfaceAudience;
3536

3637
import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.AdminService;
@@ -175,8 +176,7 @@ void updateCachedLocations(TableName tableName, byte[] regionName, byte[] rowkey
175176
* question
176177
* @throws IOException if a remote or network exception occurs
177178
*/
178-
HRegionLocation locateRegion(final byte[] regionName)
179-
throws IOException;
179+
HRegionLocation locateRegion(final byte[] regionName) throws IOException;
180180

181181
/**
182182
* Gets the locations of all regions in the specified table, <i>tableName</i>.
@@ -335,4 +335,14 @@ List<ServerName> getLiveRegionServers(Supplier<ServerName> masterAddrTracker, in
335335
* Get the bootstrap node list of another region server.
336336
*/
337337
List<ServerName> getAllBootstrapNodes(ServerName regionServer) throws IOException;
338+
339+
/**
340+
* Get the {@link User} associated with this connection. May be {@code null}.
341+
*/
342+
User getUser();
343+
344+
/**
345+
* Get the {@link ConnectionRegistry} used to orient this cluster.
346+
*/
347+
ConnectionRegistry getConnectionRegistry();
338348
}

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@
166166
value="AT_OPERATION_SEQUENCE_ON_CONCURRENT_ABSTRACTION",
167167
justification="Access to the conncurrent hash map is under a lock so should be fine.")
168168
@InterfaceAudience.Private
169-
class ConnectionImplementation implements ClusterConnection, Closeable {
169+
public class ConnectionImplementation implements ClusterConnection, Closeable {
170170
public static final String RETRIES_BY_SERVER_KEY = "hbase.client.retries.by.server";
171171
private static final Logger LOG = LoggerFactory.getLogger(ConnectionImplementation.class);
172172

@@ -513,6 +513,16 @@ public MetricsConnection getConnectionMetrics() {
513513
return this.metrics;
514514
}
515515

516+
@Override
517+
public User getUser() {
518+
return user;
519+
}
520+
521+
@Override
522+
public ConnectionRegistry getConnectionRegistry() {
523+
return registry;
524+
}
525+
516526
private ThreadPoolExecutor getBatchPool() {
517527
if (batchPool == null) {
518528
synchronized (this) {

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
* Internal use only.
3030
*/
3131
@InterfaceAudience.Private
32-
interface ConnectionRegistry extends Closeable {
32+
public interface ConnectionRegistry extends Closeable {
3333

3434
/**
3535
* Get the location of meta region(s).
@@ -48,6 +48,13 @@ interface ConnectionRegistry extends Closeable {
4848
*/
4949
CompletableFuture<ServerName> getActiveMaster();
5050

51+
/**
52+
* Return the connection string associated with this registry instance. This value is
53+
* informational, used for annotating traces. Values returned may not be valid for establishing a
54+
* working cluster connection.
55+
*/
56+
String getConnectionString();
57+
5158
/**
5259
* Closes this instance and releases any system resources associated with it
5360
*/

0 commit comments

Comments
 (0)