1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase;
21
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.Map;
28
29 import org.apache.hadoop.hbase.util.ByteStringer;
30 import org.apache.hadoop.hbase.classification.InterfaceAudience;
31 import org.apache.hadoop.hbase.classification.InterfaceStability;
32 import org.apache.hadoop.hbase.master.RegionState;
33 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
34 import org.apache.hadoop.hbase.protobuf.generated.ClusterStatusProtos;
35 import org.apache.hadoop.hbase.protobuf.generated.ClusterStatusProtos.LiveServerInfo;
36 import org.apache.hadoop.hbase.protobuf.generated.ClusterStatusProtos.RegionInTransition;
37 import org.apache.hadoop.hbase.protobuf.generated.FSProtos.HBaseVersionFileContent;
38 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
39 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier;
40 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType;
41 import org.apache.hadoop.hbase.util.Bytes;
42 import org.apache.hadoop.io.VersionedWritable;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 @InterfaceAudience.Public
64 @InterfaceStability.Evolving
65 public class ClusterStatus extends VersionedWritable {
66
67
68
69
70
71
72
73
74
75
76 private static final byte VERSION = 2;
77
78 private String hbaseVersion;
79 private Map<ServerName, ServerLoad> liveServers;
80 private Collection<ServerName> deadServers;
81 private ServerName master;
82 private Collection<ServerName> backupMasters;
83 private Map<String, RegionState> intransition;
84 private String clusterId;
85 private String[] masterCoprocessors;
86 private Boolean balancerOn;
87
88
89
90
91
92
93
94
95 @Deprecated
96 public ClusterStatus() {
97 super();
98 }
99
100 public ClusterStatus(final String hbaseVersion, final String clusterid,
101 final Map<ServerName, ServerLoad> servers,
102 final Collection<ServerName> deadServers,
103 final ServerName master,
104 final Collection<ServerName> backupMasters,
105 final Map<String, RegionState> rit,
106 final String[] masterCoprocessors,
107 final Boolean balancerOn) {
108 this.hbaseVersion = hbaseVersion;
109
110 this.liveServers = servers;
111 this.deadServers = deadServers;
112 this.master = master;
113 this.backupMasters = backupMasters;
114 this.intransition = rit;
115 this.clusterId = clusterid;
116 this.masterCoprocessors = masterCoprocessors;
117 this.balancerOn = balancerOn;
118 }
119
120
121
122
123 public Collection<ServerName> getDeadServerNames() {
124 if (deadServers == null) {
125 return Collections.<ServerName>emptyList();
126 }
127 return Collections.unmodifiableCollection(deadServers);
128 }
129
130
131
132
133 public int getServersSize() {
134 return liveServers != null ? liveServers.size() : 0;
135 }
136
137
138
139
140 public int getDeadServers() {
141 return deadServers != null ? deadServers.size() : 0;
142 }
143
144
145
146
147 public double getAverageLoad() {
148 int load = getRegionsCount();
149 return (double)load / (double)getServersSize();
150 }
151
152
153
154
155 public int getRegionsCount() {
156 int count = 0;
157 if (liveServers != null && !liveServers.isEmpty()) {
158 for (Map.Entry<ServerName, ServerLoad> e: this.liveServers.entrySet()) {
159 count += e.getValue().getNumberOfRegions();
160 }
161 }
162 return count;
163 }
164
165
166
167
168 public int getRequestsCount() {
169 int count = 0;
170 if (liveServers != null && !liveServers.isEmpty()) {
171 for (Map.Entry<ServerName, ServerLoad> e: this.liveServers.entrySet()) {
172 count += e.getValue().getNumberOfRequests();
173 }
174 }
175 return count;
176 }
177
178
179
180
181 public String getHBaseVersion() {
182 return hbaseVersion;
183 }
184
185
186
187
188 public boolean equals(Object o) {
189 if (this == o) {
190 return true;
191 }
192 if (!(o instanceof ClusterStatus)) {
193 return false;
194 }
195 return (getVersion() == ((ClusterStatus)o).getVersion()) &&
196 getHBaseVersion().equals(((ClusterStatus)o).getHBaseVersion()) &&
197 this.liveServers.equals(((ClusterStatus)o).liveServers) &&
198 this.deadServers.containsAll(((ClusterStatus)o).deadServers) &&
199 Arrays.equals(this.masterCoprocessors,
200 ((ClusterStatus)o).masterCoprocessors) &&
201 this.master.equals(((ClusterStatus)o).master) &&
202 this.backupMasters.containsAll(((ClusterStatus)o).backupMasters);
203 }
204
205
206
207
208 public int hashCode() {
209 return VERSION + hbaseVersion.hashCode() + this.liveServers.hashCode() +
210 this.deadServers.hashCode() + this.master.hashCode() +
211 this.backupMasters.hashCode();
212 }
213
214
215 public byte getVersion() {
216 return VERSION;
217 }
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232 @Deprecated
233 public Collection<ServerName> getServerInfo() {
234 return getServers();
235 }
236
237 public Collection<ServerName> getServers() {
238 if (liveServers == null) {
239 return Collections.<ServerName>emptyList();
240 }
241 return Collections.unmodifiableCollection(this.liveServers.keySet());
242 }
243
244
245
246
247
248 public ServerName getMaster() {
249 return this.master;
250 }
251
252
253
254
255 public int getBackupMastersSize() {
256 return backupMasters != null ? backupMasters.size() : 0;
257 }
258
259
260
261
262 public Collection<ServerName> getBackupMasters() {
263 if (backupMasters == null) {
264 return Collections.<ServerName>emptyList();
265 }
266 return Collections.unmodifiableCollection(this.backupMasters);
267 }
268
269
270
271
272
273 public ServerLoad getLoad(final ServerName sn) {
274 return liveServers != null ? liveServers.get(sn) : null;
275 }
276
277 @InterfaceAudience.Private
278 public Map<String, RegionState> getRegionsInTransition() {
279 if (intransition == null) {
280 return Collections.EMPTY_MAP;
281 }
282 return Collections.unmodifiableMap(intransition);
283 }
284
285 public String getClusterId() {
286 return clusterId;
287 }
288
289 public String[] getMasterCoprocessors() {
290 return masterCoprocessors;
291 }
292
293 public long getLastMajorCompactionTsForTable(TableName table) {
294 long result = Long.MAX_VALUE;
295 for (ServerName server : getServers()) {
296 ServerLoad load = getLoad(server);
297 for (RegionLoad rl : load.getRegionsLoad().values()) {
298 if (table.equals(HRegionInfo.getTable(rl.getName()))) {
299 result = Math.min(result, rl.getLastMajorCompactionTs());
300 }
301 }
302 }
303 return result == Long.MAX_VALUE ? 0 : result;
304 }
305
306 public long getLastMajorCompactionTsForRegion(final byte[] region) {
307 for (ServerName server : getServers()) {
308 ServerLoad load = getLoad(server);
309 RegionLoad rl = load.getRegionsLoad().get(region);
310 if (rl != null) {
311 return rl.getLastMajorCompactionTs();
312 }
313 }
314 return 0;
315 }
316
317 public boolean isBalancerOn() {
318 return balancerOn != null && balancerOn;
319 }
320
321 public Boolean getBalancerOn() {
322 return balancerOn;
323 }
324
325 public String toString() {
326 StringBuilder sb = new StringBuilder(1024);
327 sb.append("Master: " + master);
328
329 int backupMastersSize = getBackupMastersSize();
330 sb.append("\nNumber of backup masters: " + backupMastersSize);
331 if (backupMastersSize > 0) {
332 for (ServerName serverName: backupMasters) {
333 sb.append("\n " + serverName);
334 }
335 }
336
337 int serversSize = getServersSize();
338 sb.append("\nNumber of live region servers: " + serversSize);
339 if (serversSize > 0) {
340 for (ServerName serverName: liveServers.keySet()) {
341 sb.append("\n " + serverName.getServerName());
342 }
343 }
344
345 int deadServerSize = getDeadServers();
346 sb.append("\nNumber of dead region servers: " + deadServerSize);
347 if (deadServerSize > 0) {
348 for (ServerName serverName: deadServers) {
349 sb.append("\n " + serverName);
350 }
351 }
352
353 sb.append("\nAverage load: " + getAverageLoad());
354 sb.append("\nNumber of requests: " + getRequestsCount());
355 sb.append("\nNumber of regions: " + getRegionsCount());
356
357 int ritSize = (intransition != null) ? intransition.size() : 0;
358 sb.append("\nNumber of regions in transition: " + ritSize);
359 if (ritSize > 0) {
360 for (RegionState state: intransition.values()) {
361 sb.append("\n " + state.toDescriptiveString());
362 }
363 }
364 return sb.toString();
365 }
366
367
368
369
370
371
372 public ClusterStatusProtos.ClusterStatus convert() {
373 ClusterStatusProtos.ClusterStatus.Builder builder =
374 ClusterStatusProtos.ClusterStatus.newBuilder();
375 builder.setHbaseVersion(HBaseVersionFileContent.newBuilder().setVersion(getHBaseVersion()));
376
377 if (liveServers != null){
378 for (Map.Entry<ServerName, ServerLoad> entry : liveServers.entrySet()) {
379 LiveServerInfo.Builder lsi =
380 LiveServerInfo.newBuilder().setServer(ProtobufUtil.toServerName(entry.getKey()));
381 lsi.setServerLoad(entry.getValue().obtainServerLoadPB());
382 builder.addLiveServers(lsi.build());
383 }
384 }
385
386 if (deadServers != null){
387 for (ServerName deadServer : deadServers) {
388 builder.addDeadServers(ProtobufUtil.toServerName(deadServer));
389 }
390 }
391
392 if (intransition != null) {
393 for (Map.Entry<String, RegionState> rit : getRegionsInTransition().entrySet()) {
394 ClusterStatusProtos.RegionState rs = rit.getValue().convert();
395 RegionSpecifier.Builder spec =
396 RegionSpecifier.newBuilder().setType(RegionSpecifierType.REGION_NAME);
397 spec.setValue(ByteStringer.wrap(Bytes.toBytes(rit.getKey())));
398
399 RegionInTransition pbRIT =
400 RegionInTransition.newBuilder().setSpec(spec.build()).setRegionState(rs).build();
401 builder.addRegionsInTransition(pbRIT);
402 }
403 }
404
405 if (clusterId != null) {
406 builder.setClusterId(new ClusterId(clusterId).convert());
407 }
408
409 if (masterCoprocessors != null) {
410 for (String coprocessor : masterCoprocessors) {
411 builder.addMasterCoprocessors(HBaseProtos.Coprocessor.newBuilder().setName(coprocessor));
412 }
413 }
414
415 if (master != null){
416 builder.setMaster(ProtobufUtil.toServerName(getMaster()));
417 }
418
419 if (backupMasters != null) {
420 for (ServerName backup : backupMasters) {
421 builder.addBackupMasters(ProtobufUtil.toServerName(backup));
422 }
423 }
424
425 if (balancerOn != null){
426 builder.setBalancerOn(balancerOn);
427 }
428
429 return builder.build();
430 }
431
432
433
434
435
436
437
438 public static ClusterStatus convert(ClusterStatusProtos.ClusterStatus proto) {
439
440 Map<ServerName, ServerLoad> servers = null;
441 if (proto.getLiveServersList() != null) {
442 servers = new HashMap<ServerName, ServerLoad>(proto.getLiveServersList().size());
443 for (LiveServerInfo lsi : proto.getLiveServersList()) {
444 servers.put(ProtobufUtil.toServerName(
445 lsi.getServer()), new ServerLoad(lsi.getServerLoad()));
446 }
447 }
448
449 Collection<ServerName> deadServers = null;
450 if (proto.getDeadServersList() != null) {
451 deadServers = new ArrayList<ServerName>(proto.getDeadServersList().size());
452 for (HBaseProtos.ServerName sn : proto.getDeadServersList()) {
453 deadServers.add(ProtobufUtil.toServerName(sn));
454 }
455 }
456
457 Collection<ServerName> backupMasters = null;
458 if (proto.getBackupMastersList() != null) {
459 backupMasters = new ArrayList<ServerName>(proto.getBackupMastersList().size());
460 for (HBaseProtos.ServerName sn : proto.getBackupMastersList()) {
461 backupMasters.add(ProtobufUtil.toServerName(sn));
462 }
463 }
464
465 Map<String, RegionState> rit = null;
466 if (proto.getRegionsInTransitionList() != null) {
467 rit = new HashMap<String, RegionState>(proto.getRegionsInTransitionList().size());
468 for (RegionInTransition region : proto.getRegionsInTransitionList()) {
469 String key = new String(region.getSpec().getValue().toByteArray());
470 RegionState value = RegionState.convert(region.getRegionState());
471 rit.put(key, value);
472 }
473 }
474
475 String[] masterCoprocessors = null;
476 if (proto.getMasterCoprocessorsList() != null) {
477 final int numMasterCoprocessors = proto.getMasterCoprocessorsCount();
478 masterCoprocessors = new String[numMasterCoprocessors];
479 for (int i = 0; i < numMasterCoprocessors; i++) {
480 masterCoprocessors[i] = proto.getMasterCoprocessors(i).getName();
481 }
482 }
483
484 return new ClusterStatus(proto.getHbaseVersion().getVersion(),
485 ClusterId.convert(proto.getClusterId()).toString(),servers,deadServers,
486 ProtobufUtil.toServerName(proto.getMaster()),backupMasters,rit,masterCoprocessors,
487 proto.getBalancerOn());
488 }
489 }