blob: 7c920dad66313a15dea1f66192e1784b13ed0625 [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.ignite.internal.processors.cache.persistence;
import java.util.Collection;
import org.apache.ignite.DataRegionMetrics;
import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager;
import org.apache.ignite.internal.processors.metric.GridMetricManager;
import org.apache.ignite.internal.processors.metric.MetricRegistry;
import org.apache.ignite.internal.processors.metric.impl.AtomicLongMetric;
import org.apache.ignite.internal.processors.metric.impl.HitRateMetric;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteOutClosure;
import org.apache.ignite.mxbean.DataStorageMetricsMXBean;
/**
*
*/
public class DataStorageMetricsImpl implements DataStorageMetricsMXBean {
/** Prefix for all data storage metrics. */
public static final String DATASTORAGE_METRIC_PREFIX = "io.datastorage";
/** */
private final HitRateMetric walLoggingRate;
/** */
private final HitRateMetric walWritingRate;
/** */
private final HitRateMetric walFsyncTimeDuration;
/** */
private final HitRateMetric walFsyncTimeNum;
/** */
private final HitRateMetric walBuffPollSpinsNum;
/** */
private final AtomicLongMetric lastCpLockWaitDuration;
/** */
private final AtomicLongMetric lastCpMarkDuration;
/** */
private final AtomicLongMetric lastCpPagesWriteDuration;
/** */
private final AtomicLongMetric lastCpDuration;
/** */
private final AtomicLongMetric lastCpFsyncDuration;
/** */
private final AtomicLongMetric lastCpTotalPages;
/** */
private final AtomicLongMetric lastCpDataPages;
/** */
private final AtomicLongMetric lastCpCowPages;
/** */
private volatile long rateTimeInterval;
/** */
private volatile int subInts;
/** */
private volatile boolean metricsEnabled;
/** */
private volatile IgniteWriteAheadLogManager wal;
/** */
private volatile IgniteOutClosure<Long> walSizeProvider;
/** */
private final AtomicLongMetric lastWalSegmentRollOverTime;
/** */
private final AtomicLongMetric totalCheckpointTime;
/** */
private volatile Collection<DataRegionMetrics> regionMetrics;
/** */
private final AtomicLongMetric storageSize;
/** */
private final AtomicLongMetric sparseStorageSize;
/**
* @param mmgr Metrics manager.
* @param metricsEnabled Metrics enabled flag.
* @param rateTimeInterval Rate time interval.
* @param subInts Number of sub-intervals.
*/
public DataStorageMetricsImpl(
GridMetricManager mmgr,
boolean metricsEnabled,
long rateTimeInterval,
int subInts
) {
this.metricsEnabled = metricsEnabled;
this.rateTimeInterval = rateTimeInterval;
this.subInts = subInts;
MetricRegistry mreg = mmgr.registry(DATASTORAGE_METRIC_PREFIX);
walLoggingRate = mreg.hitRateMetric("WalLoggingRate",
"Average number of WAL records per second written during the last time interval.",
rateTimeInterval,
subInts);
walWritingRate = mreg.hitRateMetric(
"WalWritingRate",
"Average number of bytes per second written during the last time interval.",
rateTimeInterval,
subInts);
walFsyncTimeDuration = mreg.hitRateMetric(
"WalFsyncTimeDuration",
"Total duration of fsync",
rateTimeInterval,
subInts);
walFsyncTimeNum = mreg.hitRateMetric(
"WalFsyncTimeNum",
"Total count of fsync",
rateTimeInterval,
subInts);
walBuffPollSpinsNum = mreg.hitRateMetric(
"WalBuffPollSpinsRate",
"WAL buffer poll spins number over the last time interval.",
rateTimeInterval,
subInts);
lastCpLockWaitDuration = mreg.longMetric("LastCheckpointLockWaitDuration",
"Duration of the checkpoint lock wait in milliseconds.");
lastCpMarkDuration = mreg.longMetric("LastCheckpointMarkDuration",
"Duration of the checkpoint lock wait in milliseconds.");
lastCpPagesWriteDuration = mreg.longMetric("LastCheckpointPagesWriteDuration",
"Duration of the checkpoint pages write in milliseconds.");
lastCpDuration = mreg.longMetric("LastCheckpointDuration",
"Duration of the last checkpoint in milliseconds.");
lastCpFsyncDuration = mreg.longMetric("LastCheckpointFsyncDuration",
"Duration of the sync phase of the last checkpoint in milliseconds.");
lastCpTotalPages = mreg.longMetric("LastCheckpointTotalPagesNumber",
"Total number of pages written during the last checkpoint.");
lastCpDataPages = mreg.longMetric("LastCheckpointDataPagesNumber",
"Total number of data pages written during the last checkpoint.");
lastCpCowPages = mreg.longMetric("LastCheckpointCopiedOnWritePagesNumber",
"Number of pages copied to a temporary checkpoint buffer during the last checkpoint.");
lastWalSegmentRollOverTime = mreg.longMetric("WalLastRollOverTime",
"Time of the last WAL segment rollover.");
totalCheckpointTime = mreg.longMetric("CheckpointTotalTime",
"Total duration of checkpoint");
storageSize = mreg.longMetric("StorageSize",
"Storage space allocated, in bytes.");
sparseStorageSize = mreg.longMetric("SparseStorageSize",
"Storage space allocated adjusted for possible sparsity, in bytes.");
mreg.register("WalArchiveSegments",
this::getWalArchiveSegments,
"Current number of WAL segments in the WAL archive.");
mreg.register("WalTotalSize",
this::getWalTotalSize,
"Total size in bytes for storage wal files.");
}
/** {@inheritDoc} */
@Override public float getWalLoggingRate() {
if (!metricsEnabled)
return 0;
return ((float)walLoggingRate.value() * 1000) / rateTimeInterval;
}
/** {@inheritDoc} */
@Override public float getWalWritingRate() {
if (!metricsEnabled)
return 0;
return ((float)walWritingRate.value() * 1000) / rateTimeInterval;
}
/** {@inheritDoc} */
@Override public int getWalArchiveSegments() {
if (!metricsEnabled)
return 0;
return wal.walArchiveSegments();
}
/** {@inheritDoc} */
@Override public float getWalFsyncTimeAverage() {
if (!metricsEnabled)
return 0;
long numRate = walFsyncTimeNum.value();
if (numRate == 0)
return 0;
return (float)walFsyncTimeDuration.value() / numRate;
}
/** {@inheritDoc} */
@Override public long getWalBuffPollSpinsRate() {
if (!metricsEnabled)
return 0;
return walBuffPollSpinsNum.value();
}
/** {@inheritDoc} */
@Override public long getLastCheckpointDuration() {
if (!metricsEnabled)
return 0;
return lastCpDuration.value();
}
/** {@inheritDoc} */
@Override public long getLastCheckpointLockWaitDuration() {
if (!metricsEnabled)
return 0;
return lastCpLockWaitDuration.value();
}
/** {@inheritDoc} */
@Override public long getLastCheckpointMarkDuration() {
if (!metricsEnabled)
return 0;
return lastCpMarkDuration.value();
}
/** {@inheritDoc} */
@Override public long getLastCheckpointPagesWriteDuration() {
if (!metricsEnabled)
return 0;
return lastCpPagesWriteDuration.value();
}
/** {@inheritDoc} */
@Override public long getLastCheckpointFsyncDuration() {
if (!metricsEnabled)
return 0;
return lastCpFsyncDuration.value();
}
/** {@inheritDoc} */
@Override public long getLastCheckpointTotalPagesNumber() {
if (!metricsEnabled)
return 0;
return lastCpTotalPages.value();
}
/** {@inheritDoc} */
@Override public long getLastCheckpointDataPagesNumber() {
if (!metricsEnabled)
return 0;
return lastCpDataPages.value();
}
/** {@inheritDoc} */
@Override public long getLastCheckpointCopiedOnWritePagesNumber() {
if (!metricsEnabled)
return 0;
return lastCpCowPages.value();
}
/** {@inheritDoc} */
@Override public void enableMetrics() {
metricsEnabled = true;
}
/** {@inheritDoc} */
@Override public void disableMetrics() {
metricsEnabled = false;
}
/** {@inheritDoc} */
@Override public void rateTimeInterval(long rateTimeInterval) {
this.rateTimeInterval = rateTimeInterval;
resetRates();
}
/** {@inheritDoc} */
@Override public void subIntervals(int subInts) {
this.subInts = subInts;
resetRates();
}
/** {@inheritDoc} */
@Override public long getWalTotalSize() {
if (!metricsEnabled)
return 0;
IgniteOutClosure<Long> walSize = this.walSizeProvider;
return walSize != null ? walSize.apply() : 0;
}
/** {@inheritDoc} */
@Override public long getWalLastRollOverTime() {
if (!metricsEnabled)
return 0;
return lastWalSegmentRollOverTime.value();
}
/** {@inheritDoc} */
@Override public long getCheckpointTotalTime() {
if (!metricsEnabled)
return 0;
return totalCheckpointTime.value();
}
/** {@inheritDoc} */
@Override public long getDirtyPages() {
if (!metricsEnabled)
return 0;
Collection<DataRegionMetrics> regionMetrics0 = regionMetrics;
if (F.isEmpty(regionMetrics0))
return 0;
long dirtyPages = 0L;
for (DataRegionMetrics rm : regionMetrics0)
dirtyPages += rm.getDirtyPages();
return dirtyPages;
}
/** {@inheritDoc} */
@Override public long getPagesRead() {
if (!metricsEnabled)
return 0;
Collection<DataRegionMetrics> regionMetrics0 = regionMetrics;
if (F.isEmpty(regionMetrics0))
return 0;
long readPages = 0L;
for (DataRegionMetrics rm : regionMetrics0)
readPages += rm.getPagesRead();
return readPages;
}
/** {@inheritDoc} */
@Override public long getPagesWritten() {
if (!metricsEnabled)
return 0;
Collection<DataRegionMetrics> regionMetrics0 = regionMetrics;
if (F.isEmpty(regionMetrics0))
return 0;
long writtenPages = 0L;
for (DataRegionMetrics rm : regionMetrics0)
writtenPages += rm.getPagesWritten();
return writtenPages;
}
/** {@inheritDoc} */
@Override public long getPagesReplaced() {
if (!metricsEnabled)
return 0;
Collection<DataRegionMetrics> regionMetrics0 = regionMetrics;
if (F.isEmpty(regionMetrics0))
return 0;
long replacedPages = 0L;
for (DataRegionMetrics rm : regionMetrics0)
replacedPages += rm.getPagesReplaced();
return replacedPages;
}
/** {@inheritDoc} */
@Override public long getOffHeapSize() {
if (!metricsEnabled)
return 0;
Collection<DataRegionMetrics> regionMetrics0 = regionMetrics;
if (F.isEmpty(regionMetrics0))
return 0;
long offHeapSize = 0L;
for (DataRegionMetrics rm : regionMetrics0)
offHeapSize += rm.getOffHeapSize();
return offHeapSize;
}
/** {@inheritDoc} */
@Override public long getOffheapUsedSize() {
if (!metricsEnabled)
return 0;
Collection<DataRegionMetrics> regionMetrics0 = regionMetrics;
if (F.isEmpty(regionMetrics0))
return 0;
long offHeapUsedSize = 0L;
for (DataRegionMetrics rm : regionMetrics0)
offHeapUsedSize += rm.getOffheapUsedSize();
return offHeapUsedSize;
}
/** {@inheritDoc} */
@Override public long getTotalAllocatedSize() {
if (!metricsEnabled)
return 0;
Collection<DataRegionMetrics> regionMetrics0 = regionMetrics;
if (F.isEmpty(regionMetrics0))
return 0;
long totalAllocatedSize = 0L;
for (DataRegionMetrics rm : regionMetrics0)
totalAllocatedSize += rm.getTotalAllocatedSize();
return totalAllocatedSize;
}
/** {@inheritDoc} */
@Override public long getUsedCheckpointBufferPages() {
if (!metricsEnabled)
return 0;
Collection<DataRegionMetrics> regionMetrics0 = regionMetrics;
if (F.isEmpty(regionMetrics0))
return 0;
long usedCheckpointBufferPages = 0L;
for (DataRegionMetrics rm : regionMetrics0)
usedCheckpointBufferPages += rm.getUsedCheckpointBufferPages();
return usedCheckpointBufferPages;
}
/** {@inheritDoc} */
@Override public long getUsedCheckpointBufferSize() {
if (!metricsEnabled)
return 0;
Collection<DataRegionMetrics> regionMetrics0 = regionMetrics;
if (F.isEmpty(regionMetrics0))
return 0;
long usedCheckpointBufferSize = 0L;
for (DataRegionMetrics rm : regionMetrics0)
usedCheckpointBufferSize += rm.getUsedCheckpointBufferSize();
return usedCheckpointBufferSize;
}
/** {@inheritDoc} */
@Override public long getCheckpointBufferSize() {
if (!metricsEnabled)
return 0;
Collection<DataRegionMetrics> regionMetrics0 = regionMetrics;
if (F.isEmpty(regionMetrics0))
return 0;
long checkpointBufferSize = 0L;
for (DataRegionMetrics rm : regionMetrics0)
checkpointBufferSize += rm.getCheckpointBufferSize();
return checkpointBufferSize;
}
/**
* @param wal Write-ahead log manager.
*/
public void wal(IgniteWriteAheadLogManager wal) {
this.wal = wal;
}
/**
* @param walSizeProvider Wal size provider.
*/
public void setWalSizeProvider(IgniteOutClosure<Long> walSizeProvider) {
this.walSizeProvider = walSizeProvider;
}
/**
*
*/
public void onWallRollOver() {
this.lastWalSegmentRollOverTime.value(U.currentTimeMillis());
}
/**
*
*/
public void regionMetrics(Collection<DataRegionMetrics> regionMetrics) {
this.regionMetrics = regionMetrics;
}
/**
* @return Metrics enabled flag.
*/
public boolean metricsEnabled() {
return metricsEnabled;
}
/** {@inheritDoc} */
@Override public long getStorageSize() {
return storageSize.value();
}
/** {@inheritDoc} */
@Override public long getSparseStorageSize() {
return sparseStorageSize.value();
}
/**
* @param lockWaitDuration Lock wait duration.
* @param markDuration Mark duration.
* @param pagesWriteDuration Pages write duration.
* @param fsyncDuration Total checkpoint fsync duration.
* @param duration Total checkpoint duration.
* @param totalPages Total number of all pages in checkpoint.
* @param dataPages Total number of data pages in checkpoint.
* @param cowPages Total number of COW-ed pages in checkpoint.
*/
public void onCheckpoint(
long lockWaitDuration,
long markDuration,
long pagesWriteDuration,
long fsyncDuration,
long duration,
long totalPages,
long dataPages,
long cowPages,
long storageSize,
long sparseStorageSize
) {
if (metricsEnabled) {
lastCpLockWaitDuration.value(lockWaitDuration);
lastCpMarkDuration.value(markDuration);
lastCpPagesWriteDuration.value(pagesWriteDuration);
lastCpFsyncDuration.value(fsyncDuration);
lastCpDuration.value(duration);
lastCpTotalPages.value(totalPages);
lastCpDataPages.value(dataPages);
lastCpCowPages.value(cowPages);
this.storageSize.value(storageSize);
this.sparseStorageSize.value(sparseStorageSize);
totalCheckpointTime.add(duration);
}
}
/**
*
*/
public void onWalRecordLogged() {
walLoggingRate.increment();
}
/**
* @param size Size written.
*/
public void onWalBytesWritten(int size) {
walWritingRate.add(size);
}
/**
* @param nanoTime Fsync nano time.
*/
public void onFsync(long nanoTime) {
long microseconds = nanoTime / 1_000;
walFsyncTimeDuration.add(microseconds);
walFsyncTimeNum.increment();
}
/**
* @param num Number.
*/
public void onBuffPollSpin(int num) {
walBuffPollSpinsNum.add(num);
}
/**
*
*/
private void resetRates() {
walLoggingRate.reset(rateTimeInterval, subInts);
walWritingRate.reset(rateTimeInterval, subInts);
walBuffPollSpinsNum.reset(rateTimeInterval, subInts);
walFsyncTimeDuration.reset(rateTimeInterval, subInts);
walFsyncTimeNum.reset(rateTimeInterval, subInts);
}
}