Skip to content

Commit ef77619

Browse files
committed
HBASE-26730 Extend hbase shell 'status' command to support an option 'tasks'
Expose monitored tasks state in ClusterStatus API via new option in ServerLoad. Add shell support for interrogating monitored tasks state in ServerLoad.
1 parent 3da23c2 commit ef77619

File tree

15 files changed

+481
-30
lines changed

15 files changed

+481
-30
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,12 @@ default double getAverageLoad() {
161161
*/
162162
Map<TableName, RegionStatesCount> getTableRegionStatesCount();
163163

164+
/**
165+
* Provide the list of master tasks
166+
*/
167+
@Nullable
168+
List<ServerTask> getMasterTasks();
169+
164170
/**
165171
* Kinds of ClusterMetrics
166172
*/
@@ -213,5 +219,9 @@ enum Option {
213219
* metrics about table to no of regions status count
214220
*/
215221
TABLE_TO_REGIONS_COUNT,
222+
/**
223+
* metrics about monitored tasks
224+
*/
225+
TASKS,
216226
}
217227
}

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

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ public static ClusterStatusProtos.ClusterStatus toClusterStatus(ClusterMetrics m
8383
if (metrics.getMasterName() != null) {
8484
builder.setMaster(ProtobufUtil.toServerName((metrics.getMasterName())));
8585
}
86+
if (metrics.getMasterTasks() != null) {
87+
builder.addAllMasterTasks(metrics.getMasterTasks().stream()
88+
.map(t -> ProtobufUtil.toServerTask(t)).collect(Collectors.toList()));
89+
}
8690
if (metrics.getBalancerOn() != null) {
8791
builder.setBalancerOn(metrics.getBalancerOn());
8892
}
@@ -122,7 +126,9 @@ public static ClusterMetrics toClusterMetrics(
122126
proto.getTableRegionStatesCountList().stream()
123127
.collect(Collectors.toMap(
124128
e -> ProtobufUtil.toTableName(e.getTableName()),
125-
e -> ProtobufUtil.toTableRegionStatesCount(e.getRegionStatesCount()))));
129+
e -> ProtobufUtil.toTableRegionStatesCount(e.getRegionStatesCount()))))
130+
.setMasterTasks(proto.getMasterTasksList().stream()
131+
.map(t -> ProtobufUtil.getServerTask(t)).collect(Collectors.toList()));
126132
if (proto.hasClusterId()) {
127133
builder.setClusterId(ClusterId.convert(proto.getClusterId()).toString());
128134
}
@@ -164,6 +170,7 @@ public static ClusterMetrics.Option toOption(ClusterStatusProtos.Option option)
164170
case SERVERS_NAME: return ClusterMetrics.Option.SERVERS_NAME;
165171
case MASTER_INFO_PORT: return ClusterMetrics.Option.MASTER_INFO_PORT;
166172
case TABLE_TO_REGIONS_COUNT: return ClusterMetrics.Option.TABLE_TO_REGIONS_COUNT;
173+
case TASKS: return ClusterMetrics.Option.TASKS;
167174
// should not reach here
168175
default: throw new IllegalArgumentException("Invalid option: " + option);
169176
}
@@ -188,6 +195,7 @@ public static ClusterStatusProtos.Option toOption(ClusterMetrics.Option option)
188195
case SERVERS_NAME: return Option.SERVERS_NAME;
189196
case MASTER_INFO_PORT: return ClusterStatusProtos.Option.MASTER_INFO_PORT;
190197
case TABLE_TO_REGIONS_COUNT: return ClusterStatusProtos.Option.TABLE_TO_REGIONS_COUNT;
198+
case TASKS: return ClusterStatusProtos.Option.TASKS;
191199
// should not reach here
192200
default: throw new IllegalArgumentException("Invalid option: " + option);
193201
}
@@ -231,6 +239,8 @@ public static ClusterMetricsBuilder newBuilder() {
231239
private int masterInfoPort;
232240
private List<ServerName> serversName = Collections.emptyList();
233241
private Map<TableName, RegionStatesCount> tableRegionStatesCount = Collections.emptyMap();
242+
@Nullable
243+
private List<ServerTask> masterTasks;
234244

235245
private ClusterMetricsBuilder() {
236246
}
@@ -280,6 +290,10 @@ public ClusterMetricsBuilder setServerNames(List<ServerName> serversName) {
280290
this.serversName = serversName;
281291
return this;
282292
}
293+
public ClusterMetricsBuilder setMasterTasks(List<ServerTask> masterTasks) {
294+
this.masterTasks = masterTasks;
295+
return this;
296+
}
283297

284298
public ClusterMetricsBuilder setTableRegionStatesCount(
285299
Map<TableName, RegionStatesCount> tableRegionStatesCount) {
@@ -300,7 +314,8 @@ public ClusterMetrics build() {
300314
balancerOn,
301315
masterInfoPort,
302316
serversName,
303-
tableRegionStatesCount
317+
tableRegionStatesCount,
318+
masterTasks
304319
);
305320
}
306321
private static class ClusterMetricsImpl implements ClusterMetrics {
@@ -320,6 +335,7 @@ private static class ClusterMetricsImpl implements ClusterMetrics {
320335
private final int masterInfoPort;
321336
private final List<ServerName> serversName;
322337
private final Map<TableName, RegionStatesCount> tableRegionStatesCount;
338+
private final List<ServerTask> masterTasks;
323339

324340
ClusterMetricsImpl(String hbaseVersion, List<ServerName> deadServerNames,
325341
Map<ServerName, ServerMetrics> liveServerMetrics,
@@ -331,7 +347,8 @@ private static class ClusterMetricsImpl implements ClusterMetrics {
331347
Boolean balancerOn,
332348
int masterInfoPort,
333349
List<ServerName> serversName,
334-
Map<TableName, RegionStatesCount> tableRegionStatesCount) {
350+
Map<TableName, RegionStatesCount> tableRegionStatesCount,
351+
List<ServerTask> masterTasks) {
335352
this.hbaseVersion = hbaseVersion;
336353
this.deadServerNames = Preconditions.checkNotNull(deadServerNames);
337354
this.liveServerMetrics = Preconditions.checkNotNull(liveServerMetrics);
@@ -344,6 +361,7 @@ private static class ClusterMetricsImpl implements ClusterMetrics {
344361
this.masterInfoPort = masterInfoPort;
345362
this.serversName = serversName;
346363
this.tableRegionStatesCount = Preconditions.checkNotNull(tableRegionStatesCount);
364+
this.masterTasks = masterTasks;
347365
}
348366

349367
@Override
@@ -406,6 +424,11 @@ public Map<TableName, RegionStatesCount> getTableRegionStatesCount() {
406424
return Collections.unmodifiableMap(tableRegionStatesCount);
407425
}
408426

427+
@Override
428+
public List<ServerTask> getMasterTasks() {
429+
return masterTasks;
430+
}
431+
409432
@Override
410433
public String toString() {
411434
StringBuilder sb = new StringBuilder(1024);

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,11 @@ default String getVersion() {
124124
*/
125125
long getLastReportTimestamp();
126126

127+
/**
128+
* Called directly from clients such as the hbase shell
129+
* @return the active monitored tasks
130+
*/
131+
@Nullable
132+
List<ServerTask> getTasks();
133+
127134
}

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

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ public static ServerMetrics toServerMetrics(ServerName serverName, int versionNu
8787
.setReplicationLoadSink(serverLoadPB.hasReplLoadSink()
8888
? ProtobufUtil.toReplicationLoadSink(serverLoadPB.getReplLoadSink())
8989
: null)
90+
.setTasks(serverLoadPB.getTasksList().stream()
91+
.map(ProtobufUtil::getServerTask).collect(Collectors.toList()))
9092
.setReportTimestamp(serverLoadPB.getReportEndTime())
9193
.setLastReportTimestamp(serverLoadPB.getReportStartTime()).setVersionNumber(versionNumber)
9294
.setVersion(version).build();
@@ -105,19 +107,24 @@ public static ClusterStatusProtos.ServerLoad toServerLoad(ServerMetrics metrics)
105107
.setInfoServerPort(metrics.getInfoServerPort())
106108
.setMaxHeapMB((int) metrics.getMaxHeapSize().get(Size.Unit.MEGABYTE))
107109
.setUsedHeapMB((int) metrics.getUsedHeapSize().get(Size.Unit.MEGABYTE))
108-
.addAllCoprocessors(toCoprocessor(metrics.getCoprocessorNames())).addAllRegionLoads(
110+
.addAllCoprocessors(toCoprocessor(metrics.getCoprocessorNames()))
111+
.addAllRegionLoads(
109112
metrics.getRegionMetrics().values().stream().map(RegionMetricsBuilder::toRegionLoad)
110-
.collect(Collectors.toList())).addAllUserLoads(
113+
.collect(Collectors.toList()))
114+
.addAllUserLoads(
111115
metrics.getUserMetrics().values().stream().map(UserMetricsBuilder::toUserMetrics)
112-
.collect(Collectors.toList())).addAllReplLoadSource(
116+
.collect(Collectors.toList()))
117+
.addAllReplLoadSource(
113118
metrics.getReplicationLoadSourceList().stream()
114119
.map(ProtobufUtil::toReplicationLoadSource).collect(Collectors.toList()))
120+
.addAllTasks(
121+
metrics.getTasks().stream().map(ProtobufUtil::toServerTask)
122+
.collect(Collectors.toList()))
115123
.setReportStartTime(metrics.getLastReportTimestamp())
116124
.setReportEndTime(metrics.getReportTimestamp());
117125
if (metrics.getReplicationLoadSink() != null) {
118126
builder.setReplLoadSink(ProtobufUtil.toReplicationLoadSink(metrics.getReplicationLoadSink()));
119127
}
120-
121128
return builder.build();
122129
}
123130

@@ -143,6 +150,8 @@ public static ServerMetricsBuilder newBuilder(ServerName sn) {
143150
private final Set<String> coprocessorNames = new TreeSet<>();
144151
private long reportTimestamp = EnvironmentEdgeManager.currentTime();
145152
private long lastReportTimestamp = 0;
153+
private final List<ServerTask> tasks = new ArrayList<>();
154+
146155
private ServerMetricsBuilder(ServerName serverName) {
147156
this.serverName = serverName;
148157
}
@@ -228,6 +237,11 @@ public ServerMetricsBuilder setLastReportTimestamp(long value) {
228237
return this;
229238
}
230239

240+
public ServerMetricsBuilder setTasks(List<ServerTask> tasks) {
241+
this.tasks.addAll(tasks);
242+
return this;
243+
}
244+
231245
public ServerMetrics build() {
232246
return new ServerMetricsImpl(
233247
serverName,
@@ -246,7 +260,8 @@ public ServerMetrics build() {
246260
coprocessorNames,
247261
reportTimestamp,
248262
lastReportTimestamp,
249-
userMetrics);
263+
userMetrics,
264+
tasks);
250265
}
251266

252267
private static class ServerMetricsImpl implements ServerMetrics {
@@ -268,13 +283,15 @@ private static class ServerMetricsImpl implements ServerMetrics {
268283
private final long reportTimestamp;
269284
private final long lastReportTimestamp;
270285
private final Map<byte[], UserMetrics> userMetrics;
286+
private final List<ServerTask> tasks;
271287

272288
ServerMetricsImpl(ServerName serverName, int versionNumber, String version,
273289
long requestCountPerSecond, long requestCount, long readRequestsCount,
274290
long writeRequestsCount, Size usedHeapSize, Size maxHeapSize,
275291
int infoServerPort, List<ReplicationLoadSource> sources, ReplicationLoadSink sink,
276292
Map<byte[], RegionMetrics> regionStatus, Set<String> coprocessorNames,
277-
long reportTimestamp, long lastReportTimestamp, Map<byte[], UserMetrics> userMetrics) {
293+
long reportTimestamp, long lastReportTimestamp, Map<byte[], UserMetrics> userMetrics,
294+
List<ServerTask> tasks) {
278295
this.serverName = Preconditions.checkNotNull(serverName);
279296
this.versionNumber = versionNumber;
280297
this.version = version;
@@ -292,6 +309,7 @@ private static class ServerMetricsImpl implements ServerMetrics {
292309
this.coprocessorNames =Preconditions.checkNotNull(coprocessorNames);
293310
this.reportTimestamp = reportTimestamp;
294311
this.lastReportTimestamp = lastReportTimestamp;
312+
this.tasks = tasks;
295313
}
296314

297315
@Override
@@ -388,6 +406,11 @@ public long getLastReportTimestamp() {
388406
return lastReportTimestamp;
389407
}
390408

409+
@Override
410+
public List<ServerTask> getTasks() {
411+
return tasks;
412+
}
413+
391414
@Override
392415
public String toString() {
393416
int storeCount = 0;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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;
19+
20+
import org.apache.yetus.audience.InterfaceAudience;
21+
22+
/** Information about active monitored server tasks */
23+
@InterfaceAudience.Public
24+
public interface ServerTask {
25+
26+
/** Task state */
27+
enum State {
28+
RUNNING,
29+
WAITING,
30+
COMPLETE,
31+
ABORTED;
32+
}
33+
34+
/**
35+
* @return the task's description, typically a name
36+
*/
37+
String getDescription();
38+
39+
/**
40+
* @return the task's current status
41+
*/
42+
String getStatus();
43+
44+
/**
45+
* @return the task's current state
46+
*/
47+
State getState();
48+
49+
/**
50+
* @return the time when the task started, or 0 if it has not started yet
51+
*/
52+
long getStartTime();
53+
54+
/**
55+
* @return the time when the task completed, or 0 if it has not completed yet
56+
*/
57+
long getCompletionTime();
58+
59+
}

0 commit comments

Comments
 (0)