blob: 5975d392ac763fbc29d4fc360a8bb3b669d076e4 [file] [log] [blame]
/**
* Copyright The Apache Software Foundation
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.stream.Collectors;
import org.apache.hadoop.hbase.replication.ReplicationLoadSink;
import org.apache.hadoop.hbase.replication.ReplicationLoadSource;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Strings;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.shaded.protobuf.generated.ClusterStatusProtos;
import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;
@InterfaceAudience.Private
public final class ServerMetricsBuilder {
/**
* @param sn the server name
* @return a empty metrics
*/
public static ServerMetrics of(ServerName sn) {
return newBuilder(sn).build();
}
public static ServerMetrics of(ServerName sn, int versionNumber, String version) {
return newBuilder(sn).setVersionNumber(versionNumber).setVersion(version).build();
}
public static ServerMetrics toServerMetrics(ClusterStatusProtos.LiveServerInfo serverInfo) {
return toServerMetrics(ProtobufUtil.toServerName(serverInfo.getServer()), 0, "0.0.0",
serverInfo.getServerLoad());
}
public static ServerMetrics toServerMetrics(ServerName serverName,
ClusterStatusProtos.ServerLoad serverLoadPB) {
return toServerMetrics(serverName, 0, "0.0.0", serverLoadPB);
}
public static ServerMetrics toServerMetrics(ServerName serverName, int versionNumber,
String version, ClusterStatusProtos.ServerLoad serverLoadPB) {
return ServerMetricsBuilder.newBuilder(serverName)
.setRequestCountPerSecond(serverLoadPB.getNumberOfRequests())
.setRequestCount(serverLoadPB.getTotalNumberOfRequests())
.setInfoServerPort(serverLoadPB.getInfoServerPort())
.setMaxHeapSize(new Size(serverLoadPB.getMaxHeapMB(), Size.Unit.MEGABYTE))
.setUsedHeapSize(new Size(serverLoadPB.getUsedHeapMB(), Size.Unit.MEGABYTE))
.setCoprocessorNames(serverLoadPB.getCoprocessorsList().stream()
.map(HBaseProtos.Coprocessor::getName).collect(Collectors.toList()))
.setRegionMetrics(serverLoadPB.getRegionLoadsList().stream()
.map(RegionMetricsBuilder::toRegionMetrics).collect(Collectors.toList()))
.setUserMetrics(serverLoadPB.getUserLoadsList().stream()
.map(UserMetricsBuilder::toUserMetrics).collect(Collectors.toList()))
.setReplicationLoadSources(serverLoadPB.getReplLoadSourceList().stream()
.map(ProtobufUtil::toReplicationLoadSource).collect(Collectors.toList()))
.setReplicationLoadSink(serverLoadPB.hasReplLoadSink()
? ProtobufUtil.toReplicationLoadSink(serverLoadPB.getReplLoadSink())
: null)
.setReportTimestamp(serverLoadPB.getReportEndTime())
.setLastReportTimestamp(serverLoadPB.getReportStartTime()).setVersionNumber(versionNumber)
.setVersion(version).build();
}
public static List<HBaseProtos.Coprocessor> toCoprocessor(Collection<String> names) {
return names.stream()
.map(n -> HBaseProtos.Coprocessor.newBuilder().setName(n).build())
.collect(Collectors.toList());
}
public static ClusterStatusProtos.ServerLoad toServerLoad(ServerMetrics metrics) {
ClusterStatusProtos.ServerLoad.Builder builder = ClusterStatusProtos.ServerLoad.newBuilder()
.setNumberOfRequests(metrics.getRequestCountPerSecond())
.setTotalNumberOfRequests(metrics.getRequestCount())
.setInfoServerPort(metrics.getInfoServerPort())
.setMaxHeapMB((int) metrics.getMaxHeapSize().get(Size.Unit.MEGABYTE))
.setUsedHeapMB((int) metrics.getUsedHeapSize().get(Size.Unit.MEGABYTE))
.addAllCoprocessors(toCoprocessor(metrics.getCoprocessorNames())).addAllRegionLoads(
metrics.getRegionMetrics().values().stream().map(RegionMetricsBuilder::toRegionLoad)
.collect(Collectors.toList())).addAllUserLoads(
metrics.getUserMetrics().values().stream().map(UserMetricsBuilder::toUserMetrics)
.collect(Collectors.toList())).addAllReplLoadSource(
metrics.getReplicationLoadSourceList().stream()
.map(ProtobufUtil::toReplicationLoadSource).collect(Collectors.toList()))
.setReportStartTime(metrics.getLastReportTimestamp())
.setReportEndTime(metrics.getReportTimestamp());
if (metrics.getReplicationLoadSink() != null) {
builder.setReplLoadSink(ProtobufUtil.toReplicationLoadSink(metrics.getReplicationLoadSink()));
}
return builder.build();
}
public static ServerMetricsBuilder newBuilder(ServerName sn) {
return new ServerMetricsBuilder(sn);
}
private final ServerName serverName;
private int versionNumber;
private String version = "0.0.0";
private long requestCountPerSecond;
private long requestCount;
private Size usedHeapSize = Size.ZERO;
private Size maxHeapSize = Size.ZERO;
private int infoServerPort;
private List<ReplicationLoadSource> sources = Collections.emptyList();
@Nullable
private ReplicationLoadSink sink = null;
private final Map<byte[], RegionMetrics> regionStatus = new TreeMap<>(Bytes.BYTES_COMPARATOR);
private final Map<byte[], UserMetrics> userMetrics = new TreeMap<>(Bytes.BYTES_COMPARATOR);
private final Set<String> coprocessorNames = new TreeSet<>();
private long reportTimestamp = System.currentTimeMillis();
private long lastReportTimestamp = 0;
private ServerMetricsBuilder(ServerName serverName) {
this.serverName = serverName;
}
public ServerMetricsBuilder setVersionNumber(int versionNumber) {
this.versionNumber = versionNumber;
return this;
}
public ServerMetricsBuilder setVersion(String version) {
this.version = version;
return this;
}
public ServerMetricsBuilder setRequestCountPerSecond(long value) {
this.requestCountPerSecond = value;
return this;
}
public ServerMetricsBuilder setRequestCount(long value) {
this.requestCount = value;
return this;
}
public ServerMetricsBuilder setUsedHeapSize(Size value) {
this.usedHeapSize = value;
return this;
}
public ServerMetricsBuilder setMaxHeapSize(Size value) {
this.maxHeapSize = value;
return this;
}
public ServerMetricsBuilder setInfoServerPort(int value) {
this.infoServerPort = value;
return this;
}
public ServerMetricsBuilder setReplicationLoadSources(List<ReplicationLoadSource> value) {
this.sources = value;
return this;
}
public ServerMetricsBuilder setReplicationLoadSink(ReplicationLoadSink value) {
this.sink = value;
return this;
}
public ServerMetricsBuilder setRegionMetrics(List<RegionMetrics> value) {
value.forEach(v -> this.regionStatus.put(v.getRegionName(), v));
return this;
}
public ServerMetricsBuilder setUserMetrics(List<UserMetrics> value) {
value.forEach(v -> this.userMetrics.put(v.getUserName(), v));
return this;
}
public ServerMetricsBuilder setCoprocessorNames(List<String> value) {
coprocessorNames.addAll(value);
return this;
}
public ServerMetricsBuilder setReportTimestamp(long value) {
this.reportTimestamp = value;
return this;
}
public ServerMetricsBuilder setLastReportTimestamp(long value) {
this.lastReportTimestamp = value;
return this;
}
public ServerMetrics build() {
return new ServerMetricsImpl(
serverName,
versionNumber,
version,
requestCountPerSecond,
requestCount,
usedHeapSize,
maxHeapSize,
infoServerPort,
sources,
sink,
regionStatus,
coprocessorNames,
reportTimestamp,
lastReportTimestamp,
userMetrics);
}
private static class ServerMetricsImpl implements ServerMetrics {
private final ServerName serverName;
private final int versionNumber;
private final String version;
private final long requestCountPerSecond;
private final long requestCount;
private final Size usedHeapSize;
private final Size maxHeapSize;
private final int infoServerPort;
private final List<ReplicationLoadSource> sources;
@Nullable
private final ReplicationLoadSink sink;
private final Map<byte[], RegionMetrics> regionStatus;
private final Set<String> coprocessorNames;
private final long reportTimestamp;
private final long lastReportTimestamp;
private final Map<byte[], UserMetrics> userMetrics;
ServerMetricsImpl(ServerName serverName, int versionNumber, String version,
long requestCountPerSecond, long requestCount, Size usedHeapSize, Size maxHeapSize,
int infoServerPort, List<ReplicationLoadSource> sources, ReplicationLoadSink sink,
Map<byte[], RegionMetrics> regionStatus, Set<String> coprocessorNames, long reportTimestamp,
long lastReportTimestamp, Map<byte[], UserMetrics> userMetrics) {
this.serverName = Preconditions.checkNotNull(serverName);
this.versionNumber = versionNumber;
this.version = version;
this.requestCountPerSecond = requestCountPerSecond;
this.requestCount = requestCount;
this.usedHeapSize = Preconditions.checkNotNull(usedHeapSize);
this.maxHeapSize = Preconditions.checkNotNull(maxHeapSize);
this.infoServerPort = infoServerPort;
this.sources = Preconditions.checkNotNull(sources);
this.sink = sink;
this.regionStatus = Preconditions.checkNotNull(regionStatus);
this.userMetrics = Preconditions.checkNotNull(userMetrics);
this.coprocessorNames =Preconditions.checkNotNull(coprocessorNames);
this.reportTimestamp = reportTimestamp;
this.lastReportTimestamp = lastReportTimestamp;
}
@Override
public ServerName getServerName() {
return serverName;
}
@Override
public int getVersionNumber() {
return versionNumber;
}
public String getVersion() {
return version;
}
@Override
public long getRequestCountPerSecond() {
return requestCountPerSecond;
}
@Override
public long getRequestCount() {
return requestCount;
}
@Override
public Size getUsedHeapSize() {
return usedHeapSize;
}
@Override
public Size getMaxHeapSize() {
return maxHeapSize;
}
@Override
public int getInfoServerPort() {
return infoServerPort;
}
@Override
public List<ReplicationLoadSource> getReplicationLoadSourceList() {
return Collections.unmodifiableList(sources);
}
@Override
public Map<String, List<ReplicationLoadSource>> getReplicationLoadSourceMap(){
Map<String,List<ReplicationLoadSource>> sourcesMap = new HashMap<>();
for(ReplicationLoadSource loadSource : sources){
sourcesMap.computeIfAbsent(loadSource.getPeerID(),
peerId -> new ArrayList()).add(loadSource);
}
return sourcesMap;
}
@Override
public ReplicationLoadSink getReplicationLoadSink() {
return sink;
}
@Override
public Map<byte[], RegionMetrics> getRegionMetrics() {
return Collections.unmodifiableMap(regionStatus);
}
@Override
public Map<byte[], UserMetrics> getUserMetrics() {
return Collections.unmodifiableMap(userMetrics);
}
@Override
public Set<String> getCoprocessorNames() {
return Collections.unmodifiableSet(coprocessorNames);
}
@Override
public long getReportTimestamp() {
return reportTimestamp;
}
@Override
public long getLastReportTimestamp() {
return lastReportTimestamp;
}
@Override
public String toString() {
int storeCount = 0;
int storeFileCount = 0;
int storeRefCount = 0;
int maxCompactedStoreFileRefCount = 0;
long uncompressedStoreFileSizeMB = 0;
long storeFileSizeMB = 0;
long memStoreSizeMB = 0;
long storefileIndexSizeKB = 0;
long rootLevelIndexSizeKB = 0;
long readRequestsCount = 0;
long cpRequestsCount = 0;
long writeRequestsCount = 0;
long filteredReadRequestsCount = 0;
long bloomFilterSizeMB = 0;
long compactingCellCount = 0;
long compactedCellCount = 0;
for (RegionMetrics r : getRegionMetrics().values()) {
storeCount += r.getStoreCount();
storeFileCount += r.getStoreFileCount();
storeRefCount += r.getStoreRefCount();
int currentMaxCompactedStoreFileRefCount = r.getMaxCompactedStoreFileRefCount();
maxCompactedStoreFileRefCount = Math.max(maxCompactedStoreFileRefCount,
currentMaxCompactedStoreFileRefCount);
uncompressedStoreFileSizeMB += r.getUncompressedStoreFileSize().get(Size.Unit.MEGABYTE);
storeFileSizeMB += r.getStoreFileSize().get(Size.Unit.MEGABYTE);
memStoreSizeMB += r.getMemStoreSize().get(Size.Unit.MEGABYTE);
storefileIndexSizeKB += r.getStoreFileUncompressedDataIndexSize().get(Size.Unit.KILOBYTE);
readRequestsCount += r.getReadRequestCount();
cpRequestsCount += r.getCpRequestCount();
writeRequestsCount += r.getWriteRequestCount();
filteredReadRequestsCount += r.getFilteredReadRequestCount();
rootLevelIndexSizeKB += r.getStoreFileRootLevelIndexSize().get(Size.Unit.KILOBYTE);
bloomFilterSizeMB += r.getBloomFilterSize().get(Size.Unit.MEGABYTE);
compactedCellCount += r.getCompactedCellCount();
compactingCellCount += r.getCompactingCellCount();
}
StringBuilder sb = Strings.appendKeyValue(new StringBuilder(), "requestsPerSecond",
Double.valueOf(getRequestCountPerSecond()));
Strings.appendKeyValue(sb, "numberOfOnlineRegions",
Integer.valueOf(getRegionMetrics().size()));
Strings.appendKeyValue(sb, "usedHeapMB", getUsedHeapSize());
Strings.appendKeyValue(sb, "maxHeapMB", getMaxHeapSize());
Strings.appendKeyValue(sb, "numberOfStores", storeCount);
Strings.appendKeyValue(sb, "numberOfStorefiles", storeFileCount);
Strings.appendKeyValue(sb, "storeRefCount", storeRefCount);
Strings.appendKeyValue(sb, "maxCompactedStoreFileRefCount",
maxCompactedStoreFileRefCount);
Strings.appendKeyValue(sb, "storefileUncompressedSizeMB", uncompressedStoreFileSizeMB);
Strings.appendKeyValue(sb, "storefileSizeMB", storeFileSizeMB);
if (uncompressedStoreFileSizeMB != 0) {
Strings.appendKeyValue(sb, "compressionRatio", String.format("%.4f",
(float) storeFileSizeMB / (float) uncompressedStoreFileSizeMB));
}
Strings.appendKeyValue(sb, "memstoreSizeMB", memStoreSizeMB);
Strings.appendKeyValue(sb, "readRequestsCount", readRequestsCount);
Strings.appendKeyValue(sb, "cpRequestsCount", cpRequestsCount);
Strings.appendKeyValue(sb, "filteredReadRequestsCount", filteredReadRequestsCount);
Strings.appendKeyValue(sb, "writeRequestsCount", writeRequestsCount);
Strings.appendKeyValue(sb, "rootIndexSizeKB", rootLevelIndexSizeKB);
Strings.appendKeyValue(sb, "totalStaticIndexSizeKB", storefileIndexSizeKB);
Strings.appendKeyValue(sb, "totalStaticBloomSizeKB", bloomFilterSizeMB);
Strings.appendKeyValue(sb, "totalCompactingKVs", compactingCellCount);
Strings.appendKeyValue(sb, "currentCompactedKVs", compactedCellCount);
float compactionProgressPct = Float.NaN;
if (compactingCellCount > 0) {
compactionProgressPct =
Float.valueOf((float) compactedCellCount / compactingCellCount);
}
Strings.appendKeyValue(sb, "compactionProgressPct", compactionProgressPct);
Strings.appendKeyValue(sb, "coprocessors", getCoprocessorNames());
return sb.toString();
}
}
}