001/** 002 * Copyright The Apache Software Foundation 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 * http://www.apache.org/licenses/LICENSE-2.0 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.hadoop.hbase; 019 020import edu.umd.cs.findbugs.annotations.Nullable; 021import java.util.Collection; 022import java.util.Collections; 023import java.util.List; 024import java.util.Map; 025import java.util.Set; 026import java.util.TreeMap; 027import java.util.TreeSet; 028import java.util.stream.Collectors; 029import org.apache.hadoop.hbase.replication.ReplicationLoadSink; 030import org.apache.hadoop.hbase.replication.ReplicationLoadSource; 031import org.apache.hadoop.hbase.util.Bytes; 032import org.apache.hadoop.hbase.util.Strings; 033import org.apache.yetus.audience.InterfaceAudience; 034 035import org.apache.hbase.thirdparty.com.google.common.base.Preconditions; 036import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 037import org.apache.hadoop.hbase.shaded.protobuf.generated.ClusterStatusProtos; 038import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos; 039 040@InterfaceAudience.Private 041public final class ServerMetricsBuilder { 042 043 /** 044 * @param sn the server name 045 * @return a empty metrics 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 return ServerMetricsBuilder.newBuilder(serverName) 068 .setRequestCountPerSecond(serverLoadPB.getNumberOfRequests()) 069 .setRequestCount(serverLoadPB.getTotalNumberOfRequests()) 070 .setInfoServerPort(serverLoadPB.getInfoServerPort()) 071 .setMaxHeapSize(new Size(serverLoadPB.getMaxHeapMB(), Size.Unit.MEGABYTE)) 072 .setUsedHeapSize(new Size(serverLoadPB.getUsedHeapMB(), Size.Unit.MEGABYTE)) 073 .setCoprocessorNames(serverLoadPB.getCoprocessorsList().stream() 074 .map(HBaseProtos.Coprocessor::getName).collect(Collectors.toList())) 075 .setRegionMetrics(serverLoadPB.getRegionLoadsList().stream() 076 .map(RegionMetricsBuilder::toRegionMetrics).collect(Collectors.toList())) 077 .setReplicationLoadSources(serverLoadPB.getReplLoadSourceList().stream() 078 .map(ProtobufUtil::toReplicationLoadSource).collect(Collectors.toList())) 079 .setReplicationLoadSink(serverLoadPB.hasReplLoadSink() 080 ? ProtobufUtil.toReplicationLoadSink(serverLoadPB.getReplLoadSink()) 081 : null) 082 .setReportTimestamp(serverLoadPB.getReportEndTime()) 083 .setLastReportTimestamp(serverLoadPB.getReportStartTime()).setVersionNumber(versionNumber) 084 .setVersion(version).build(); 085 } 086 087 public static List<HBaseProtos.Coprocessor> toCoprocessor(Collection<String> names) { 088 return names.stream() 089 .map(n -> HBaseProtos.Coprocessor.newBuilder().setName(n).build()) 090 .collect(Collectors.toList()); 091 } 092 093 public static ClusterStatusProtos.ServerLoad toServerLoad(ServerMetrics metrics) { 094 ClusterStatusProtos.ServerLoad.Builder builder = ClusterStatusProtos.ServerLoad.newBuilder() 095 .setNumberOfRequests(metrics.getRequestCountPerSecond()) 096 .setTotalNumberOfRequests(metrics.getRequestCount()) 097 .setInfoServerPort(metrics.getInfoServerPort()) 098 .setMaxHeapMB((int) metrics.getMaxHeapSize().get(Size.Unit.MEGABYTE)) 099 .setUsedHeapMB((int) metrics.getUsedHeapSize().get(Size.Unit.MEGABYTE)) 100 .addAllCoprocessors(toCoprocessor(metrics.getCoprocessorNames())) 101 .addAllRegionLoads(metrics.getRegionMetrics().values().stream() 102 .map(RegionMetricsBuilder::toRegionLoad) 103 .collect(Collectors.toList())) 104 .addAllReplLoadSource(metrics.getReplicationLoadSourceList().stream() 105 .map(ProtobufUtil::toReplicationLoadSource) 106 .collect(Collectors.toList())) 107 .setReportStartTime(metrics.getLastReportTimestamp()) 108 .setReportEndTime(metrics.getReportTimestamp()); 109 if (metrics.getReplicationLoadSink() != null) { 110 builder.setReplLoadSink(ProtobufUtil.toReplicationLoadSink( 111 metrics.getReplicationLoadSink())); 112 } 113 return builder.build(); 114 } 115 116 public static ServerMetricsBuilder newBuilder(ServerName sn) { 117 return new ServerMetricsBuilder(sn); 118 } 119 120 private final ServerName serverName; 121 private int versionNumber; 122 private String version = "0.0.0"; 123 private long requestCountPerSecond; 124 private long requestCount; 125 private Size usedHeapSize = Size.ZERO; 126 private Size maxHeapSize = Size.ZERO; 127 private int infoServerPort; 128 private List<ReplicationLoadSource> sources = Collections.emptyList(); 129 @Nullable 130 private ReplicationLoadSink sink = null; 131 private final Map<byte[], RegionMetrics> regionStatus = new TreeMap<>(Bytes.BYTES_COMPARATOR); 132 private final Set<String> coprocessorNames = new TreeSet<>(); 133 private long reportTimestamp = System.currentTimeMillis(); 134 private long lastReportTimestamp = 0; 135 private ServerMetricsBuilder(ServerName serverName) { 136 this.serverName = serverName; 137 } 138 139 public ServerMetricsBuilder setVersionNumber(int versionNumber) { 140 this.versionNumber = versionNumber; 141 return this; 142 } 143 144 public ServerMetricsBuilder setVersion(String version) { 145 this.version = version; 146 return this; 147 } 148 149 public ServerMetricsBuilder setRequestCountPerSecond(long value) { 150 this.requestCountPerSecond = value; 151 return this; 152 } 153 154 public ServerMetricsBuilder setRequestCount(long value) { 155 this.requestCount = value; 156 return this; 157 } 158 159 public ServerMetricsBuilder setUsedHeapSize(Size value) { 160 this.usedHeapSize = value; 161 return this; 162 } 163 164 public ServerMetricsBuilder setMaxHeapSize(Size value) { 165 this.maxHeapSize = value; 166 return this; 167 } 168 169 public ServerMetricsBuilder setInfoServerPort(int value) { 170 this.infoServerPort = value; 171 return this; 172 } 173 174 public ServerMetricsBuilder setReplicationLoadSources(List<ReplicationLoadSource> value) { 175 this.sources = value; 176 return this; 177 } 178 179 public ServerMetricsBuilder setReplicationLoadSink(ReplicationLoadSink value) { 180 this.sink = value; 181 return this; 182 } 183 184 public ServerMetricsBuilder setRegionMetrics(List<RegionMetrics> value) { 185 value.forEach(v -> this.regionStatus.put(v.getRegionName(), v)); 186 return this; 187 } 188 189 public ServerMetricsBuilder setCoprocessorNames(List<String> value) { 190 coprocessorNames.addAll(value); 191 return this; 192 } 193 194 public ServerMetricsBuilder setReportTimestamp(long value) { 195 this.reportTimestamp = value; 196 return this; 197 } 198 199 public ServerMetricsBuilder setLastReportTimestamp(long value) { 200 this.lastReportTimestamp = value; 201 return this; 202 } 203 204 public ServerMetrics build() { 205 return new ServerMetricsImpl( 206 serverName, 207 versionNumber, 208 version, 209 requestCountPerSecond, 210 requestCount, 211 usedHeapSize, 212 maxHeapSize, 213 infoServerPort, 214 sources, 215 sink, 216 regionStatus, 217 coprocessorNames, 218 reportTimestamp, 219 lastReportTimestamp); 220 } 221 222 private static class ServerMetricsImpl implements ServerMetrics { 223 private final ServerName serverName; 224 private final int versionNumber; 225 private final String version; 226 private final long requestCountPerSecond; 227 private final long requestCount; 228 private final Size usedHeapSize; 229 private final Size maxHeapSize; 230 private final int infoServerPort; 231 private final List<ReplicationLoadSource> sources; 232 @Nullable 233 private final ReplicationLoadSink sink; 234 private final Map<byte[], RegionMetrics> regionStatus; 235 private final Set<String> coprocessorNames; 236 private final long reportTimestamp; 237 private final long lastReportTimestamp; 238 239 ServerMetricsImpl(ServerName serverName, int versionNumber, String version, 240 long requestCountPerSecond, long requestCount, Size usedHeapSize, Size maxHeapSize, 241 int infoServerPort, List<ReplicationLoadSource> sources, ReplicationLoadSink sink, 242 Map<byte[], RegionMetrics> regionStatus, Set<String> coprocessorNames, long reportTimestamp, 243 long lastReportTimestamp) { 244 this.serverName = Preconditions.checkNotNull(serverName); 245 this.versionNumber = versionNumber; 246 this.version = version; 247 this.requestCountPerSecond = requestCountPerSecond; 248 this.requestCount = requestCount; 249 this.usedHeapSize = Preconditions.checkNotNull(usedHeapSize); 250 this.maxHeapSize = Preconditions.checkNotNull(maxHeapSize); 251 this.infoServerPort = infoServerPort; 252 this.sources = Preconditions.checkNotNull(sources); 253 this.sink = sink; 254 this.regionStatus = Preconditions.checkNotNull(regionStatus); 255 this.coprocessorNames =Preconditions.checkNotNull(coprocessorNames); 256 this.reportTimestamp = reportTimestamp; 257 this.lastReportTimestamp = lastReportTimestamp; 258 } 259 260 @Override 261 public ServerName getServerName() { 262 return serverName; 263 } 264 265 @Override 266 public int getVersionNumber() { 267 return versionNumber; 268 } 269 270 public String getVersion() { 271 return version; 272 } 273 274 @Override 275 public long getRequestCountPerSecond() { 276 return requestCountPerSecond; 277 } 278 279 @Override 280 public long getRequestCount() { 281 return requestCount; 282 } 283 284 @Override 285 public Size getUsedHeapSize() { 286 return usedHeapSize; 287 } 288 289 @Override 290 public Size getMaxHeapSize() { 291 return maxHeapSize; 292 } 293 294 @Override 295 public int getInfoServerPort() { 296 return infoServerPort; 297 } 298 299 @Override 300 public List<ReplicationLoadSource> getReplicationLoadSourceList() { 301 return Collections.unmodifiableList(sources); 302 } 303 304 @Override 305 public ReplicationLoadSink getReplicationLoadSink() { 306 return sink; 307 } 308 309 @Override 310 public Map<byte[], RegionMetrics> getRegionMetrics() { 311 return Collections.unmodifiableMap(regionStatus); 312 } 313 314 @Override 315 public Set<String> getCoprocessorNames() { 316 return Collections.unmodifiableSet(coprocessorNames); 317 } 318 319 @Override 320 public long getReportTimestamp() { 321 return reportTimestamp; 322 } 323 324 @Override 325 public long getLastReportTimestamp() { 326 return lastReportTimestamp; 327 } 328 329 @Override 330 public String toString() { 331 int storeCount = 0; 332 int storeFileCount = 0; 333 long uncompressedStoreFileSizeMB = 0; 334 long storeFileSizeMB = 0; 335 long memStoreSizeMB = 0; 336 long storefileIndexSizeKB = 0; 337 long rootLevelIndexSizeKB = 0; 338 long readRequestsCount = 0; 339 long writeRequestsCount = 0; 340 long filteredReadRequestsCount = 0; 341 long bloomFilterSizeMB = 0; 342 long compactingCellCount = 0; 343 long compactedCellCount = 0; 344 for (RegionMetrics r : getRegionMetrics().values()) { 345 storeCount += r.getStoreCount(); 346 storeFileCount += r.getStoreFileCount(); 347 uncompressedStoreFileSizeMB += r.getUncompressedStoreFileSize().get(Size.Unit.MEGABYTE); 348 storeFileSizeMB += r.getStoreFileSize().get(Size.Unit.MEGABYTE); 349 memStoreSizeMB += r.getMemStoreSize().get(Size.Unit.MEGABYTE); 350 storefileIndexSizeKB += r.getStoreFileUncompressedDataIndexSize().get(Size.Unit.KILOBYTE); 351 readRequestsCount += r.getReadRequestCount(); 352 writeRequestsCount += r.getWriteRequestCount(); 353 filteredReadRequestsCount += r.getFilteredReadRequestCount(); 354 rootLevelIndexSizeKB += r.getStoreFileRootLevelIndexSize().get(Size.Unit.KILOBYTE); 355 bloomFilterSizeMB += r.getBloomFilterSize().get(Size.Unit.MEGABYTE); 356 compactedCellCount += r.getCompactedCellCount(); 357 compactingCellCount += r.getCompactingCellCount(); 358 } 359 StringBuilder sb = Strings.appendKeyValue(new StringBuilder(), "requestsPerSecond", 360 Double.valueOf(getRequestCountPerSecond())); 361 Strings.appendKeyValue(sb, "numberOfOnlineRegions", 362 Integer.valueOf(getRegionMetrics().size())); 363 Strings.appendKeyValue(sb, "usedHeapMB", getUsedHeapSize()); 364 Strings.appendKeyValue(sb, "maxHeapMB", getMaxHeapSize()); 365 Strings.appendKeyValue(sb, "numberOfStores", storeCount); 366 Strings.appendKeyValue(sb, "numberOfStorefiles", storeFileCount); 367 Strings.appendKeyValue(sb, "storefileUncompressedSizeMB", uncompressedStoreFileSizeMB); 368 Strings.appendKeyValue(sb, "storefileSizeMB", storeFileSizeMB); 369 if (uncompressedStoreFileSizeMB != 0) { 370 Strings.appendKeyValue(sb, "compressionRatio", String.format("%.4f", 371 (float) storeFileSizeMB / (float) uncompressedStoreFileSizeMB)); 372 } 373 Strings.appendKeyValue(sb, "memstoreSizeMB", memStoreSizeMB); 374 Strings.appendKeyValue(sb, "readRequestsCount", readRequestsCount); 375 Strings.appendKeyValue(sb, "filteredReadRequestsCount", filteredReadRequestsCount); 376 Strings.appendKeyValue(sb, "writeRequestsCount", writeRequestsCount); 377 Strings.appendKeyValue(sb, "rootIndexSizeKB", rootLevelIndexSizeKB); 378 Strings.appendKeyValue(sb, "totalStaticIndexSizeKB", storefileIndexSizeKB); 379 Strings.appendKeyValue(sb, "totalStaticBloomSizeKB", bloomFilterSizeMB); 380 Strings.appendKeyValue(sb, "totalCompactingKVs", compactingCellCount); 381 Strings.appendKeyValue(sb, "currentCompactedKVs", compactedCellCount); 382 float compactionProgressPct = Float.NaN; 383 if (compactingCellCount > 0) { 384 compactionProgressPct = 385 Float.valueOf((float) compactedCellCount / compactingCellCount); 386 } 387 Strings.appendKeyValue(sb, "compactionProgressPct", compactionProgressPct); 388 Strings.appendKeyValue(sb, "coprocessors", getCoprocessorNames()); 389 return sb.toString(); 390 } 391 } 392}