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