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