001/** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019 020package org.apache.hadoop.hbase; 021 022import edu.umd.cs.findbugs.annotations.Nullable; 023import java.util.ArrayList; 024import java.util.Arrays; 025import java.util.Collection; 026import java.util.List; 027import java.util.Map; 028import java.util.stream.Collectors; 029 030import org.apache.hadoop.hbase.client.RegionStatesCount; 031import org.apache.hadoop.hbase.master.RegionState; 032import org.apache.yetus.audience.InterfaceAudience; 033 034import org.apache.hbase.thirdparty.com.google.common.base.Objects; 035 036/** 037 * Status information on the HBase cluster. 038 * <p> 039 * <tt>ClusterStatus</tt> provides clients with information such as: 040 * <ul> 041 * <li>The count and names of region servers in the cluster.</li> 042 * <li>The count and names of dead region servers in the cluster.</li> 043 * <li>The name of the active master for the cluster.</li> 044 * <li>The name(s) of the backup master(s) for the cluster, if they exist.</li> 045 * <li>The average cluster load.</li> 046 * <li>The number of regions deployed on the cluster.</li> 047 * <li>The number of requests since last report.</li> 048 * <li>Detailed region server loading and resource usage information, 049 * per server and per region.</li> 050 * <li>Regions in transition at master</li> 051 * <li>The unique cluster ID</li> 052 * </ul> 053 * <tt>{@link ClusterMetrics.Option}</tt> provides a way to get desired ClusterStatus information. 054 * The following codes will get all the cluster information. 055 * <pre> 056 * {@code 057 * // Original version still works 058 * Admin admin = connection.getAdmin(); 059 * ClusterStatus status = admin.getClusterStatus(); 060 * // or below, a new version which has the same effects 061 * ClusterStatus status = admin.getClusterStatus(EnumSet.allOf(Option.class)); 062 * } 063 * </pre> 064 * If information about live servers is the only wanted. 065 * then codes in the following way: 066 * <pre> 067 * {@code 068 * Admin admin = connection.getAdmin(); 069 * ClusterStatus status = admin.getClusterStatus(EnumSet.of(Option.LIVE_SERVERS)); 070 * } 071 * </pre> 072 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 073 * Use {@link ClusterMetrics} instead. 074 */ 075@InterfaceAudience.Public 076@Deprecated 077public class ClusterStatus implements ClusterMetrics { 078 079 // TODO: remove this in 3.0 080 private static final byte VERSION = 2; 081 082 private final ClusterMetrics metrics; 083 084 /** 085 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 086 */ 087 @Deprecated 088 public ClusterStatus(final String hbaseVersion, final String clusterid, 089 final Map<ServerName, ServerLoad> servers, 090 final Collection<ServerName> deadServers, 091 final ServerName master, 092 final Collection<ServerName> backupMasters, 093 final List<RegionState> rit, 094 final String[] masterCoprocessors, 095 final Boolean balancerOn, 096 final int masterInfoPort) { 097 // TODO: make this constructor private 098 this(ClusterMetricsBuilder.newBuilder().setHBaseVersion(hbaseVersion) 099 .setDeadServerNames(new ArrayList<>(deadServers)) 100 .setLiveServerMetrics(servers.entrySet().stream() 101 .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()))) 102 .setBackerMasterNames(new ArrayList<>(backupMasters)).setBalancerOn(balancerOn) 103 .setClusterId(clusterid) 104 .setMasterCoprocessorNames(Arrays.asList(masterCoprocessors)) 105 .setMasterName(master) 106 .setMasterInfoPort(masterInfoPort) 107 .setRegionsInTransition(rit) 108 .build()); 109 } 110 111 @InterfaceAudience.Private 112 public ClusterStatus(ClusterMetrics metrics) { 113 this.metrics = metrics; 114 } 115 116 /** 117 * @return the names of region servers on the dead list 118 */ 119 @Override 120 public List<ServerName> getDeadServerNames() { 121 return metrics.getDeadServerNames(); 122 } 123 124 @Override 125 public Map<ServerName, ServerMetrics> getLiveServerMetrics() { 126 return metrics.getLiveServerMetrics(); 127 } 128 129 /** 130 * @return the number of region servers in the cluster 131 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 132 * Use {@link #getLiveServerMetrics()}. 133 */ 134 @Deprecated 135 public int getServersSize() { 136 return metrics.getLiveServerMetrics().size(); 137 } 138 139 /** 140 * @return the number of dead region servers in the cluster 141 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 142 * (<a href="https://issues.apache.org/jira/browse/HBASE-13656">HBASE-13656</a>). 143 * Use {@link #getDeadServerNames()}. 144 */ 145 @Deprecated 146 public int getDeadServers() { 147 return getDeadServersSize(); 148 } 149 150 /** 151 * @return the number of dead region servers in the cluster 152 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 153 * Use {@link #getDeadServerNames()}. 154 */ 155 @Deprecated 156 public int getDeadServersSize() { 157 return metrics.getDeadServerNames().size(); 158 } 159 160 /** 161 * @return the number of regions deployed on the cluster 162 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 163 * Use {@link #getRegionCount()}. 164 */ 165 @Deprecated 166 public int getRegionsCount() { 167 return getRegionCount(); 168 } 169 170 /** 171 * @return the number of requests since last report 172 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 173 * Use {@link #getRequestCount()} instead. 174 */ 175 @Deprecated 176 public int getRequestsCount() { 177 return (int) getRequestCount(); 178 } 179 180 @Nullable 181 @Override 182 public ServerName getMasterName() { 183 return metrics.getMasterName(); 184 } 185 186 @Override 187 public List<ServerName> getBackupMasterNames() { 188 return metrics.getBackupMasterNames(); 189 } 190 191 @Override 192 public List<RegionState> getRegionStatesInTransition() { 193 return metrics.getRegionStatesInTransition(); 194 } 195 196 /** 197 * @return the HBase version string as reported by the HMaster 198 */ 199 public String getHBaseVersion() { 200 return metrics.getHBaseVersion(); 201 } 202 203 private Map<ServerName, ServerLoad> getLiveServerLoads() { 204 return metrics.getLiveServerMetrics().entrySet().stream() 205 .collect(Collectors.toMap(e -> e.getKey(), e -> new ServerLoad(e.getValue()))); 206 } 207 208 @Override 209 public boolean equals(Object o) { 210 if (this == o) { 211 return true; 212 } 213 if (!(o instanceof ClusterStatus)) { 214 return false; 215 } 216 ClusterStatus other = (ClusterStatus) o; 217 return Objects.equal(getHBaseVersion(), other.getHBaseVersion()) && 218 Objects.equal(getLiveServerLoads(), other.getLiveServerLoads()) && 219 getDeadServerNames().containsAll(other.getDeadServerNames()) && 220 Arrays.equals(getMasterCoprocessors(), other.getMasterCoprocessors()) && 221 Objects.equal(getMaster(), other.getMaster()) && 222 getBackupMasters().containsAll(other.getBackupMasters()) && 223 Objects.equal(getClusterId(), other.getClusterId()) && 224 getMasterInfoPort() == other.getMasterInfoPort(); 225 } 226 227 @Override 228 public int hashCode() { 229 return metrics.hashCode(); 230 } 231 232 /** 233 * @return the object version number 234 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 235 */ 236 @Deprecated 237 public byte getVersion() { 238 return VERSION; 239 } 240 241 /** 242 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 243 * Use {@link #getLiveServerMetrics()} instead. 244 */ 245 @Deprecated 246 public Collection<ServerName> getServers() { 247 return metrics.getLiveServerMetrics().keySet(); 248 } 249 250 /** 251 * Returns detailed information about the current master {@link ServerName}. 252 * @return current master information if it exists 253 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 254 * Use {@link #getMasterName} instead. 255 */ 256 @Deprecated 257 public ServerName getMaster() { 258 return metrics.getMasterName(); 259 } 260 261 /** 262 * @return the number of backup masters in the cluster 263 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 264 * Use {@link #getBackupMasterNames} instead. 265 */ 266 @Deprecated 267 public int getBackupMastersSize() { 268 return metrics.getBackupMasterNames().size(); 269 } 270 271 /** 272 * @return the names of backup masters 273 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 274 * Use {@link #getBackupMasterNames} instead. 275 */ 276 @Deprecated 277 public List<ServerName> getBackupMasters() { 278 return metrics.getBackupMasterNames(); 279 } 280 281 /** 282 * @param sn 283 * @return Server's load or null if not found. 284 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 285 * Use {@link #getLiveServerMetrics} instead. 286 */ 287 @Deprecated 288 public ServerLoad getLoad(final ServerName sn) { 289 ServerMetrics serverMetrics = metrics.getLiveServerMetrics().get(sn); 290 return serverMetrics == null ? null : new ServerLoad(serverMetrics); 291 } 292 293 public String getClusterId() { 294 return metrics.getClusterId(); 295 } 296 297 @Override 298 public List<String> getMasterCoprocessorNames() { 299 return metrics.getMasterCoprocessorNames(); 300 } 301 302 /** 303 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 304 * Use {@link #getMasterCoprocessorNames} instead. 305 */ 306 @Deprecated 307 public String[] getMasterCoprocessors() { 308 List<String> rval = metrics.getMasterCoprocessorNames(); 309 return rval.toArray(new String[rval.size()]); 310 } 311 312 /** 313 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 314 * Use {@link #getLastMajorCompactionTimestamp(TableName)} instead. 315 */ 316 @Deprecated 317 public long getLastMajorCompactionTsForTable(TableName table) { 318 return metrics.getLastMajorCompactionTimestamp(table); 319 } 320 321 /** 322 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 323 * Use {@link #getLastMajorCompactionTimestamp(byte[])} instead. 324 */ 325 @Deprecated 326 public long getLastMajorCompactionTsForRegion(final byte[] region) { 327 return metrics.getLastMajorCompactionTimestamp(region); 328 } 329 330 /** 331 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 332 * No flag in 2.0 333 */ 334 @Deprecated 335 public boolean isBalancerOn() { 336 return metrics.getBalancerOn() != null && metrics.getBalancerOn(); 337 } 338 339 @Override 340 public Boolean getBalancerOn() { 341 return metrics.getBalancerOn(); 342 } 343 344 @Override 345 public int getMasterInfoPort() { 346 return metrics.getMasterInfoPort(); 347 } 348 349 @Override 350 public List<ServerName> getServersName() { 351 return metrics.getServersName(); 352 } 353 354 @Override 355 public Map<TableName, RegionStatesCount> getTableRegionStatesCount() { 356 return metrics.getTableRegionStatesCount(); 357 } 358 359 @Override 360 public String toString() { 361 StringBuilder sb = new StringBuilder(1024); 362 sb.append("Master: " + metrics.getMasterName()); 363 364 int backupMastersSize = getBackupMastersSize(); 365 sb.append("\nNumber of backup masters: " + backupMastersSize); 366 if (backupMastersSize > 0) { 367 for (ServerName serverName: metrics.getBackupMasterNames()) { 368 sb.append("\n " + serverName); 369 } 370 } 371 372 int serversSize = getServersSize(); 373 int serversNameSize = getServersName().size(); 374 sb.append("\nNumber of live region servers: " 375 + (serversSize > 0 ? serversSize : serversNameSize)); 376 if (serversSize > 0) { 377 for (ServerName serverName : metrics.getLiveServerMetrics().keySet()) { 378 sb.append("\n " + serverName.getServerName()); 379 } 380 } else if (serversNameSize > 0) { 381 for (ServerName serverName : getServersName()) { 382 sb.append("\n " + serverName.getServerName()); 383 } 384 } 385 386 int deadServerSize = metrics.getDeadServerNames().size(); 387 sb.append("\nNumber of dead region servers: " + deadServerSize); 388 if (deadServerSize > 0) { 389 for (ServerName serverName : metrics.getDeadServerNames()) { 390 sb.append("\n " + serverName); 391 } 392 } 393 394 sb.append("\nAverage load: " + getAverageLoad()); 395 sb.append("\nNumber of requests: " + getRequestCount()); 396 sb.append("\nNumber of regions: " + getRegionsCount()); 397 398 int ritSize = metrics.getRegionStatesInTransition().size(); 399 sb.append("\nNumber of regions in transition: " + ritSize); 400 if (ritSize > 0) { 401 for (RegionState state: metrics.getRegionStatesInTransition()) { 402 sb.append("\n " + state.toDescriptiveString()); 403 } 404 } 405 return sb.toString(); 406 } 407}