001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase; 019 020import edu.umd.cs.findbugs.annotations.Nullable; 021import java.util.ArrayList; 022import java.util.Collection; 023import java.util.Collections; 024import java.util.HashMap; 025import java.util.List; 026import java.util.Map; 027import java.util.Set; 028import java.util.TreeMap; 029import java.util.TreeSet; 030import java.util.stream.Collectors; 031import org.apache.hadoop.hbase.replication.ReplicationLoadSink; 032import org.apache.hadoop.hbase.replication.ReplicationLoadSource; 033import org.apache.hadoop.hbase.util.Bytes; 034import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 035import org.apache.hadoop.hbase.util.Strings; 036import org.apache.yetus.audience.InterfaceAudience; 037 038import org.apache.hbase.thirdparty.com.google.common.base.Preconditions; 039 040import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 041import org.apache.hadoop.hbase.shaded.protobuf.generated.ClusterStatusProtos; 042import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos; 043 044@InterfaceAudience.Private 045public final class ServerMetricsBuilder { 046 047 public static ServerMetrics of(ServerName sn) { 048 return newBuilder(sn).build(); 049 } 050 051 public static ServerMetrics of(ServerName sn, int versionNumber, String version) { 052 return newBuilder(sn).setVersionNumber(versionNumber).setVersion(version).build(); 053 } 054 055 public static ServerMetrics toServerMetrics(ClusterStatusProtos.LiveServerInfo serverInfo) { 056 return toServerMetrics(ProtobufUtil.toServerName(serverInfo.getServer()), 0, "0.0.0", 057 serverInfo.getServerLoad()); 058 } 059 060 public static ServerMetrics toServerMetrics(ServerName serverName, 061 ClusterStatusProtos.ServerLoad serverLoadPB) { 062 return toServerMetrics(serverName, 0, "0.0.0", serverLoadPB); 063 } 064 065 public static ServerMetrics toServerMetrics(ServerName serverName, int versionNumber, 066 String version, ClusterStatusProtos.ServerLoad serverLoadPB) { 067 ServerMetricsBuilder builder = ServerMetricsBuilder.newBuilder(serverName) 068 .setRequestCountPerSecond(serverLoadPB.getNumberOfRequests()) 069 .setRequestCount(serverLoadPB.getTotalNumberOfRequests()) 070 .setInfoServerPort(serverLoadPB.getInfoServerPort()) 071 .setReadRequestCount(serverLoadPB.getReadRequestsCount()) 072 .setWriteRequestCount(serverLoadPB.getWriteRequestsCount()) 073 .setMaxHeapSize(new Size(serverLoadPB.getMaxHeapMB(), Size.Unit.MEGABYTE)) 074 .setUsedHeapSize(new Size(serverLoadPB.getUsedHeapMB(), Size.Unit.MEGABYTE)) 075 .setCoprocessorNames(serverLoadPB.getCoprocessorsList().stream() 076 .map(HBaseProtos.Coprocessor::getName).collect(Collectors.toList())) 077 .setRegionMetrics(serverLoadPB.getRegionLoadsList().stream() 078 .map(RegionMetricsBuilder::toRegionMetrics).collect(Collectors.toList())) 079 .setUserMetrics(serverLoadPB.getUserLoadsList().stream() 080 .map(UserMetricsBuilder::toUserMetrics).collect(Collectors.toList())) 081 .setReplicationLoadSources(serverLoadPB.getReplLoadSourceList().stream() 082 .map(ProtobufUtil::toReplicationLoadSource).collect(Collectors.toList())) 083 .setReplicationLoadSink(serverLoadPB.hasReplLoadSink() 084 ? ProtobufUtil.toReplicationLoadSink(serverLoadPB.getReplLoadSink()) 085 : null) 086 .setTasks(serverLoadPB.getTasksList().stream().map(ProtobufUtil::getServerTask) 087 .collect(Collectors.toList())) 088 .setRegionCachedInfo(serverLoadPB.getRegionCachedInfoMap()) 089 .setReportTimestamp(serverLoadPB.getReportEndTime()) 090 .setLastReportTimestamp(serverLoadPB.getReportStartTime()).setVersionNumber(versionNumber) 091 .setVersion(version) 092 .setCacheFreeSize(serverLoadPB.hasCacheFreeSize() ? serverLoadPB.getCacheFreeSize() : 0L) 093 .setRegionColdDataInfo(serverLoadPB.getRegionColdDataMap()); 094 return builder.build(); 095 } 096 097 public static List<HBaseProtos.Coprocessor> toCoprocessor(Collection<String> names) { 098 return names.stream().map(n -> HBaseProtos.Coprocessor.newBuilder().setName(n).build()) 099 .collect(Collectors.toList()); 100 } 101 102 public static ClusterStatusProtos.ServerLoad toServerLoad(ServerMetrics metrics) { 103 ClusterStatusProtos.ServerLoad.Builder builder = ClusterStatusProtos.ServerLoad.newBuilder() 104 .setNumberOfRequests(metrics.getRequestCountPerSecond()) 105 .setTotalNumberOfRequests(metrics.getRequestCount()) 106 .setInfoServerPort(metrics.getInfoServerPort()) 107 .setMaxHeapMB((int) metrics.getMaxHeapSize().get(Size.Unit.MEGABYTE)) 108 .setUsedHeapMB((int) metrics.getUsedHeapSize().get(Size.Unit.MEGABYTE)) 109 .addAllCoprocessors(toCoprocessor(metrics.getCoprocessorNames())) 110 .addAllRegionLoads(metrics.getRegionMetrics().values().stream() 111 .map(RegionMetricsBuilder::toRegionLoad).collect(Collectors.toList())) 112 .addAllUserLoads(metrics.getUserMetrics().values().stream() 113 .map(UserMetricsBuilder::toUserMetrics).collect(Collectors.toList())) 114 .addAllReplLoadSource(metrics.getReplicationLoadSourceList().stream() 115 .map(ProtobufUtil::toReplicationLoadSource).collect(Collectors.toList())) 116 .addAllTasks( 117 metrics.getTasks().stream().map(ProtobufUtil::toServerTask).collect(Collectors.toList())) 118 .putAllRegionCachedInfo(metrics.getRegionCachedInfo()) 119 .setReportStartTime(metrics.getLastReportTimestamp()) 120 .setReportEndTime(metrics.getReportTimestamp()); 121 if (metrics.getReplicationLoadSink() != null) { 122 builder.setReplLoadSink(ProtobufUtil.toReplicationLoadSink(metrics.getReplicationLoadSink())); 123 } 124 builder.setCacheFreeSize(metrics.getCacheFreeSize()); 125 return builder.build(); 126 } 127 128 public static ServerMetricsBuilder newBuilder(ServerName sn) { 129 return new ServerMetricsBuilder(sn); 130 } 131 132 private final ServerName serverName; 133 private int versionNumber; 134 private String version = "0.0.0"; 135 private long requestCountPerSecond; 136 private long requestCount; 137 private long readRequestCount; 138 private long writeRequestCount; 139 private Size usedHeapSize = Size.ZERO; 140 private Size maxHeapSize = Size.ZERO; 141 private int infoServerPort; 142 private List<ReplicationLoadSource> sources = Collections.emptyList(); 143 @Nullable 144 private ReplicationLoadSink sink = null; 145 private final Map<byte[], RegionMetrics> regionStatus = new TreeMap<>(Bytes.BYTES_COMPARATOR); 146 private final Map<byte[], UserMetrics> userMetrics = new TreeMap<>(Bytes.BYTES_COMPARATOR); 147 private final Set<String> coprocessorNames = new TreeSet<>(); 148 private long reportTimestamp = EnvironmentEdgeManager.currentTime(); 149 private long lastReportTimestamp = 0; 150 private final List<ServerTask> tasks = new ArrayList<>(); 151 private Map<String, Integer> regionCachedInfo = new HashMap<>(); 152 private long cacheFreeSize; 153 private Map<String, Integer> regionColdDataInfo = Collections.emptyMap(); 154 155 private ServerMetricsBuilder(ServerName serverName) { 156 this.serverName = serverName; 157 } 158 159 public ServerMetricsBuilder setVersionNumber(int versionNumber) { 160 this.versionNumber = versionNumber; 161 return this; 162 } 163 164 public ServerMetricsBuilder setVersion(String version) { 165 this.version = version; 166 return this; 167 } 168 169 public ServerMetricsBuilder setRequestCountPerSecond(long value) { 170 this.requestCountPerSecond = value; 171 return this; 172 } 173 174 public ServerMetricsBuilder setRequestCount(long value) { 175 this.requestCount = value; 176 return this; 177 } 178 179 public ServerMetricsBuilder setReadRequestCount(long value) { 180 this.readRequestCount = value; 181 return this; 182 } 183 184 public ServerMetricsBuilder setWriteRequestCount(long value) { 185 this.writeRequestCount = value; 186 return this; 187 } 188 189 public ServerMetricsBuilder setUsedHeapSize(Size value) { 190 this.usedHeapSize = value; 191 return this; 192 } 193 194 public ServerMetricsBuilder setMaxHeapSize(Size value) { 195 this.maxHeapSize = value; 196 return this; 197 } 198 199 public ServerMetricsBuilder setInfoServerPort(int value) { 200 this.infoServerPort = value; 201 return this; 202 } 203 204 public ServerMetricsBuilder setReplicationLoadSources(List<ReplicationLoadSource> value) { 205 this.sources = value; 206 return this; 207 } 208 209 public ServerMetricsBuilder setReplicationLoadSink(ReplicationLoadSink value) { 210 this.sink = value; 211 return this; 212 } 213 214 public ServerMetricsBuilder setRegionMetrics(List<RegionMetrics> value) { 215 value.forEach(v -> this.regionStatus.put(v.getRegionName(), v)); 216 return this; 217 } 218 219 public ServerMetricsBuilder setUserMetrics(List<UserMetrics> value) { 220 value.forEach(v -> this.userMetrics.put(v.getUserName(), v)); 221 return this; 222 } 223 224 public ServerMetricsBuilder setCoprocessorNames(List<String> value) { 225 coprocessorNames.addAll(value); 226 return this; 227 } 228 229 public ServerMetricsBuilder setReportTimestamp(long value) { 230 this.reportTimestamp = value; 231 return this; 232 } 233 234 public ServerMetricsBuilder setLastReportTimestamp(long value) { 235 this.lastReportTimestamp = value; 236 return this; 237 } 238 239 public ServerMetricsBuilder setTasks(List<ServerTask> tasks) { 240 this.tasks.addAll(tasks); 241 return this; 242 } 243 244 public ServerMetricsBuilder setRegionCachedInfo(Map<String, Integer> value) { 245 this.regionCachedInfo = value; 246 return this; 247 } 248 249 public ServerMetricsBuilder setCacheFreeSize(long blockCacheFreeSize) { 250 this.cacheFreeSize = blockCacheFreeSize; 251 return this; 252 } 253 254 public ServerMetricsBuilder setRegionColdDataInfo(Map<String, Integer> regionColdDataInfo) { 255 this.regionColdDataInfo = regionColdDataInfo; 256 return this; 257 } 258 259 public ServerMetrics build() { 260 return new ServerMetricsImpl(serverName, versionNumber, version, requestCountPerSecond, 261 requestCount, readRequestCount, writeRequestCount, usedHeapSize, maxHeapSize, infoServerPort, 262 sources, sink, regionStatus, coprocessorNames, reportTimestamp, lastReportTimestamp, 263 userMetrics, tasks, regionCachedInfo, cacheFreeSize, regionColdDataInfo); 264 } 265 266 private static class ServerMetricsImpl implements ServerMetrics { 267 private final ServerName serverName; 268 private final int versionNumber; 269 private final String version; 270 private final long requestCountPerSecond; 271 private final long requestCount; 272 private final long readRequestsCount; 273 private final long writeRequestsCount; 274 private final Size usedHeapSize; 275 private final Size maxHeapSize; 276 private final int infoServerPort; 277 private final List<ReplicationLoadSource> sources; 278 @Nullable 279 private final ReplicationLoadSink sink; 280 private final Map<byte[], RegionMetrics> regionStatus; 281 private final Set<String> coprocessorNames; 282 private final long reportTimestamp; 283 private final long lastReportTimestamp; 284 private final Map<byte[], UserMetrics> userMetrics; 285 private final List<ServerTask> tasks; 286 private final Map<String, Integer> regionCachedInfo; 287 private final long cacheFreeSize; 288 private final Map<String, Integer> regionColdDataInfo; 289 290 ServerMetricsImpl(ServerName serverName, int versionNumber, String version, 291 long requestCountPerSecond, long requestCount, long readRequestsCount, 292 long writeRequestsCount, Size usedHeapSize, Size maxHeapSize, int infoServerPort, 293 List<ReplicationLoadSource> sources, ReplicationLoadSink sink, 294 Map<byte[], RegionMetrics> regionStatus, Set<String> coprocessorNames, long reportTimestamp, 295 long lastReportTimestamp, Map<byte[], UserMetrics> userMetrics, List<ServerTask> tasks, 296 Map<String, Integer> regionCachedInfo, long cacheFreeSize, 297 Map<String, Integer> regionColdDataInfo) { 298 this.serverName = Preconditions.checkNotNull(serverName); 299 this.versionNumber = versionNumber; 300 this.version = version; 301 this.requestCountPerSecond = requestCountPerSecond; 302 this.requestCount = requestCount; 303 this.readRequestsCount = readRequestsCount; 304 this.writeRequestsCount = writeRequestsCount; 305 this.usedHeapSize = Preconditions.checkNotNull(usedHeapSize); 306 this.maxHeapSize = Preconditions.checkNotNull(maxHeapSize); 307 this.infoServerPort = infoServerPort; 308 this.sources = Preconditions.checkNotNull(sources); 309 this.sink = sink; 310 this.regionStatus = Preconditions.checkNotNull(regionStatus); 311 this.userMetrics = Preconditions.checkNotNull(userMetrics); 312 this.coprocessorNames = Preconditions.checkNotNull(coprocessorNames); 313 this.reportTimestamp = reportTimestamp; 314 this.lastReportTimestamp = lastReportTimestamp; 315 this.tasks = tasks; 316 this.regionCachedInfo = regionCachedInfo; 317 this.cacheFreeSize = cacheFreeSize; 318 this.regionColdDataInfo = regionColdDataInfo; 319 } 320 321 @Override 322 public ServerName getServerName() { 323 return serverName; 324 } 325 326 @Override 327 public int getVersionNumber() { 328 return versionNumber; 329 } 330 331 @Override 332 public String getVersion() { 333 return version; 334 } 335 336 @Override 337 public long getRequestCountPerSecond() { 338 return requestCountPerSecond; 339 } 340 341 @Override 342 public long getRequestCount() { 343 return requestCount; 344 } 345 346 @Override 347 public long getReadRequestsCount() { 348 return readRequestsCount; 349 } 350 351 @Override 352 public long getWriteRequestsCount() { 353 return writeRequestsCount; 354 } 355 356 @Override 357 public Size getUsedHeapSize() { 358 return usedHeapSize; 359 } 360 361 @Override 362 public Size getMaxHeapSize() { 363 return maxHeapSize; 364 } 365 366 @Override 367 public int getInfoServerPort() { 368 return infoServerPort; 369 } 370 371 @Override 372 public List<ReplicationLoadSource> getReplicationLoadSourceList() { 373 return Collections.unmodifiableList(sources); 374 } 375 376 @Override 377 public Map<String, List<ReplicationLoadSource>> getReplicationLoadSourceMap() { 378 Map<String, List<ReplicationLoadSource>> sourcesMap = new HashMap<>(); 379 for (ReplicationLoadSource loadSource : sources) { 380 sourcesMap.computeIfAbsent(loadSource.getPeerID(), peerId -> new ArrayList<>()) 381 .add(loadSource); 382 } 383 return sourcesMap; 384 } 385 386 @Override 387 public ReplicationLoadSink getReplicationLoadSink() { 388 return sink; 389 } 390 391 @Override 392 public Map<byte[], RegionMetrics> getRegionMetrics() { 393 return Collections.unmodifiableMap(regionStatus); 394 } 395 396 @Override 397 public Map<byte[], UserMetrics> getUserMetrics() { 398 return Collections.unmodifiableMap(userMetrics); 399 } 400 401 @Override 402 public Set<String> getCoprocessorNames() { 403 return Collections.unmodifiableSet(coprocessorNames); 404 } 405 406 @Override 407 public long getReportTimestamp() { 408 return reportTimestamp; 409 } 410 411 @Override 412 public long getLastReportTimestamp() { 413 return lastReportTimestamp; 414 } 415 416 @Override 417 public List<ServerTask> getTasks() { 418 return tasks; 419 } 420 421 @Override 422 public Map<String, Integer> getRegionCachedInfo() { 423 return Collections.unmodifiableMap(regionCachedInfo); 424 } 425 426 @Override 427 public long getCacheFreeSize() { 428 return cacheFreeSize; 429 } 430 431 @Override 432 public Map<String, Integer> getRegionColdDataSize() { 433 return Collections 434 .unmodifiableMap(regionColdDataInfo != null ? regionColdDataInfo : Collections.emptyMap()); 435 } 436 437 @Override 438 public String toString() { 439 int storeCount = 0; 440 int storeFileCount = 0; 441 int storeRefCount = 0; 442 int maxCompactedStoreFileRefCount = 0; 443 long uncompressedStoreFileSizeMB = 0; 444 long storeFileSizeMB = 0; 445 long memStoreSizeMB = 0; 446 long storefileIndexSizeKB = 0; 447 long rootLevelIndexSizeKB = 0; 448 long readRequestsCount = 0; 449 long cpRequestsCount = 0; 450 long writeRequestsCount = 0; 451 long filteredReadRequestsCount = 0; 452 long bloomFilterSizeMB = 0; 453 long compactingCellCount = 0; 454 long compactedCellCount = 0; 455 for (RegionMetrics r : getRegionMetrics().values()) { 456 storeCount += r.getStoreCount(); 457 storeFileCount += r.getStoreFileCount(); 458 storeRefCount += r.getStoreRefCount(); 459 int currentMaxCompactedStoreFileRefCount = r.getMaxCompactedStoreFileRefCount(); 460 maxCompactedStoreFileRefCount = 461 Math.max(maxCompactedStoreFileRefCount, currentMaxCompactedStoreFileRefCount); 462 uncompressedStoreFileSizeMB += 463 (long) r.getUncompressedStoreFileSize().get(Size.Unit.MEGABYTE); 464 storeFileSizeMB += (long) r.getStoreFileSize().get(Size.Unit.MEGABYTE); 465 memStoreSizeMB += (long) r.getMemStoreSize().get(Size.Unit.MEGABYTE); 466 storefileIndexSizeKB += 467 (long) r.getStoreFileUncompressedDataIndexSize().get(Size.Unit.KILOBYTE); 468 readRequestsCount += r.getReadRequestCount(); 469 cpRequestsCount += r.getCpRequestCount(); 470 writeRequestsCount += r.getWriteRequestCount(); 471 filteredReadRequestsCount += r.getFilteredReadRequestCount(); 472 rootLevelIndexSizeKB += (long) r.getStoreFileRootLevelIndexSize().get(Size.Unit.KILOBYTE); 473 bloomFilterSizeMB += (long) r.getBloomFilterSize().get(Size.Unit.MEGABYTE); 474 compactedCellCount += r.getCompactedCellCount(); 475 compactingCellCount += r.getCompactingCellCount(); 476 } 477 StringBuilder sb = Strings.appendKeyValue(new StringBuilder(), "requestsPerSecond", 478 Double.valueOf(getRequestCountPerSecond())); 479 Strings.appendKeyValue(sb, "numberOfOnlineRegions", 480 Integer.valueOf(getRegionMetrics().size())); 481 Strings.appendKeyValue(sb, "usedHeapMB", getUsedHeapSize()); 482 Strings.appendKeyValue(sb, "maxHeapMB", getMaxHeapSize()); 483 Strings.appendKeyValue(sb, "numberOfStores", storeCount); 484 Strings.appendKeyValue(sb, "numberOfStorefiles", storeFileCount); 485 Strings.appendKeyValue(sb, "storeRefCount", storeRefCount); 486 Strings.appendKeyValue(sb, "maxCompactedStoreFileRefCount", maxCompactedStoreFileRefCount); 487 Strings.appendKeyValue(sb, "storefileUncompressedSizeMB", uncompressedStoreFileSizeMB); 488 Strings.appendKeyValue(sb, "storefileSizeMB", storeFileSizeMB); 489 if (uncompressedStoreFileSizeMB != 0) { 490 Strings.appendKeyValue(sb, "compressionRatio", 491 String.format("%.4f", (float) storeFileSizeMB / (float) uncompressedStoreFileSizeMB)); 492 } 493 Strings.appendKeyValue(sb, "memstoreSizeMB", memStoreSizeMB); 494 Strings.appendKeyValue(sb, "readRequestsCount", readRequestsCount); 495 Strings.appendKeyValue(sb, "cpRequestsCount", cpRequestsCount); 496 Strings.appendKeyValue(sb, "filteredReadRequestsCount", filteredReadRequestsCount); 497 Strings.appendKeyValue(sb, "writeRequestsCount", writeRequestsCount); 498 Strings.appendKeyValue(sb, "rootIndexSizeKB", rootLevelIndexSizeKB); 499 Strings.appendKeyValue(sb, "totalStaticIndexSizeKB", storefileIndexSizeKB); 500 Strings.appendKeyValue(sb, "totalStaticBloomSizeKB", bloomFilterSizeMB); 501 Strings.appendKeyValue(sb, "totalCompactingKVs", compactingCellCount); 502 Strings.appendKeyValue(sb, "currentCompactedKVs", compactedCellCount); 503 float compactionProgressPct = Float.NaN; 504 if (compactingCellCount > 0) { 505 compactionProgressPct = Float.valueOf((float) compactedCellCount / compactingCellCount); 506 } 507 Strings.appendKeyValue(sb, "compactionProgressPct", compactionProgressPct); 508 Strings.appendKeyValue(sb, "coprocessors", getCoprocessorNames()); 509 return sb.toString(); 510 } 511 } 512}