You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by tk...@apache.org on 2025/10/03 10:03:52 UTC
(ignite-3) 01/01: IGNITE-26594 wip
This is an automated email from the ASF dual-hosted git repository.
tkalkirill pushed a commit to branch ignite-26594
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
commit 6c5ea5ff124670be4c8a2d2722ab6817de5afdd3
Author: Kirill Tkalenko <tk...@yandex.ru>
AuthorDate: Fri Oct 3 13:03:32 2025 +0300
IGNITE-26594 wip
---
modules/page-memory/build.gradle | 1 +
.../persistence/PersistentPageMemory.java | 35 +++----
.../PersistentPageMemoryMetricSource.java | 4 +-
.../persistence/PersistentPageMemoryMetrics.java | 75 ++++++++++++++
.../PersistentPageMemoryMetricsTest.java | 114 +++++++++++++++++++++
5 files changed, 206 insertions(+), 23 deletions(-)
diff --git a/modules/page-memory/build.gradle b/modules/page-memory/build.gradle
index a20830959e7..7189f055c56 100644
--- a/modules/page-memory/build.gradle
+++ b/modules/page-memory/build.gradle
@@ -41,6 +41,7 @@ dependencies {
testImplementation project(':ignite-failure-handler')
testImplementation testFixtures(project(':ignite-core'))
testImplementation testFixtures(project(':ignite-configuration'))
+ testImplementation testFixtures(project(':ignite-metrics'))
testImplementation libs.auto.service.annotations
testFixturesAnnotationProcessor libs.auto.service
diff --git a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemory.java b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemory.java
index 80741dc7d0f..2c1d0e637a4 100644
--- a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemory.java
+++ b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemory.java
@@ -82,8 +82,6 @@ import org.apache.ignite.internal.lang.IgniteInternalCheckedException;
import org.apache.ignite.internal.lang.IgniteInternalException;
import org.apache.ignite.internal.logger.IgniteLogger;
import org.apache.ignite.internal.logger.Loggers;
-import org.apache.ignite.internal.metrics.IntGauge;
-import org.apache.ignite.internal.metrics.LongGauge;
import org.apache.ignite.internal.pagememory.FullPageId;
import org.apache.ignite.internal.pagememory.PageMemory;
import org.apache.ignite.internal.pagememory.configuration.PersistentDataRegionConfiguration;
@@ -155,8 +153,6 @@ public class PersistentPageMemory implements PageMemory {
/** Data region configuration. */
private final PersistentDataRegionConfiguration dataRegionConfiguration;
- private final PersistentPageMemoryMetricSource metricSource;
-
/** Page IO registry. */
private final PageIoRegistry ioRegistry;
@@ -213,6 +209,8 @@ public class PersistentPageMemory implements PageMemory {
/** Checkpoint timeout lock. */
private final CheckpointTimeoutLock checkpointTimeoutLock;
+ private final PersistentPageMemoryMetrics metrics;
+
/**
* Constructor.
*
@@ -240,8 +238,6 @@ public class PersistentPageMemory implements PageMemory {
PartitionDestructionLockManager partitionDestructionLockManager
) {
this.dataRegionConfiguration = dataRegionConfiguration;
- this.metricSource = metricSource;
- initMetrics();
this.ioRegistry = ioRegistry;
this.sizes = concat(segmentSizes, checkpointBufferSize);
@@ -274,9 +270,15 @@ public class PersistentPageMemory implements PageMemory {
throw new IgniteInternalException("Unexpected page replacement mode: " + replacementMode);
}
+ metrics = new PersistentPageMemoryMetrics(metricSource, this, dataRegionConfiguration);
+
delayedPageReplacementTracker = new DelayedPageReplacementTracker(
pageSize,
- flushDirtyPageForReplacement,
+ (pageMemory, fullPageId, buffer) -> {
+ metrics.incrementWriteToDiskMetric();
+
+ flushDirtyPageForReplacement.write(pageMemory, fullPageId, buffer);
+ },
LOG,
sizes.length - 1,
partitionDestructionLockManager
@@ -285,21 +287,6 @@ public class PersistentPageMemory implements PageMemory {
this.writeThrottle = null;
}
- private void initMetrics() {
- metricSource.addMetric(new IntGauge(
- "UsedCheckpointBufferPages", "Number of currently used pages in checkpoint buffer.", this::usedCheckpointBufferPages
- ));
- metricSource.addMetric(new IntGauge(
- "MaxCheckpointBufferPages", "The capacity of checkpoint buffer in pages.", this::maxCheckpointBufferPages
- ));
- // TODO: IGNITE-25702 Fix the concept of "region"
- metricSource.addMetric(new LongGauge(
- "MaxSize",
- "Maximum in-memory region size in bytes.",
- dataRegionConfiguration::sizeBytes
- ));
- }
-
/**
* Temporary method to enable throttling in tests.
*
@@ -850,6 +837,8 @@ public class PersistentPageMemory implements PageMemory {
pageStoreManager.read(grpId, pageId, buf, false);
actualPageId = getPageId(buf);
+
+ metrics.incrementReadFromDiskMetric();
} finally {
rwLock.writeUnlock(lockedPageAbsPtr + PAGE_LOCK_OFFSET, actualPageId == 0 ? TAG_LOCK_ALWAYS : tag(actualPageId));
}
@@ -2055,6 +2044,8 @@ public class PersistentPageMemory implements PageMemory {
pageStoreWriter.writePage(fullId, buf, partitionGeneration);
buf.rewind();
+
+ metrics.incrementWriteToDiskMetric();
}
// We pinned the page either when allocated the temp buffer, or when resolved abs pointer.
diff --git a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemoryMetricSource.java b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemoryMetricSource.java
index 56bcf99c0ab..50f007bd8d6 100644
--- a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemoryMetricSource.java
+++ b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemoryMetricSource.java
@@ -58,10 +58,12 @@ public class PersistentPageMemoryMetricSource implements MetricSource {
/**
* Adds metric to the source.
*/
- public synchronized void addMetric(Metric metric) {
+ public synchronized <T extends Metric> T addMetric(T metric) {
assert !enabled : "Cannot add metrics when source is enabled";
metrics.put(metric.name(), metric);
+
+ return metric;
}
@Override
diff --git a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemoryMetrics.java b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemoryMetrics.java
new file mode 100644
index 00000000000..c3594ee6cf8
--- /dev/null
+++ b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemoryMetrics.java
@@ -0,0 +1,75 @@
+/*
+ * 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.pagememory.persistence;
+
+import org.apache.ignite.internal.metrics.IntGauge;
+import org.apache.ignite.internal.metrics.LongAdderMetric;
+import org.apache.ignite.internal.metrics.LongGauge;
+import org.apache.ignite.internal.pagememory.configuration.PersistentDataRegionConfiguration;
+
+/** Persistent page memory metrics. */
+class PersistentPageMemoryMetrics {
+ private final LongAdderMetric readPagesFromDisk;
+
+ private final LongAdderMetric writePagesToDisk;
+
+ PersistentPageMemoryMetrics(
+ PersistentPageMemoryMetricSource source,
+ PersistentPageMemory pageMemory,
+ PersistentDataRegionConfiguration dataRegionConfiguration
+ ) {
+ source.addMetric(new IntGauge(
+ "UsedCheckpointBufferPages",
+ "Number of currently used pages in checkpoint buffer.",
+ pageMemory::usedCheckpointBufferPages
+ ));
+
+ source.addMetric(new IntGauge(
+ "MaxCheckpointBufferPages",
+ "The capacity of checkpoint buffer in pages.",
+ pageMemory::maxCheckpointBufferPages
+ ));
+
+ // TODO: IGNITE-25702 Fix the concept of "region"
+ source.addMetric(new LongGauge(
+ "MaxSize",
+ "Maximum in-memory region size in bytes.",
+ dataRegionConfiguration::sizeBytes
+ ));
+
+ readPagesFromDisk = source.addMetric(new LongAdderMetric(
+ "PagesRead",
+ "Number of pages read from disk since the last restart."
+ ));
+
+ writePagesToDisk = source.addMetric(new LongAdderMetric(
+ "PagesWritten",
+ "Number of pages written to disk since the last restart."
+ ));
+ }
+
+ /** Increases the disk page read metric by one. */
+ public void incrementReadFromDiskMetric() {
+ readPagesFromDisk.increment();
+ }
+
+ /** Increases the page writes to disk metric by one. */
+ public void incrementWriteToDiskMetric() {
+ writePagesToDisk.increment();
+ }
+}
diff --git a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemoryMetricsTest.java b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemoryMetricsTest.java
new file mode 100644
index 00000000000..e0be64dbe76
--- /dev/null
+++ b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/PersistentPageMemoryMetricsTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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.pagememory.persistence;
+
+import static org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.ignite.internal.manager.ComponentContext;
+import org.apache.ignite.internal.metrics.Metric;
+import org.apache.ignite.internal.metrics.MetricManager;
+import org.apache.ignite.internal.metrics.MetricSet;
+import org.apache.ignite.internal.metrics.TestMetricManager;
+import org.apache.ignite.internal.pagememory.configuration.PersistentDataRegionConfiguration;
+import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/** For {@link PersistentPageMemoryMetrics} testing. */
+public class PersistentPageMemoryMetricsTest extends BaseIgniteAbstractTest {
+ private final PersistentPageMemoryMetricSource metricSource = new PersistentPageMemoryMetricSource("test");
+
+ private final PersistentPageMemory pageMemory = mock(PersistentPageMemory.class);
+
+ private final PersistentDataRegionConfiguration dataRegionConfig = PersistentDataRegionConfiguration.builder().size(100).build();
+
+ private final PersistentPageMemoryMetrics metrics = new PersistentPageMemoryMetrics(metricSource, pageMemory, dataRegionConfig);
+
+ private final MetricManager metricManager = new TestMetricManager();
+
+ @BeforeEach
+ void setUp() {
+ metricManager.registerSource(metricSource);
+ metricManager.enable(metricSource);
+
+ assertThat(metricManager.startAsync(new ComponentContext()), willCompleteSuccessfully());
+ }
+
+ @AfterEach
+ void tearDown() {
+ metricManager.beforeNodeStop();
+
+ assertThat(metricManager.stopAsync(new ComponentContext()), willCompleteSuccessfully());
+ }
+
+ @Test
+ void testMaxSize() {
+ checkMetricValue("MaxSize", Long.toString(dataRegionConfig.sizeBytes()));
+ }
+
+ @Test
+ void testUsedCheckpointBufferPages() {
+ when(pageMemory.usedCheckpointBufferPages()).thenReturn(42);
+
+ checkMetricValue("UsedCheckpointBufferPages", "42");
+ }
+
+ @Test
+ void testMaxCheckpointBufferPages() {
+ when(pageMemory.maxCheckpointBufferPages()).thenReturn(84);
+
+ checkMetricValue("MaxCheckpointBufferPages", "84");
+ }
+
+ @Test
+ void testPagesRead() {
+ checkMetricValue("PagesRead", "0");
+
+ metrics.incrementReadFromDiskMetric();
+ metrics.incrementReadFromDiskMetric();
+
+ checkMetricValue("PagesRead", "2");
+ }
+
+ @Test
+ void testPagesWritten() {
+ checkMetricValue("PagesWritten", "0");
+
+ metrics.incrementWriteToDiskMetric();
+ metrics.incrementWriteToDiskMetric();
+ metrics.incrementWriteToDiskMetric();
+
+ checkMetricValue("PagesWritten", "3");
+ }
+
+ private void checkMetricValue(String metricName, String exp) {
+ MetricSet metricsSet = metricManager.metricSnapshot().metrics().get(metricSource.name());
+
+ Metric metric = metricsSet.get(metricName);
+
+ assertNotNull(metric, metricName);
+
+ assertEquals(exp, metric.getValueAsString(), metricName);
+ }
+}