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 return this.intransition;
280 }
281
282 public String getClusterId() {
283 return clusterId;
284 }
285
286 public String[] getMasterCoprocessors() {
287 return masterCoprocessors;
288 }
289
290 public long getLastMajorCompactionTsForTable(TableName table) {
291 long result = Long.MAX_VALUE;
292 for (ServerName server : getServers()) {
293 ServerLoad load = getLoad(server);
294 for (RegionLoad rl : load.getRegionsLoad().values()) {
295 if (table.equals(HRegionInfo.getTable(rl.getName()))) {
296 result = Math.min(result, rl.getLastMajorCompactionTs());
297 }
298 }
299 }
300 return result == Long.MAX_VALUE ? 0 : result;
301 }
302
303 public long getLastMajorCompactionTsForRegion(final byte[] region) {
304 for (ServerName server : getServers()) {
305 ServerLoad load = getLoad(server);
306 RegionLoad rl = load.getRegionsLoad().get(region);
307 if (rl != null) {
308 return rl.getLastMajorCompactionTs();
309 }
310 }
311 return 0;
312 }
313
314 public boolean isBalancerOn() {
315 return balancerOn != null && balancerOn;
316 }
317
318 public Boolean getBalancerOn() {
319 return balancerOn;
320 }
321
322 public String toString() {
323 StringBuilder sb = new StringBuilder(1024);
324 sb.append("Master: " + master);
325
326 int backupMastersSize = getBackupMastersSize();
327 sb.append("\nNumber of backup masters: " + backupMastersSize);
328 if (backupMastersSize > 0) {
329 for (ServerName serverName: backupMasters) {
330 sb.append("\n " + serverName);
331 }
332 }
333
334 int serversSize = getServersSize();
335 sb.append("\nNumber of live region servers: " + serversSize);
336 if (serversSize > 0) {
337 for (ServerName serverName: liveServers.keySet()) {
338 sb.append("\n " + serverName.getServerName());
339 }
340 }
341
342 int deadServerSize = getDeadServers();
343 sb.append("\nNumber of dead region servers: " + deadServerSize);
344 if (deadServerSize > 0) {
345 for (ServerName serverName: deadServers) {
346 sb.append("\n " + serverName);
347 }
348 }
349
350 sb.append("\nAverage load: " + getAverageLoad());
351 sb.append("\nNumber of requests: " + getRequestsCount());
352 sb.append("\nNumber of regions: " + getRegionsCount());
353
354 int ritSize = (intransition != null) ? intransition.size() : 0;
355 sb.append("\nNumber of regions in transition: " + ritSize);
356 if (ritSize > 0) {
357 for (RegionState state: intransition.values()) {
358 sb.append("\n " + state.toDescriptiveString());
359 }
360 }
361 return sb.toString();
362 }
363
364
365
366
367
368
369 public ClusterStatusProtos.ClusterStatus convert() {
370 ClusterStatusProtos.ClusterStatus.Builder builder =
371 ClusterStatusProtos.ClusterStatus.newBuilder();
372 builder.setHbaseVersion(HBaseVersionFileContent.newBuilder().setVersion(getHBaseVersion()));
373
374 if (liveServers != null){
375 for (Map.Entry<ServerName, ServerLoad> entry : liveServers.entrySet()) {
376 LiveServerInfo.Builder lsi =
377 LiveServerInfo.newBuilder().setServer(ProtobufUtil.toServerName(entry.getKey()));
378 lsi.setServerLoad(entry.getValue().obtainServerLoadPB());
379 builder.addLiveServers(lsi.build());
380 }
381 }
382
383 if (deadServers != null){
384 for (ServerName deadServer : deadServers) {
385 builder.addDeadServers(ProtobufUtil.toServerName(deadServer));
386 }
387 }
388
389 if (intransition != null) {
390 for (Map.Entry<String, RegionState> rit : getRegionsInTransition().entrySet()) {
391 ClusterStatusProtos.RegionState rs = rit.getValue().convert();
392 RegionSpecifier.Builder spec =
393 RegionSpecifier.newBuilder().setType(RegionSpecifierType.REGION_NAME);
394 spec.setValue(ByteStringer.wrap(Bytes.toBytes(rit.getKey())));
395
396 RegionInTransition pbRIT =
397 RegionInTransition.newBuilder().setSpec(spec.build()).setRegionState(rs).build();
398 builder.addRegionsInTransition(pbRIT);
399 }
400 }
401
402 if (clusterId != null) {
403 builder.setClusterId(new ClusterId(clusterId).convert());
404 }
405
406 if (masterCoprocessors != null) {
407 for (String coprocessor : masterCoprocessors) {
408 builder.addMasterCoprocessors(HBaseProtos.Coprocessor.newBuilder().setName(coprocessor));
409 }
410 }
411
412 if (master != null){
413 builder.setMaster(ProtobufUtil.toServerName(getMaster()));
414 }
415
416 if (backupMasters != null) {
417 for (ServerName backup : backupMasters) {
418 builder.addBackupMasters(ProtobufUtil.toServerName(backup));
419 }
420 }
421
422 if (balancerOn != null){
423 builder.setBalancerOn(balancerOn);
424 }
425
426 return builder.build();
427 }
428
429
430
431
432
433
434
435 public static ClusterStatus convert(ClusterStatusProtos.ClusterStatus proto) {
436
437 Map<ServerName, ServerLoad> servers = null;
438 if (proto.getLiveServersList() != null) {
439 servers = new HashMap<ServerName, ServerLoad>(proto.getLiveServersList().size());
440 for (LiveServerInfo lsi : proto.getLiveServersList()) {
441 servers.put(ProtobufUtil.toServerName(
442 lsi.getServer()), new ServerLoad(lsi.getServerLoad()));
443 }
444 }
445
446 Collection<ServerName> deadServers = null;
447 if (proto.getDeadServersList() != null) {
448 deadServers = new ArrayList<ServerName>(proto.getDeadServersList().size());
449 for (HBaseProtos.ServerName sn : proto.getDeadServersList()) {
450 deadServers.add(ProtobufUtil.toServerName(sn));
451 }
452 }
453
454 Collection<ServerName> backupMasters = null;
455 if (proto.getBackupMastersList() != null) {
456 backupMasters = new ArrayList<ServerName>(proto.getBackupMastersList().size());
457 for (HBaseProtos.ServerName sn : proto.getBackupMastersList()) {
458 backupMasters.add(ProtobufUtil.toServerName(sn));
459 }
460 }
461
462 Map<String, RegionState> rit = null;
463 if (proto.getRegionsInTransitionList() != null) {
464 rit = new HashMap<String, RegionState>(proto.getRegionsInTransitionList().size());
465 for (RegionInTransition region : proto.getRegionsInTransitionList()) {
466 String key = new String(region.getSpec().getValue().toByteArray());
467 RegionState value = RegionState.convert(region.getRegionState());
468 rit.put(key, value);
469 }
470 }
471
472 String[] masterCoprocessors = null;
473 if (proto.getMasterCoprocessorsList() != null) {
474 final int numMasterCoprocessors = proto.getMasterCoprocessorsCount();
475 masterCoprocessors = new String[numMasterCoprocessors];
476 for (int i = 0; i < numMasterCoprocessors; i++) {
477 masterCoprocessors[i] = proto.getMasterCoprocessors(i).getName();
478 }
479 }
480
481 return new ClusterStatus(proto.getHbaseVersion().getVersion(),
482 ClusterId.convert(proto.getClusterId()).toString(),servers,deadServers,
483 ProtobufUtil.toServerName(proto.getMaster()),backupMasters,rit,masterCoprocessors,
484 proto.getBalancerOn());
485 }
486 }