This is an automated email from the ASF dual-hosted git repository.
namelchev 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 1d9312af9a5 IGNITE-22962 Added conflict resolver metrics (#11469)
1d9312af9a5 is described below
commit 1d9312af9a5d73e0a89e8d39ae9ab552bd6c36f1
Author: Maksim Davydov <[email protected]>
AuthorDate: Mon Aug 12 12:30:25 2024 +0300
IGNITE-22962 Added conflict resolver metrics (#11469)
---
.../change-data-capture-extensions.adoc | 13 --
docs/_docs/monitoring-metrics/new-metrics.adoc | 3 +
.../processors/cache/CacheMetricsImpl.java | 50 ++++++-
.../processors/cache/GridCacheContext.java | 10 ++
.../metric/CacheMetricsConflictResolverTest.java | 146 +++++++++++++++++++++
.../ignite/testsuites/IgniteCacheTestSuite13.java | 2 +
6 files changed, 210 insertions(+), 14 deletions(-)
diff --git
a/docs/_docs/extensions-and-integrations/change-data-capture-extensions.adoc
b/docs/_docs/extensions-and-integrations/change-data-capture-extensions.adoc
index 98d6cfc7f32..206f5fbb842 100644
--- a/docs/_docs/extensions-and-integrations/change-data-capture-extensions.adoc
+++ b/docs/_docs/extensions-and-integrations/change-data-capture-extensions.adoc
@@ -260,19 +260,6 @@ You should consider the nature of your transactions, the
rate of change of your
Custom conflict resolver can be set via `conflictResolver` and allows to
compare or merge the conflict data in any required way.
-=== Conflict Resolver Metrics
-
-The Ignite's built-in `CacheVersionConflictResolverPluginProvider` provides
the following metrics:
-
-[cols="35%,65%",opts="header"]
-|===
-|Name |Description
-| `AcceptedCount` | Count of accepted entries.
-| `RejectedCount` | Count of rejected entries.
-|===
-
-These metrics are registered under `conflict-resolver` registry for each node
configured with this plugin.
-
=== Configuration example
Configuration is done via Ignite node plugin:
diff --git a/docs/_docs/monitoring-metrics/new-metrics.adoc
b/docs/_docs/monitoring-metrics/new-metrics.adoc
index 7bce59dcb00..e723e93fa9f 100644
--- a/docs/_docs/monitoring-metrics/new-metrics.adoc
+++ b/docs/_docs/monitoring-metrics/new-metrics.adoc
@@ -68,6 +68,9 @@ Register name: `cache.{cache_name}.{near}`
|CacheSize|long|Local cache size.
|CommitTime |histogram | Commit time in nanoseconds.
|CommitTimeTotal |long| The total time of commit, in nanoseconds.
+|ConflictResolverAcceptedCount|long|Conflict resolver accepted entries count.
+|ConflictResolverRejectedCount|long|Conflict resolver rejected entries count.
+|ConflictResolverMergedCount|long|Conflict resolver merged entries count.
|EntryProcessorHits | long|The total number of invocations on keys, which
exist in cache.
|EntryProcessorInvokeTimeNanos | long | The total time of cache invocations
for which this node is the initiator, in nanoseconds.
|EntryProcessorMaxInvocationTime |long | So far, the maximum time to execute
cache invokes for which this node is the initiator.
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
index 0f305d63751..02892764994 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
@@ -228,6 +228,18 @@ public class CacheMetricsImpl implements CacheMetrics {
/** The number of local node partitions that remain to be processed to
complete indexing. */
private final IntMetricImpl idxBuildPartitionsLeftCnt;
+ /** Cache metric registry. */
+ private final MetricRegistryImpl mreg;
+
+ /** Conflict resolver accepted entries count. */
+ private LongAdderMetric rslvrAcceptedCnt;
+
+ /** Conflict resolver rejected entries count. */
+ private LongAdderMetric rslvrRejectedCnt;
+
+ /** Conflict resolver merged entries count. */
+ private LongAdderMetric rslvrMergedCnt;
+
/**
* Creates cache metrics.
*
@@ -256,7 +268,7 @@ public class CacheMetricsImpl implements CacheMetrics {
delegate = null;
- MetricRegistryImpl mreg =
cctx.kernalContext().metric().registry(cacheMetricsRegistryName(cctx.name(),
isNear));
+ mreg =
cctx.kernalContext().metric().registry(cacheMetricsRegistryName(cctx.name(),
isNear));
reads = mreg.longMetric("CacheGets",
"The total number of gets to the cache.");
@@ -732,6 +744,15 @@ public class CacheMetricsImpl implements CacheMetrics {
txKeyCollisionInfo = null;
idxRebuildKeyProcessed.reset();
+
+ if (rslvrAcceptedCnt != null)
+ rslvrAcceptedCnt.reset();
+
+ if (rslvrRejectedCnt != null)
+ rslvrRejectedCnt.reset();
+
+ if (rslvrMergedCnt != null)
+ rslvrMergedCnt.reset();
}
/** {@inheritDoc} */
@@ -1659,6 +1680,33 @@ public class CacheMetricsImpl implements CacheMetrics {
return idxBuildPartitionsLeftCnt.value();
}
+ /** */
+ public void incrementResolverAcceptedCount() {
+ rslvrAcceptedCnt.increment();
+ }
+
+ /** */
+ public void incrementResolverRejectedCount() {
+ rslvrRejectedCnt.increment();
+ }
+
+ /** */
+ public void incrementResolverMergedCount() {
+ rslvrMergedCnt.increment();
+ }
+
+ /** Registers metrics for conflict resolver. */
+ public void registerResolverMetrics() {
+ rslvrAcceptedCnt =
mreg.longAdderMetric("ConflictResolverAcceptedCount",
+ "Conflict resolver accepted entries count");
+
+ rslvrRejectedCnt =
mreg.longAdderMetric("ConflictResolverRejectedCount",
+ "Conflict resolver rejected entries count");
+
+ rslvrMergedCnt = mreg.longAdderMetric("ConflictResolverMergedCount",
+ "Conflict resolver merged entries count");
+ }
+
/** {@inheritDoc} */
@Override public String toString() {
return S.toString(CacheMetricsImpl.class, this);
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
index fbf11bf85a1..dc5b8a7b2cf 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
@@ -487,6 +487,9 @@ public class GridCacheContext<K, V> implements
Externalizable {
*/
void initConflictResolver() {
conflictRslvr = rslvrMgr.conflictResolver();
+
+ if (conflictRslvr != null)
+ cache().metrics0().registerResolverMetrics();
}
/**
@@ -1641,6 +1644,13 @@ public class GridCacheContext<K, V> implements
Externalizable {
GridCacheVersionConflictContext<K, V> ctx =
conflictRslvr.resolve(cacheObjCtx, oldEntry, newEntry,
atomicVerComp);
+ if (ctx.isUseNew())
+ cache().metrics0().incrementResolverAcceptedCount();
+ else if (ctx.isUseOld())
+ cache().metrics0().incrementResolverRejectedCount();
+ else
+ cache().metrics0().incrementResolverMergedCount();
+
if (ctx.isManualResolve())
drMgr.onReceiveCacheConflictResolved(ctx.isUseNew(),
ctx.isUseOld(), ctx.isMerge());
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/metric/CacheMetricsConflictResolverTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/metric/CacheMetricsConflictResolverTest.java
new file mode 100644
index 00000000000..b2385935fcc
--- /dev/null
+++
b/modules/core/src/test/java/org/apache/ignite/internal/metric/CacheMetricsConflictResolverTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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.metric;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import
org.apache.ignite.internal.processors.cache.CacheConflictResolutionManager;
+import org.apache.ignite.internal.processors.cache.CacheObjectValueContext;
+import org.apache.ignite.internal.processors.cache.GridCacheManagerAdapter;
+import
org.apache.ignite.internal.processors.cache.version.CacheVersionConflictResolver;
+import
org.apache.ignite.internal.processors.cache.version.GridCacheVersionConflictContext;
+import
org.apache.ignite.internal.processors.cache.version.GridCacheVersionedEntryEx;
+import org.apache.ignite.internal.processors.metric.MetricRegistryImpl;
+import org.apache.ignite.plugin.AbstractTestPluginProvider;
+import org.apache.ignite.plugin.PluginContext;
+import org.apache.ignite.spi.metric.LongMetric;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+
+import static
org.apache.ignite.internal.processors.metric.impl.MetricUtils.cacheMetricsRegistryName;
+
+/** Tests conflict resolver metrics per cache. */
+public class CacheMetricsConflictResolverTest extends GridCommonAbstractTest {
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String
igniteInstanceName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+ cfg.setPluginProviders(new AbstractTestPluginProvider() {
+ @Override public String name() {
+ return "ConflictResolverProvider";
+ }
+
+ @Override public <T> T createComponent(PluginContext ctx, Class<T>
cls) {
+ if (cls != CacheConflictResolutionManager.class)
+ return null;
+
+ return (T)new DynamicResolutionManager<>();
+ }
+ });
+
+ return cfg;
+ }
+
+ /** */
+ @Test
+ public void testCacheConflictResolver() throws Exception {
+ IgniteEx ign = startGrid(0);
+
+ IgniteCache<Object, Object> cache =
ign.getOrCreateCache(DEFAULT_CACHE_NAME);
+
+ checkMetrics(0, 0, 0);
+
+ TestCacheVersionConflictResolver.plc = ResolvePolicy.USE_NEW;
+
+ cache.put(0, 0);
+
+ checkMetrics(1, 0, 0);
+
+ TestCacheVersionConflictResolver.plc = ResolvePolicy.USE_OLD;
+
+ cache.put(0, 0);
+
+ checkMetrics(1, 1, 0);
+
+ TestCacheVersionConflictResolver.plc = ResolvePolicy.MERGE;
+
+ cache.put(0, 0);
+
+ checkMetrics(1, 1, 1);
+ }
+
+ /** */
+ private void checkMetrics(int expAccepted, int expRejected, int expMerged)
{
+ MetricRegistryImpl mreg =
grid(0).context().metric().registry(cacheMetricsRegistryName(DEFAULT_CACHE_NAME,
false));
+
+ assertEquals(expAccepted,
mreg.<LongMetric>findMetric("ConflictResolverAcceptedCount").value());
+ assertEquals(expRejected,
mreg.<LongMetric>findMetric("ConflictResolverRejectedCount").value());
+ assertEquals(expMerged,
mreg.<LongMetric>findMetric("ConflictResolverMergedCount").value());
+ }
+
+ /** */
+ private static class TestCacheVersionConflictResolver implements
CacheVersionConflictResolver {
+ /** */
+ private static ResolvePolicy plc;
+
+ /** {@inheritDoc} */
+ @Override public <K, V> GridCacheVersionConflictContext<K, V> resolve(
+ CacheObjectValueContext ctx,
+ GridCacheVersionedEntryEx<K, V> oldEntry,
+ GridCacheVersionedEntryEx<K, V> newEntry,
+ boolean atomicVerComparator
+ ) {
+ GridCacheVersionConflictContext<K, V> res = new
GridCacheVersionConflictContext<>(ctx, oldEntry, newEntry);
+
+ if (plc == ResolvePolicy.USE_NEW)
+ res.useNew();
+ else if (plc == ResolvePolicy.USE_OLD)
+ res.useOld();
+ else
+ res.merge(
+ newEntry.value(ctx),
+ Math.max(oldEntry.ttl(), newEntry.ttl()),
+ Math.max(oldEntry.expireTime(), newEntry.expireTime())
+ );
+
+ return res;
+ }
+ }
+
+ /** */
+ private static class DynamicResolutionManager<K, V> extends
GridCacheManagerAdapter<K, V>
+ implements CacheConflictResolutionManager<K, V> {
+ /** {@inheritDoc} */
+ @Override public CacheVersionConflictResolver conflictResolver() {
+ return new TestCacheVersionConflictResolver();
+ }
+ }
+
+ /** Policy for conflict resolver. */
+ private enum ResolvePolicy {
+ /** Use old. */
+ USE_OLD,
+
+ /** Use new. */
+ USE_NEW,
+
+ /** Merge. */
+ MERGE
+ }
+}
diff --git
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java
index 58ace1eff29..b9d1e4fd6be 100644
---
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java
+++
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.ignite.internal.metric.CacheMetricsAddRemoveTest;
+import org.apache.ignite.internal.metric.CacheMetricsConflictResolverTest;
import org.apache.ignite.internal.metric.CustomMetricsTest;
import org.apache.ignite.internal.metric.IoStatisticsCachePersistenceSelfTest;
import org.apache.ignite.internal.metric.IoStatisticsCacheSelfTest;
@@ -89,6 +90,7 @@ public class IgniteCacheTestSuite13 {
GridTestUtils.addTestIfNeeded(suite, SystemViewComputeJobTest.class,
ignoredTests);
GridTestUtils.addTestIfNeeded(suite,
SystemViewCacheExpiryPolicyTest.class, ignoredTests);
GridTestUtils.addTestIfNeeded(suite, CacheMetricsAddRemoveTest.class,
ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
CacheMetricsConflictResolverTest.class, ignoredTests);
GridTestUtils.addTestIfNeeded(suite, JmxExporterSpiTest.class,
ignoredTests);
GridTestUtils.addTestIfNeeded(suite, LogExporterSpiTest.class,
ignoredTests);
GridTestUtils.addTestIfNeeded(suite,
ReadMetricsOnNodeStartupTest.class, ignoredTests);