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) { 052 return newBuilder(sn).setVersionNumber(versionNumber).build(); 053 } 054 055 public static ServerMetrics toServerMetrics(ClusterStatusProtos.LiveServerInfo serverInfo) { 056 return toServerMetrics(ProtobufUtil.toServerName(serverInfo.getServer()), 0, 057 serverInfo.getServerLoad()); 058 } 059 060 public static ServerMetrics toServerMetrics(ServerName serverName, 061 ClusterStatusProtos.ServerLoad serverLoadPB) { 062 return toServerMetrics(serverName, 0, serverLoadPB); 063 } 064 065 public static ServerMetrics toServerMetrics(ServerName serverName, int versionNumber, 066 ClusterStatusProtos.ServerLoad serverLoadPB) { 067 return ServerMetricsBuilder.newBuilder(serverName).setVersionNumber(versionNumber) 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) 077 .collect(Collectors.toList())) 078 .setReplicationLoadSources(serverLoadPB.getReplLoadSourceList().stream() 079 .map(ProtobufUtil::toReplicationLoadSource) 080 .collect(Collectors.toList())) 081 .setReplicationLoadSink(serverLoadPB.hasReplLoadSink() ? 082 ProtobufUtil.toReplicationLoadSink(serverLoadPB.getReplLoadSink()) : null) 083 .setReportTimestamp(serverLoadPB.getReportEndTime()) 084 .setLastReportTimestamp(serverLoadPB.getReportStartTime()) 085 .build(); 086 } 087 088 public static List<HBaseProtos.Coprocessor> toCoprocessor(Collection<String> names) { 089 return names.stream() 090 .map(n -> HBaseProtos.Coprocessor.newBuilder().setName(n).build()) 091 .collect(Collectors.toList()); 092 } 093 094 public static ClusterStatusProtos.ServerLoad toServerLoad(ServerMetrics metrics) { 095 ClusterStatusProtos.ServerLoad.Builder builder = ClusterStatusProtos.ServerLoad.newBuilder() 096 .setNumberOfRequests(metrics.getRequestCountPerSecond()) 097 .setTotalNumberOfRequests(metrics.getRequestCount()) 098 .setInfoServerPort(metrics.getInfoServerPort()) 099 .setMaxHeapMB((int) metrics.getMaxHeapSize().get(Size.Unit.MEGABYTE)) 100 .setUsedHeapMB((int) metrics.getUsedHeapSize().get(Size.Unit.MEGABYTE)) 101 .addAllCoprocessors(toCoprocessor(metrics.getCoprocessorNames())) 102 .addAllRegionLoads(metrics.getRegionMetrics().values().stream() 103 .map(RegionMetricsBuilder::toRegionLoad) 104 .collect(Collectors.toList())) 105 .addAllReplLoadSource(metrics.getReplicationLoadSourceList().stream() 106 .map(ProtobufUtil::toReplicationLoadSource) 107 .collect(Collectors.toList())) 108 .setReportStartTime(metrics.getLastReportTimestamp()) 109 .setReportEndTime(metrics.getReportTimestamp()); 110 if (metrics.getReplicationLoadSink() != null) { 111 builder.setReplLoadSink(ProtobufUtil.toReplicationLoadSink( 112 metrics.getReplicationLoadSink())); 113 } 114 return builder.build(); 115 } 116 117 public static ServerMetricsBuilder newBuilder(ServerName sn) { 118 return new ServerMetricsBuilder(sn); 119 } 120 121 private final ServerName serverName; 122 private int versionNumber; 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 setRequestCountPerSecond(long value) { 145 this.requestCountPerSecond = value; 146 return this; 147 } 148 149 public ServerMetricsBuilder setRequestCount(long value) { 150 this.requestCount = value; 151 return this; 152 } 153 154 public ServerMetricsBuilder setUsedHeapSize(Size value) { 155 this.usedHeapSize = value; 156 return this; 157 } 158 159 public ServerMetricsBuilder setMaxHeapSize(Size value) { 160 this.maxHeapSize = value; 161 return this; 162 } 163 164 public ServerMetricsBuilder setInfoServerPort(int value) { 165 this.infoServerPort = value; 166 return this; 167 } 168 169 public ServerMetricsBuilder setReplicationLoadSources(List<ReplicationLoadSource> value) { 170 this.sources = value; 171 return this; 172 } 173 174 public ServerMetricsBuilder setReplicationLoadSink(ReplicationLoadSink value) { 175 this.sink = value; 176 return this; 177 } 178 179 public ServerMetricsBuilder setRegionMetrics(List<RegionMetrics> value) { 180 value.forEach(v -> this.regionStatus.put(v.getRegionName(), v)); 181 return this; 182 } 183 184 public ServerMetricsBuilder setCoprocessorNames(List<String> value) { 185 coprocessorNames.addAll(value); 186 return this; 187 } 188 189 public ServerMetricsBuilder setReportTimestamp(long value) { 190 this.reportTimestamp = value; 191 return this; 192 } 193 194 public ServerMetricsBuilder setLastReportTimestamp(long value) { 195 this.lastReportTimestamp = value; 196 return this; 197 } 198 199 public ServerMetrics build() { 200 return new ServerMetricsImpl( 201 serverName, 202 versionNumber, 203 requestCountPerSecond, 204 requestCount, 205 usedHeapSize, 206 maxHeapSize, 207 infoServerPort, 208 sources, 209 sink, 210 regionStatus, 211 coprocessorNames, 212 reportTimestamp, 213 lastReportTimestamp); 214 } 215 216 private static class ServerMetricsImpl implements ServerMetrics { 217 private final ServerName serverName; 218 private final int versionNumber; 219 private final long requestCountPerSecond; 220 private final long requestCount; 221 private final Size usedHeapSize; 222 private final Size maxHeapSize; 223 private final int infoServerPort; 224 private final List<ReplicationLoadSource> sources; 225 @Nullable 226 private final ReplicationLoadSink sink; 227 private final Map<byte[], RegionMetrics> regionStatus; 228 private final Set<String> coprocessorNames; 229 private final long reportTimestamp; 230 private final long lastReportTimestamp; 231 232 ServerMetricsImpl(ServerName serverName, int versionNumber, long requestCountPerSecond, 233 long requestCount, Size usedHeapSize, Size maxHeapSize, int infoServerPort, 234 List<ReplicationLoadSource> sources, ReplicationLoadSink sink, 235 Map<byte[], RegionMetrics> regionStatus, Set<String> coprocessorNames, long reportTimestamp, 236 long lastReportTimestamp) { 237 this.serverName = Preconditions.checkNotNull(serverName); 238 this.versionNumber = versionNumber; 239 this.requestCountPerSecond = requestCountPerSecond; 240 this.requestCount = requestCount; 241 this.usedHeapSize = Preconditions.checkNotNull(usedHeapSize); 242 this.maxHeapSize = Preconditions.checkNotNull(maxHeapSize); 243 this.infoServerPort = infoServerPort; 244 this.sources = Preconditions.checkNotNull(sources); 245 this.sink = sink; 246 this.regionStatus = Preconditions.checkNotNull(regionStatus); 247 this.coprocessorNames =Preconditions.checkNotNull(coprocessorNames); 248 this.reportTimestamp = reportTimestamp; 249 this.lastReportTimestamp = lastReportTimestamp; 250 } 251 252 @Override 253 public ServerName getServerName() { 254 return serverName; 255 } 256 257 @Override 258 public int getVersionNumber() { 259 return versionNumber; 260 } 261 262 @Override 263 public long getRequestCountPerSecond() { 264 return requestCountPerSecond; 265 } 266 267 @Override 268 public long getRequestCount() { 269 return requestCount; 270 } 271 272 @Override 273 public Size getUsedHeapSize() { 274 return usedHeapSize; 275 } 276 277 @Override 278 public Size getMaxHeapSize() { 279 return maxHeapSize; 280 } 281 282 @Override 283 public int getInfoServerPort() { 284 return infoServerPort; 285 } 286 287 @Override 288 public List<ReplicationLoadSource> getReplicationLoadSourceList() { 289 return Collections.unmodifiableList(sources); 290 } 291 292 @Override 293 public ReplicationLoadSink getReplicationLoadSink() { 294 return sink; 295 } 296 297 @Override 298 public Map<byte[], RegionMetrics> getRegionMetrics() { 299 return Collections.unmodifiableMap(regionStatus); 300 } 301 302 @Override 303 public Set<String> getCoprocessorNames() { 304 return Collections.unmodifiableSet(coprocessorNames); 305 } 306 307 @Override 308 public long getReportTimestamp() { 309 return reportTimestamp; 310 } 311 312 @Override 313 public long getLastReportTimestamp() { 314 return lastReportTimestamp; 315 } 316 317 @Override 318 public String toString() { 319 int storeCount = 0; 320 int storeFileCount = 0; 321 long uncompressedStoreFileSizeMB = 0; 322 long storeFileSizeMB = 0; 323 long memStoreSizeMB = 0; 324 long storefileIndexSizeKB = 0; 325 long rootLevelIndexSizeKB = 0; 326 long readRequestsCount = 0; 327 long writeRequestsCount = 0; 328 long filteredReadRequestsCount = 0; 329 long bloomFilterSizeMB = 0; 330 long compactingCellCount = 0; 331 long compactedCellCount = 0; 332 for (RegionMetrics r : getRegionMetrics().values()) { 333 storeCount += r.getStoreCount(); 334 storeFileCount += r.getStoreFileCount(); 335 uncompressedStoreFileSizeMB += r.getUncompressedStoreFileSize().get(Size.Unit.MEGABYTE); 336 storeFileSizeMB += r.getStoreFileSize().get(Size.Unit.MEGABYTE); 337 memStoreSizeMB += r.getMemStoreSize().get(Size.Unit.MEGABYTE); 338 storefileIndexSizeKB += r.getStoreFileUncompressedDataIndexSize().get(Size.Unit.KILOBYTE); 339 readRequestsCount += r.getReadRequestCount(); 340 writeRequestsCount += r.getWriteRequestCount(); 341 filteredReadRequestsCount += r.getFilteredReadRequestCount(); 342 rootLevelIndexSizeKB += r.getStoreFileRootLevelIndexSize().get(Size.Unit.KILOBYTE); 343 bloomFilterSizeMB += r.getBloomFilterSize().get(Size.Unit.MEGABYTE); 344 compactedCellCount += r.getCompactedCellCount(); 345 compactingCellCount += r.getCompactingCellCount(); 346 } 347 StringBuilder sb = Strings.appendKeyValue(new StringBuilder(), "requestsPerSecond", 348 Double.valueOf(getRequestCountPerSecond())); 349 Strings.appendKeyValue(sb, "numberOfOnlineRegions", 350 Integer.valueOf(getRegionMetrics().size())); 351 Strings.appendKeyValue(sb, "usedHeapMB", getUsedHeapSize()); 352 Strings.appendKeyValue(sb, "maxHeapMB", getMaxHeapSize()); 353 Strings.appendKeyValue(sb, "numberOfStores", storeCount); 354 Strings.appendKeyValue(sb, "numberOfStorefiles", storeFileCount); 355 Strings.appendKeyValue(sb, "storefileUncompressedSizeMB", uncompressedStoreFileSizeMB); 356 Strings.appendKeyValue(sb, "storefileSizeMB", storeFileSizeMB); 357 if (uncompressedStoreFileSizeMB != 0) { 358 Strings.appendKeyValue(sb, "compressionRatio", String.format("%.4f", 359 (float) storeFileSizeMB / (float) uncompressedStoreFileSizeMB)); 360 } 361 Strings.appendKeyValue(sb, "memstoreSizeMB", memStoreSizeMB); 362 Strings.appendKeyValue(sb, "readRequestsCount", readRequestsCount); 363 Strings.appendKeyValue(sb, "filteredReadRequestsCount", filteredReadRequestsCount); 364 Strings.appendKeyValue(sb, "writeRequestsCount", writeRequestsCount); 365 Strings.appendKeyValue(sb, "rootIndexSizeKB", rootLevelIndexSizeKB); 366 Strings.appendKeyValue(sb, "totalStaticIndexSizeKB", storefileIndexSizeKB); 367 Strings.appendKeyValue(sb, "totalStaticBloomSizeKB", bloomFilterSizeMB); 368 Strings.appendKeyValue(sb, "totalCompactingKVs", compactingCellCount); 369 Strings.appendKeyValue(sb, "currentCompactedKVs", compactedCellCount); 370 float compactionProgressPct = Float.NaN; 371 if (compactingCellCount > 0) { 372 compactionProgressPct = 373 Float.valueOf((float) compactedCellCount / compactingCellCount); 374 } 375 Strings.appendKeyValue(sb, "compactionProgressPct", compactionProgressPct); 376 Strings.appendKeyValue(sb, "coprocessors", getCoprocessorNames()); 377 return sb.toString(); 378 } 379 } 380}