You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ib...@apache.org on 2022/09/26 13:49:02 UTC
[ignite] branch master updated: IGNITE-17728 Improve size-related metrics (#10259)
This is an automated email from the ASF dual-hosted git repository.
ibessonov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new d6159f57b60 IGNITE-17728 Improve size-related metrics (#10259)
d6159f57b60 is described below
commit d6159f57b60c340f1053077e5b2bbbe439b688c7
Author: Alexander Polovtcev <al...@gmail.com>
AuthorDate: Mon Sep 26 16:48:45 2022 +0300
IGNITE-17728 Improve size-related metrics (#10259)
---
.../java/org/apache/ignite/DataRegionMetrics.java | 23 +++++---
.../cache/persistence/DataRegionMetricsImpl.java | 61 +++++++++++++++----
.../persistence/DataRegionMetricsMXBeanImpl.java | 9 ++-
.../persistence/DataRegionMetricsSnapshot.java | 59 +++++++++++--------
.../cache/persistence/pagemem/PageMetricsImpl.java | 1 -
.../persistence/pagemem/FillFactorMetricTest.java | 68 ++++++++++------------
.../Cache/DataRegionMetricsTest.cs | 2 +-
7 files changed, 139 insertions(+), 84 deletions(-)
diff --git a/modules/core/src/main/java/org/apache/ignite/DataRegionMetrics.java b/modules/core/src/main/java/org/apache/ignite/DataRegionMetrics.java
index 58fd5360643..7d6f3c48974 100644
--- a/modules/core/src/main/java/org/apache/ignite/DataRegionMetrics.java
+++ b/modules/core/src/main/java/org/apache/ignite/DataRegionMetrics.java
@@ -75,6 +75,15 @@ public interface DataRegionMetrics {
*/
public long getTotalAllocatedPages();
+ /**
+ * Gets a total size of memory allocated in the data region. When persistence is disabled, this
+ * metric shows the total size of pages in memory. When persistence is enabled, this metric shows the
+ * total size of pages in memory and on disk.
+ *
+ * @return Total size of memory allocated, in bytes.
+ */
+ public long getTotalAllocatedSize();
+
/**
* Gets a total number of pages used for storing the data. It includes allocated pages except of empty
* pages that are not used yet or pages that can be reused.
@@ -88,13 +97,13 @@ public interface DataRegionMetrics {
public long getTotalUsedPages();
/**
- * Gets a total size of memory allocated in the data region. When persistence is disabled, this
- * metric shows the total size of pages in memory. When persistence is enabled, this metric shows the
- * total size of pages in memory and on disk.
+ * Returns the total amount of bytes occupied by the non-empty pages. This value is directly tied to the
+ * {@link #getTotalUsedPages} and does not take page fragmentation into account (i.e. if some data is removed from
+ * a page, but it is not completely empty, it will still show the whole page bytes as being occupied).
*
- * @return Total size of memory allocated, in bytes.
+ * @return Total amount of bytes occupied by the non-empty pages
*/
- public long getTotalAllocatedSize();
+ public long getTotalUsedSize();
/**
* Gets pages allocation rate of a memory region.
@@ -119,9 +128,9 @@ public interface DataRegionMetrics {
public float getLargeEntriesPagesPercentage();
/**
- * Gets the percentage of the used space.
+ * Returns the ratio of space occupied by user and system data to the whole allocated space.
*
- * @return The percentage of the used space.
+ * @return Ratio of space occupied by user and system data to the whole allocated space.
*/
public float getPagesFillFactor();
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java
index 188ed968874..18e70b72c24 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java
@@ -168,6 +168,7 @@ public class DataRegionMetricsImpl implements DataRegionMetrics {
private volatile long rateTimeInterval;
/** Histogram of cold/hot pages. */
+ @Nullable
private final PeriodicHistogramMetricImpl pageTsHistogram;
/**
@@ -316,14 +317,19 @@ public class DataRegionMetricsImpl implements DataRegionMetrics {
return dataRegionPageMetrics.totalPages().value();
}
+ /** {@inheritDoc} */
+ @Override public long getTotalAllocatedSize() {
+ return getTotalAllocatedPages() * pageMem.systemPageSize();
+ }
+
/** {@inheritDoc} */
@Override public long getTotalUsedPages() {
return getTotalAllocatedPages() - dataRegionMetricsProvider.emptyDataPages();
}
/** {@inheritDoc} */
- @Override public long getTotalAllocatedSize() {
- return getTotalAllocatedPages() * (persistenceEnabled ? pageMem.pageSize() : pageMem.systemPageSize());
+ @Override public long getTotalUsedSize() {
+ return getTotalUsedPages() * pageMem.systemPageSize();
}
/** {@inheritDoc} */
@@ -356,11 +362,29 @@ public class DataRegionMetricsImpl implements DataRegionMetrics {
if (!metricsEnabled)
return 0;
- long freeSpace = dataRegionMetricsProvider.partiallyFilledPagesFreeSpace();
+ long totalSpace = getTotalAllocatedSize();
+
+ if (totalSpace == 0)
+ return 0;
+
+ return (float)getSizeUsedByData() / totalSpace;
+ }
+
+ /**
+ * Calculates the number of bytes, occupied by data. Unlike {@link #getTotalUsedSize} it also takes into account the
+ * empty space in non-empty pages.
+ */
+ private long getSizeUsedByData() {
+ // Total amount of bytes occupied by all pages.
+ long totalSpace = getTotalAllocatedSize();
+
+ // Amount of free bytes in fragmented data pages.
+ long partiallyFreeSpace = dataRegionMetricsProvider.partiallyFilledPagesFreeSpace();
- long totalAllocated = getPageSize() * getTotalAllocatedPages();
+ // Amount of bytes in empty data pages.
+ long emptySpace = dataRegionMetricsProvider.emptyDataPages() * pageMem.systemPageSize();
- return totalAllocated != 0 ? (float)(totalAllocated - freeSpace) / totalAllocated : 0f;
+ return totalSpace - partiallyFreeSpace - emptySpace;
}
/** {@inheritDoc} */
@@ -555,14 +579,14 @@ public class DataRegionMetricsImpl implements DataRegionMetrics {
return pageMetrics;
synchronized (cacheGrpMetricsLock) {
- IntMap<PageMetrics> localCacheGrpMetrics = cacheGrpMetrics;
+ IntMap<PageMetrics> locCacheGrpMetrics = cacheGrpMetrics;
// double check
- PageMetrics doubleCheckPageMetrics = localCacheGrpMetrics.get(cacheGrpId);
+ PageMetrics doubleCheckPageMetrics = locCacheGrpMetrics.get(cacheGrpId);
if (doubleCheckPageMetrics != null)
return doubleCheckPageMetrics;
- IntMap<PageMetrics> copy = new IntHashMap<>(localCacheGrpMetrics);
+ IntMap<PageMetrics> copy = new IntHashMap<>(locCacheGrpMetrics);
PageMetrics newMetrics = Optional.of(kernalCtx)
// both cache and group descriptor can be null
@@ -675,20 +699,35 @@ public class DataRegionMetricsImpl implements DataRegionMetrics {
mreg.register("PagesFillFactor",
this::getPagesFillFactor,
- "The percentage of the used space.");
+ "Returns the ratio of space occupied by user and system data to the whole allocated space");
+
+ mreg.register("SizeUsedByData",
+ this::getSizeUsedByData,
+ "Returns the number of bytes, occupied by data. Similar to TotalUsedSize, but it also takes into " +
+ "account the empty space in non-empty pages");
mreg.register("PhysicalMemoryPages",
this::getPhysicalMemoryPages,
- "Number of pages residing in physical RAM.");
+ "Number of pages residing in physical RAM");
mreg.register("OffheapUsedSize",
this::getOffheapUsedSize,
- "Offheap used size in bytes.");
+ "Offheap used size in bytes");
+
+ // TotalAllocatedPages metrics is registered by PageMetrics
mreg.register("TotalAllocatedSize",
this::getTotalAllocatedSize,
"Gets a total size of memory allocated in the data region, in bytes");
+ mreg.register("TotalUsedPages",
+ this::getTotalUsedPages,
+ "Gets an amount of non-empty pages allocated in the data region");
+
+ mreg.register("TotalUsedSize",
+ this::getTotalUsedSize,
+ "Gets an amount of bytes, occupied by non-empty pages allocated in the data region");
+
mreg.register("PhysicalMemorySize",
this::getPhysicalMemorySize,
"Gets total size of pages loaded to the RAM, in bytes");
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsMXBeanImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsMXBeanImpl.java
index b0e94d88a6b..e68438b1337 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsMXBeanImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsMXBeanImpl.java
@@ -75,14 +75,19 @@ class DataRegionMetricsMXBeanImpl implements DataRegionMetricsMXBean {
return memMetrics.getTotalAllocatedPages();
}
+ /** {@inheritDoc} */
+ @Override public long getTotalAllocatedSize() {
+ return memMetrics.getTotalAllocatedSize();
+ }
+
/** {@inheritDoc} */
@Override public long getTotalUsedPages() {
return memMetrics.getTotalUsedPages();
}
/** {@inheritDoc} */
- @Override public long getTotalAllocatedSize() {
- return memMetrics.getTotalAllocatedSize();
+ @Override public long getTotalUsedSize() {
+ return memMetrics.getTotalUsedSize();
}
/** {@inheritDoc} */
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsSnapshot.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsSnapshot.java
index d18219217d4..316f98fe875 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsSnapshot.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsSnapshot.java
@@ -24,70 +24,73 @@ import org.apache.ignite.DataRegionMetrics;
*/
public class DataRegionMetricsSnapshot implements DataRegionMetrics {
/** */
- private String name;
+ private final String name;
/** */
- private long totalAllocatedPages;
+ private final long totalAllocatedPages;
/** */
- private long totalUsedPages;
+ private final long totalAllocatedSize;
/** */
- private long totalAllocatedSize;
+ private final long totalUsedPages;
/** */
- private float allocationRate;
+ private final long totalUsedSize;
/** */
- private float evictionRate;
+ private final float allocationRate;
/** */
- private float largeEntriesPagesPercentage;
+ private final float evictionRate;
/** */
- private float pagesFillFactor;
+ private final float largeEntriesPagesPercentage;
/** */
- private long dirtyPages;
+ private final float pagesFillFactor;
/** */
- private float pageReplaceRate;
+ private final long dirtyPages;
/** */
- private float pageReplaceAge;
+ private final float pageReplaceRate;
/** */
- private long physicalMemoryPages;
+ private final float pageReplaceAge;
/** */
- private long physicalMemorySize;
+ private final long physicalMemoryPages;
/** */
- private long usedCheckpointBufferPages;
+ private final long physicalMemorySize;
/** */
- private long usedCheckpointBufferSize;
+ private final long usedCheckpointBufferPages;
/** */
- private long checkpointBufferSize;
+ private final long usedCheckpointBufferSize;
/** */
- private int pageSize;
+ private final long checkpointBufferSize;
/** */
- private long readPages;
+ private final int pageSize;
/** */
- private long writtenPages;
+ private final long readPages;
/** */
- private long replacedPage;
+ private final long writtenPages;
/** */
- private long offHeapSize;
+ private final long replacedPage;
/** */
- private long offHeapUsedSize;
+ private final long offHeapSize;
+
+ /** */
+ private final long offHeapUsedSize;
/**
* @param metrics Metrics instance to take a copy.
@@ -95,8 +98,9 @@ public class DataRegionMetricsSnapshot implements DataRegionMetrics {
public DataRegionMetricsSnapshot(DataRegionMetrics metrics) {
name = metrics.getName();
totalAllocatedPages = metrics.getTotalAllocatedPages();
- totalUsedPages = metrics.getTotalUsedPages();
totalAllocatedSize = metrics.getTotalAllocatedSize();
+ totalUsedPages = metrics.getTotalUsedPages();
+ totalUsedSize = metrics.getTotalUsedSize();
allocationRate = metrics.getAllocationRate();
evictionRate = metrics.getEvictionRate();
largeEntriesPagesPercentage = metrics.getLargeEntriesPagesPercentage();
@@ -127,14 +131,19 @@ public class DataRegionMetricsSnapshot implements DataRegionMetrics {
return totalAllocatedPages;
}
+ /** {@inheritDoc} */
+ @Override public long getTotalAllocatedSize() {
+ return totalAllocatedSize;
+ }
+
/** {@inheritDoc} */
@Override public long getTotalUsedPages() {
return totalUsedPages;
}
/** {@inheritDoc} */
- @Override public long getTotalAllocatedSize() {
- return totalAllocatedSize;
+ @Override public long getTotalUsedSize() {
+ return totalUsedSize;
}
/** {@inheritDoc} */
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMetricsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMetricsImpl.java
index 84661fbc3ab..3e9b923641b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMetricsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMetricsImpl.java
@@ -120,7 +120,6 @@ public class PageMetricsImpl implements PageMetrics {
return totalPages;
}
-
/** {@inheritDoc} */
@Override public LongAdderMetric indexPages() {
return idxPages;
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/FillFactorMetricTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/FillFactorMetricTest.java
index ea4a78643c4..5e424404e47 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/FillFactorMetricTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/FillFactorMetricTest.java
@@ -44,10 +44,10 @@ public class FillFactorMetricTest extends GridCommonAbstractTest {
private static final String MY_CACHE = "mycache";
/** */
- public static final int NODES = 2;
+ private static final int NODES = 2;
/** */
- public static final long LARGE_PRIME = 4294967291L;
+ private static final long LARGE_PRIME = 4294967291L;
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
@@ -78,7 +78,7 @@ public class FillFactorMetricTest extends GridCommonAbstractTest {
/**
* Records counter.
*/
- private AtomicInteger recordsInCache = new AtomicInteger();
+ private final AtomicInteger recordsInCache = new AtomicInteger();
/**
* Last fill factor values.
@@ -110,16 +110,16 @@ public class FillFactorMetricTest extends GridCommonAbstractTest {
*/
@Test
public void testFillAndEmpty() throws Exception {
- final AtomicBoolean stopLoadFlag = new AtomicBoolean();
- final AtomicBoolean doneFlag = new AtomicBoolean();
+ AtomicBoolean stopLoadFlag = new AtomicBoolean();
+ AtomicBoolean doneFlag = new AtomicBoolean();
startGrids(NODES);
grid(0).getOrCreateCache(cacheCfg());
- final int pageSize = grid(0).configuration().getDataStorageConfiguration().getPageSize();
+ int pageSize = grid(0).configuration().getDataStorageConfiguration().getPageSize();
- IgniteInternalFuture printStatFut = GridTestUtils.runAsync(new Runnable() {
+ IgniteInternalFuture<?> printStatFut = GridTestUtils.runAsync(new Runnable() {
@Override public void run() {
while (!doneFlag.get()) {
log.info("Stat nodes:");
@@ -160,24 +160,22 @@ public class FillFactorMetricTest extends GridCommonAbstractTest {
stopLoadFlag.set(false);
recordsInCache.set(0);
- IgniteInternalFuture loadFut = GridTestUtils.runAsync(new Runnable() {
- @Override public void run() {
- IgniteCache<Object, Object> cache = grid(0).cache(MY_CACHE);
+ IgniteInternalFuture<?> loadFut = GridTestUtils.runAsync(() -> {
+ IgniteCache<Object, Object> cache = grid(0).cache(MY_CACHE);
- while (!stopLoadFlag.get()) {
- int i = recordsInCache.incrementAndGet();
+ while (!stopLoadFlag.get()) {
+ int i = recordsInCache.incrementAndGet();
- final long res = (i * i) % LARGE_PRIME;
+ long res = (i * i) % LARGE_PRIME;
- cache.put(res, new byte[1 << (res % 16)]);
+ cache.put(res, new byte[1 << (res % 16)]);
- try {
- // Steadily add entries to cache but avoid overconsumption of RAM and CPU
- Thread.sleep(1);
- }
- catch (InterruptedException ie) {
- return;
- }
+ try {
+ // Steadily add entries to cache but avoid overconsumption of RAM and CPU
+ Thread.sleep(1);
+ }
+ catch (InterruptedException ie) {
+ return;
}
}
});
@@ -195,22 +193,20 @@ public class FillFactorMetricTest extends GridCommonAbstractTest {
log.info("Going downward");
- IgniteInternalFuture clearFut = GridTestUtils.runAsync(new Runnable() {
- @Override public void run() {
- IgniteCache<Object, Object> cache = grid(0).cache(MY_CACHE);
+ IgniteInternalFuture<?> clearFut = GridTestUtils.runAsync(() -> {
+ IgniteCache<Object, Object> cache = grid(0).cache(MY_CACHE);
- int i;
- while ((i = recordsInCache.getAndDecrement()) > 0) {
- final long res = (i * i) % LARGE_PRIME;
+ int i;
+ while ((i = recordsInCache.getAndDecrement()) > 0) {
+ long res = (i * i) % LARGE_PRIME;
- cache.remove(res);
+ cache.remove(res);
- try {
- Thread.sleep(1);
- }
- catch (InterruptedException ie) {
- return;
- }
+ try {
+ Thread.sleep(1);
+ }
+ catch (InterruptedException ie) {
+ return;
}
}
});
@@ -218,10 +214,8 @@ public class FillFactorMetricTest extends GridCommonAbstractTest {
// Wait for cache to be cleared
clearFut.get();
- // Since refactoring of AbstractFreeList with recycling empty data pages,
- // fill factor after cache cleaning will about 0.99, no more obsolete typically value 0.8
for (float fillFactor : curFillFactor)
- assertTrue("FillFactor too low: " + fillFactor, fillFactor > 0.9);
+ assertTrue("FillFactor too low: " + fillFactor, fillFactor > 0.6);
}
doneFlag.set(true);
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/DataRegionMetricsTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/DataRegionMetricsTest.cs
index 4c26d0ab6ed..6088f206956 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/DataRegionMetricsTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/DataRegionMetricsTest.cs
@@ -147,7 +147,7 @@ namespace Apache.Ignite.Core.Tests.Cache
Assert.Greater(metrics.TotalAllocatedPages, isPersistent ? 0 : 1000);
Assert.Greater(metrics.PhysicalMemoryPages, isPersistent ? 0 : 1000);
Assert.AreEqual(metrics.TotalAllocatedSize,
- metrics.TotalAllocatedPages * (metrics.PageSize + (isPersistent ? 0 : PageOverhead)));
+ metrics.TotalAllocatedPages * (metrics.PageSize + (isPersistent ? PersistentPageOverhead : PageOverhead)));
Assert.AreEqual(metrics.PhysicalMemorySize,
metrics.PhysicalMemoryPages * (metrics.PageSize + (isPersistent ? PersistentPageOverhead : PageOverhead)));
Assert.Greater(metrics.OffHeapSize, metrics.PhysicalMemoryPages);