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 double getAverageLoad() {
172 int load = getRegionsCount();
173 return (double)load / (double)getServersSize();
174 }
175
176
177
178
179 public int getRegionsCount() {
180 int count = 0;
181 if (liveServers != null && !liveServers.isEmpty()) {
182 for (Map.Entry<ServerName, ServerLoad> e: this.liveServers.entrySet()) {
183 count += e.getValue().getNumberOfRegions();
184 }
185 }
186 return count;
187 }
188
189
190
191
192 public int getRequestsCount() {
193 int count = 0;
194 if (liveServers != null && !liveServers.isEmpty()) {
195 for (Map.Entry<ServerName, ServerLoad> e: this.liveServers.entrySet()) {
196 count = (int) (count + e.getValue().getNumberOfRequests());
197 }
198 }
199 return count;
200 }
201
202
203
204
205 public String getHBaseVersion() {
206 return hbaseVersion;
207 }
208
209
210
211
212 @Override
213 public boolean equals(Object o) {
214 if (this == o) {
215 return true;
216 }
217 if (!(o instanceof ClusterStatus)) {
218 return false;
219 }
220 ClusterStatus other = (ClusterStatus) o;
221 return Objects.equal(getHBaseVersion(), other.getHBaseVersion()) &&
222 Objects.equal(this.liveServers, other.liveServers) &&
223 getDeadServerNames().containsAll(other.getDeadServerNames()) &&
224 Arrays.equals(getMasterCoprocessors(), other.getMasterCoprocessors()) &&
225 Objects.equal(getMaster(), other.getMaster()) &&
226 getBackupMasters().containsAll(other.getBackupMasters()) &&
227 Objects.equal(getClusterId(), other.getClusterId());
228 }
229
230
231
232
233 @Override
234 public int hashCode() {
235 return VERSION + hbaseVersion.hashCode() + this.liveServers.hashCode() +
236 this.deadServers.hashCode() + this.master.hashCode() +
237 this.backupMasters.hashCode();
238 }
239
240
241 @Override
242 public byte getVersion() {
243 return VERSION;
244 }
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259 @Deprecated
260 public Collection<ServerName> getServerInfo() {
261 return getServers();
262 }
263
264 public Collection<ServerName> getServers() {
265 if (liveServers == null) {
266 return Collections.<ServerName>emptyList();
267 }
268 return Collections.unmodifiableCollection(this.liveServers.keySet());
269 }
270
271
272
273
274
275 public ServerName getMaster() {
276 return this.master;
277 }
278
279
280
281
282 public int getBackupMastersSize() {
283 return backupMasters != null ? backupMasters.size() : 0;
284 }
285
286
287
288
289 public Collection<ServerName> getBackupMasters() {
290 if (backupMasters == null) {
291 return Collections.<ServerName>emptyList();
292 }
293 return Collections.unmodifiableCollection(this.backupMasters);
294 }
295
296
297
298
299
300 public ServerLoad getLoad(final ServerName sn) {
301 return liveServers != null ? liveServers.get(sn) : null;
302 }
303
304 @InterfaceAudience.Private
305 public Set<RegionState> getRegionsInTransition() {
306 if (intransition == null) {
307 return Collections.emptySet();
308 }
309 return Collections.unmodifiableSet(intransition);
310 }
311
312 public String getClusterId() {
313 return clusterId;
314 }
315
316 public String[] getMasterCoprocessors() {
317 return masterCoprocessors;
318 }
319
320 public long getLastMajorCompactionTsForTable(TableName table) {
321 long result = Long.MAX_VALUE;
322 for (ServerName server : getServers()) {
323 ServerLoad load = getLoad(server);
324 for (RegionLoad rl : load.getRegionsLoad().values()) {
325 if (table.equals(HRegionInfo.getTable(rl.getName()))) {
326 result = Math.min(result, rl.getLastMajorCompactionTs());
327 }
328 }
329 }
330 return result == Long.MAX_VALUE ? 0 : result;
331 }
332
333 public long getLastMajorCompactionTsForRegion(final byte[] region) {
334 for (ServerName server : getServers()) {
335 ServerLoad load = getLoad(server);
336 RegionLoad rl = load.getRegionsLoad().get(region);
337 if (rl != null) {
338 return rl.getLastMajorCompactionTs();
339 }
340 }
341 return 0;
342 }
343
344 public boolean isBalancerOn() {
345 return balancerOn != null && balancerOn;
346 }
347
348 public Boolean getBalancerOn() {
349 return balancerOn;
350 }
351
352 @Override
353 public String toString() {
354 StringBuilder sb = new StringBuilder(1024);
355 sb.append("Master: " + master);
356
357 int backupMastersSize = getBackupMastersSize();
358 sb.append("\nNumber of backup masters: " + backupMastersSize);
359 if (backupMastersSize > 0) {
360 for (ServerName serverName: backupMasters) {
361 sb.append("\n " + serverName);
362 }
363 }
364
365 int serversSize = getServersSize();
366 sb.append("\nNumber of live region servers: " + serversSize);
367 if (serversSize > 0) {
368 for (ServerName serverName: liveServers.keySet()) {
369 sb.append("\n " + serverName.getServerName());
370 }
371 }
372
373 int deadServerSize = getDeadServers();
374 sb.append("\nNumber of dead region servers: " + deadServerSize);
375 if (deadServerSize > 0) {
376 for (ServerName serverName: deadServers) {
377 sb.append("\n " + serverName);
378 }
379 }
380
381 sb.append("\nAverage load: " + getAverageLoad());
382 sb.append("\nNumber of requests: " + getRequestsCount());
383 sb.append("\nNumber of regions: " + getRegionsCount());
384
385 int ritSize = (intransition != null) ? intransition.size() : 0;
386 sb.append("\nNumber of regions in transition: " + ritSize);
387 if (ritSize > 0) {
388 for (RegionState state: intransition) {
389 sb.append("\n " + state.toDescriptiveString());
390 }
391 }
392 return sb.toString();
393 }
394
395
396
397
398
399
400 @Deprecated
401 public ClusterStatusProtos.ClusterStatus convert() {
402 ClusterStatusProtos.ClusterStatus.Builder builder =
403 ClusterStatusProtos.ClusterStatus.newBuilder();
404 builder.setHbaseVersion(HBaseVersionFileContent.newBuilder().setVersion(getHBaseVersion()));
405
406 if (liveServers != null){
407 for (Map.Entry<ServerName, ServerLoad> entry : liveServers.entrySet()) {
408 LiveServerInfo.Builder lsi =
409 LiveServerInfo.newBuilder().setServer(ProtobufUtil.toServerName(entry.getKey()));
410 lsi.setServerLoad(entry.getValue().obtainServerLoadPB());
411 builder.addLiveServers(lsi.build());
412 }
413 }
414
415 if (deadServers != null){
416 for (ServerName deadServer : deadServers) {
417 builder.addDeadServers(ProtobufUtil.toServerName(deadServer));
418 }
419 }
420
421 if (intransition != null) {
422 for (RegionState rit : getRegionsInTransition()) {
423 ClusterStatusProtos.RegionState rs = rit.convert();
424 RegionSpecifier.Builder spec =
425 RegionSpecifier.newBuilder().setType(RegionSpecifierType.REGION_NAME);
426 spec.setValue(ByteStringer.wrap(rit.getRegion().getRegionName()));
427
428 RegionInTransition pbRIT =
429 RegionInTransition.newBuilder().setSpec(spec.build()).setRegionState(rs).build();
430 builder.addRegionsInTransition(pbRIT);
431 }
432 }
433
434 if (clusterId != null) {
435 builder.setClusterId(new ClusterId(clusterId).convert());
436 }
437
438 if (masterCoprocessors != null) {
439 for (String coprocessor : masterCoprocessors) {
440 builder.addMasterCoprocessors(HBaseProtos.Coprocessor.newBuilder().setName(coprocessor));
441 }
442 }
443
444 if (master != null){
445 builder.setMaster(ProtobufUtil.toServerName(getMaster()));
446 }
447
448 if (backupMasters != null) {
449 for (ServerName backup : backupMasters) {
450 builder.addBackupMasters(ProtobufUtil.toServerName(backup));
451 }
452 }
453
454 if (balancerOn != null){
455 builder.setBalancerOn(balancerOn);
456 }
457
458 return builder.build();
459 }
460
461
462
463
464
465
466
467 @Deprecated
468 public static ClusterStatus convert(ClusterStatusProtos.ClusterStatus proto) {
469
470 Map<ServerName, ServerLoad> servers = null;
471 if (!proto.getLiveServersList().isEmpty()) {
472 servers = new HashMap<ServerName, ServerLoad>(proto.getLiveServersList().size());
473 for (LiveServerInfo lsi : proto.getLiveServersList()) {
474 servers.put(ProtobufUtil.toServerName(
475 lsi.getServer()), new ServerLoad(lsi.getServerLoad()));
476 }
477 }
478
479 Collection<ServerName> deadServers = null;
480 if (!proto.getDeadServersList().isEmpty()) {
481 deadServers = new ArrayList<ServerName>(proto.getDeadServersList().size());
482 for (HBaseProtos.ServerName sn : proto.getDeadServersList()) {
483 deadServers.add(ProtobufUtil.toServerName(sn));
484 }
485 }
486
487 Collection<ServerName> backupMasters = null;
488 if (!proto.getBackupMastersList().isEmpty()) {
489 backupMasters = new ArrayList<ServerName>(proto.getBackupMastersList().size());
490 for (HBaseProtos.ServerName sn : proto.getBackupMastersList()) {
491 backupMasters.add(ProtobufUtil.toServerName(sn));
492 }
493 }
494
495 Set<RegionState> rit = null;
496 if (!proto.getRegionsInTransitionList().isEmpty()) {
497 rit = new HashSet<RegionState>(proto.getRegionsInTransitionList().size());
498 for (RegionInTransition region : proto.getRegionsInTransitionList()) {
499 RegionState value = RegionState.convert(region.getRegionState());
500 rit.add(value);
501 }
502 }
503
504 String[] masterCoprocessors = null;
505 if (!proto.getMasterCoprocessorsList().isEmpty()) {
506 final int numMasterCoprocessors = proto.getMasterCoprocessorsCount();
507 masterCoprocessors = new String[numMasterCoprocessors];
508 for (int i = 0; i < numMasterCoprocessors; i++) {
509 masterCoprocessors[i] = proto.getMasterCoprocessors(i).getName();
510 }
511 }
512
513 return new ClusterStatus(proto.getHbaseVersion().getVersion(),
514 ClusterId.convert(proto.getClusterId()).toString(),servers,deadServers,
515 ProtobufUtil.toServerName(proto.getMaster()),backupMasters,rit,masterCoprocessors,
516 proto.getBalancerOn());
517 }
518 }