blob: e4d8707b86523239d39065fd278024d946a77759 [file] [log] [blame]
/**
* 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.hdfs.server.datanode.fsdataset;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdfs.DFSConfigKeys;
import org.apache.hadoop.metrics2.MetricsSystem;
import org.apache.hadoop.metrics2.annotation.Metric;
import org.apache.hadoop.metrics2.annotation.Metrics;
import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
import org.apache.hadoop.metrics2.lib.MetricsRegistry;
import org.apache.hadoop.metrics2.lib.MutableCounterLong;
import org.apache.hadoop.metrics2.lib.MutableQuantiles;
import org.apache.hadoop.metrics2.lib.MutableRate;
import java.util.concurrent.ThreadLocalRandom;
/**
* This class is for maintaining Datanode Volume IO related statistics and
* publishing them through the metrics interfaces.
*/
@InterfaceAudience.Private
@InterfaceStability.Evolving
@Metrics(name = "DataNodeVolume", about = "DataNode Volume metrics",
context = "dfs")
public class DataNodeVolumeMetrics {
private final MetricsRegistry registry = new MetricsRegistry("FsVolume");
@Metric("number of metadata operations")
private MutableCounterLong totalMetadataOperations;
@Metric("metadata operation rate")
private MutableRate metadataOperationRate;
private MutableQuantiles[] metadataOperationLatencyQuantiles;
@Metric("number of data file io operations")
private MutableCounterLong totalDataFileIos;
@Metric("data file io operation rate")
private MutableRate dataFileIoRate;
private MutableQuantiles[] dataFileIoLatencyQuantiles;
@Metric("file io flush rate")
private MutableRate flushIoRate;
private MutableQuantiles[] flushIoLatencyQuantiles;
@Metric("file io sync rate")
private MutableRate syncIoRate;
private MutableQuantiles[] syncIoLatencyQuantiles;
@Metric("file io read rate")
private MutableRate readIoRate;
private MutableQuantiles[] readIoLatencyQuantiles;
@Metric("file io write rate")
private MutableRate writeIoRate;
private MutableQuantiles[] writeIoLatencyQuantiles;
@Metric("number of file io errors")
private MutableCounterLong totalFileIoErrors;
@Metric("file io error rate")
private MutableRate fileIoErrorRate;
public long getTotalMetadataOperations() {
return totalMetadataOperations.value();
}
// Based on metadataOperationRate
public long getMetadataOperationSampleCount() {
return metadataOperationRate.lastStat().numSamples();
}
public double getMetadataOperationMean() {
return metadataOperationRate.lastStat().mean();
}
public double getMetadataOperationStdDev() {
return metadataOperationRate.lastStat().stddev();
}
public long getTotalDataFileIos() {
return totalDataFileIos.value();
}
// Based on dataFileIoRate
public long getDataFileIoSampleCount() {
return dataFileIoRate.lastStat().numSamples();
}
public double getDataFileIoMean() {
return dataFileIoRate.lastStat().mean();
}
public double getDataFileIoStdDev() {
return dataFileIoRate.lastStat().stddev();
}
// Based on flushIoRate
public long getFlushIoSampleCount() {
return flushIoRate.lastStat().numSamples();
}
public double getFlushIoMean() {
return flushIoRate.lastStat().mean();
}
public double getFlushIoStdDev() {
return flushIoRate.lastStat().stddev();
}
// Based on syncIoRate
public long getSyncIoSampleCount() {
return syncIoRate.lastStat().numSamples();
}
public double getSyncIoMean() {
return syncIoRate.lastStat().mean();
}
public double getSyncIoStdDev() {
return syncIoRate.lastStat().stddev();
}
// Based on readIoRate
public long getReadIoSampleCount() {
return readIoRate.lastStat().numSamples();
}
public double getReadIoMean() {
return readIoRate.lastStat().mean();
}
public double getReadIoStdDev() {
return readIoRate.lastStat().stddev();
}
// Based on writeIoRate
public long getWriteIoSampleCount() {
return syncIoRate.lastStat().numSamples();
}
public double getWriteIoMean() {
return syncIoRate.lastStat().mean();
}
public double getWriteIoStdDev() {
return syncIoRate.lastStat().stddev();
}
public long getTotalFileIoErrors() {
return totalFileIoErrors.value();
}
// Based on fileIoErrorRate
public long getFileIoErrorSampleCount() {
return fileIoErrorRate.lastStat().numSamples();
}
public double getFileIoErrorMean() {
return fileIoErrorRate.lastStat().mean();
}
public double getFileIoErrorStdDev() {
return fileIoErrorRate.lastStat().stddev();
}
private final String name;
private final MetricsSystem ms;
public DataNodeVolumeMetrics(final MetricsSystem metricsSystem,
final String volumeName, final int[] intervals) {
this.ms = metricsSystem;
this.name = volumeName;
final int len = intervals.length;
metadataOperationLatencyQuantiles = new MutableQuantiles[len];
dataFileIoLatencyQuantiles = new MutableQuantiles[len];
flushIoLatencyQuantiles = new MutableQuantiles[len];
syncIoLatencyQuantiles = new MutableQuantiles[len];
readIoLatencyQuantiles = new MutableQuantiles[len];
writeIoLatencyQuantiles = new MutableQuantiles[len];
for (int i = 0; i < len; i++) {
int interval = intervals[i];
metadataOperationLatencyQuantiles[i] = registry.newQuantiles(
"metadataOperationLatency" + interval + "s",
"Meatadata Operation Latency in ms", "ops", "latency", interval);
dataFileIoLatencyQuantiles[i] = registry.newQuantiles(
"dataFileIoLatency" + interval + "s",
"Data File Io Latency in ms", "ops", "latency", interval);
flushIoLatencyQuantiles[i] = registry.newQuantiles(
"flushIoLatency" + interval + "s",
"Data flush Io Latency in ms", "ops", "latency", interval);
syncIoLatencyQuantiles[i] = registry.newQuantiles(
"syncIoLatency" + interval + "s",
"Data sync Io Latency in ms", "ops", "latency", interval);
readIoLatencyQuantiles[i] = registry.newQuantiles(
"readIoLatency" + interval + "s",
"Data read Io Latency in ms", "ops", "latency", interval);
writeIoLatencyQuantiles[i] = registry.newQuantiles(
"writeIoLatency" + interval + "s",
"Data write Io Latency in ms", "ops", "latency", interval);
}
}
public static DataNodeVolumeMetrics create(final Configuration conf,
final String volumeName) {
MetricsSystem ms = DefaultMetricsSystem.instance();
String name = "DataNodeVolume-"+ (volumeName.isEmpty()
? "UndefinedDataNodeVolume"+ ThreadLocalRandom.current().nextInt()
: volumeName.replace(':', '-'));
// Percentile measurement is off by default, by watching no intervals
int[] intervals =
conf.getInts(DFSConfigKeys.DFS_METRICS_PERCENTILES_INTERVALS_KEY);
return ms.register(name, null, new DataNodeVolumeMetrics(ms, name,
intervals));
}
public String name() {
return name;
}
public void unRegister() {
ms.unregisterSource(name);
}
public void addMetadastaOperationLatency(final long latency) {
totalMetadataOperations.incr();
metadataOperationRate.add(latency);
for (MutableQuantiles q : metadataOperationLatencyQuantiles) {
q.add(latency);
}
}
public void addDataFileIoLatency(final long latency) {
totalDataFileIos.incr();
dataFileIoRate.add(latency);
for (MutableQuantiles q : dataFileIoLatencyQuantiles) {
q.add(latency);
}
}
public void addSyncIoLatency(final long latency) {
syncIoRate.add(latency);
for (MutableQuantiles q : syncIoLatencyQuantiles) {
q.add(latency);
}
}
public void addFlushIoLatency(final long latency) {
flushIoRate.add(latency);
for (MutableQuantiles q : flushIoLatencyQuantiles) {
q.add(latency);
}
}
public void addReadIoLatency(final long latency) {
readIoRate.add(latency);
for (MutableQuantiles q : readIoLatencyQuantiles) {
q.add(latency);
}
}
public void addWriteIoLatency(final long latency) {
writeIoRate.add(latency);
for (MutableQuantiles q: writeIoLatencyQuantiles) {
q.add(latency);
}
}
public void addFileIoError(final long latency) {
totalFileIoErrors.incr();
metadataOperationRate.add(latency);
}
}