You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by av...@apache.org on 2019/08/28 11:35:30 UTC

[ignite] branch master updated: IGNITE-11978 javadoc enhancement for the ReadRepair feature (#6689)

This is an automated email from the ASF dual-hosted git repository.

av 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 fe8fd20  IGNITE-11978 javadoc enhancement for the ReadRepair feature (#6689)
fe8fd20 is described below

commit fe8fd2041a17d4d315408ebcf90def33db17c66c
Author: Slava Koptilin <sl...@gmail.com>
AuthorDate: Wed Aug 28 14:35:21 2019 +0300

    IGNITE-11978 javadoc enhancement for the ReadRepair feature (#6689)
---
 .../main/java/org/apache/ignite/IgniteCache.java   | 24 ++++++--
 .../events/CacheConsistencyViolationEvent.java     | 69 ++++++++++++++++------
 .../processors/cache/CacheOperationContext.java    |  4 +-
 .../cache/GatewayProtectedCacheProxy.java          | 24 ++++----
 .../processors/cache/GridCacheAdapter.java         | 14 ++++-
 .../GridNearReadRepairAbstractFuture.java          | 14 ++++-
 .../GridNearReadRepairCheckOnlyFuture.java         | 20 ++++++-
 .../near/consistency/GridNearReadRepairFuture.java | 12 +++-
 .../cache/consistency/AbstractReadRepairTest.java  |  2 +-
 9 files changed, 143 insertions(+), 40 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
index 9711a33..002f2c2 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
@@ -63,8 +63,10 @@ import org.apache.ignite.lang.IgniteBiPredicate;
 import org.apache.ignite.lang.IgniteClosure;
 import org.apache.ignite.lang.IgniteFuture;
 import org.apache.ignite.mxbean.CacheMetricsMXBean;
+import org.apache.ignite.transactions.TransactionConcurrency;
 import org.apache.ignite.transactions.TransactionException;
 import org.apache.ignite.transactions.TransactionHeuristicException;
+import org.apache.ignite.transactions.TransactionIsolation;
 import org.apache.ignite.transactions.TransactionRollbackException;
 import org.apache.ignite.transactions.TransactionTimeoutException;
 import org.jetbrains.annotations.Nullable;
@@ -145,18 +147,32 @@ public interface IgniteCache<K, V> extends javax.cache.Cache<K, V>, IgniteAsyncS
      *  <li>for transactional caches:
      *  <p>values across the topology will be replaced by latest versioned value:
      *  <ul>
-     *      <li>automaticaly for OPTIMISTIC || READ_COMMITTED transactions</li>
-     *      <li>at commit() for PESSIMISTIC && !READ_COMMITTED transactions</li>
+     *      <li>automatically for transactions that have {@link TransactionConcurrency#OPTIMISTIC} concurrency mode
+     *          or {@link TransactionIsolation#READ_COMMITTED} isolation level</li>
+     *      <li>at commit() phase for transactions that have {@link TransactionConcurrency#PESSIMISTIC} concurrency mode
+     *          and isolation level other than {@link TransactionIsolation#READ_COMMITTED}</li>
      *  </ul>
      *  <p>consistency violation event will be recorded in case it's configured as recordable</li>
-     *  <li>for atomic caches: consistency violation exception will be thrown.</li>
+     *  <li>for atomic caches: consistency violation exception will be thrown.
+     *  Be aware that consistency violation event will not be recorded in this case.</li>
      * </ul>
      * <p>
      * One more important thing is that this proxy usage does not guarantee "all copies check" in case value
      * already cached inside the transaction. In case you use !READ_COMMITTED isolation mode and already have
      * cached value, for example already read the value or performed a write, you'll gain the cached value.
      * <p>
-     * Local caches and caches without backups, obviously, can not be checked using this feature.
+     * Due to the nature of the atomic cache, false-positive results can be observed. For example, an attempt to check
+     * consistency under cache loading may lead to consistency violation exception. By default, the implementation tries
+     * to check the given key three times. The number of attempts can be changed using
+     * {@link IgniteSystemProperties#IGNITE_NEAR_GET_MAX_REMAPS} property.
+     * <p>
+     * Consistency check is incompatible with the following cache configurations:
+     * <ul>
+     *     <li>Caches without backups.</li>
+     *     <li>Local caches.</li>
+     *     <li>Near caches.</li>
+     *     <li>Caches that use "read-through" mode.</li>
+     * </ul>
      * <p>
      * Full list of repairable methods:
      * <ul>
diff --git a/modules/core/src/main/java/org/apache/ignite/events/CacheConsistencyViolationEvent.java b/modules/core/src/main/java/org/apache/ignite/events/CacheConsistencyViolationEvent.java
index 9fcc889..01fee82 100644
--- a/modules/core/src/main/java/org/apache/ignite/events/CacheConsistencyViolationEvent.java
+++ b/modules/core/src/main/java/org/apache/ignite/events/CacheConsistencyViolationEvent.java
@@ -24,46 +24,81 @@ import org.apache.ignite.cluster.ClusterNode;
 import static org.apache.ignite.events.EventType.EVT_CONSISTENCY_VIOLATION;
 
 /**
- * Event indicates consistency violation detection.
+ * Event indicates a consistency violation.
+ * <p>
+ * Grid events are used for notification about what happens within the grid. Note that by
+ * design Ignite keeps all events generated on the local node locally and it provides
+ * APIs for performing a distributed queries across multiple nodes:
+ * <ul>
+ *      <li>
+ *          {@link org.apache.ignite.IgniteEvents#remoteQuery(org.apache.ignite.lang.IgnitePredicate, long, int...)} -
+ *          asynchronously querying events occurred on the nodes specified, including remote nodes.
+ *      </li>
+ *      <li>
+ *          {@link org.apache.ignite.IgniteEvents#localQuery(org.apache.ignite.lang.IgnitePredicate, int...)} -
+ *          querying only local events stored on this local node.
+ *      </li>
+ *      <li>
+ *          {@link org.apache.ignite.IgniteEvents#localListen(org.apache.ignite.lang.IgnitePredicate, int...)} -
+ *          listening to local grid events (events from remote nodes not included).
+ *      </li>
+ * </ul>
+ * User can also wait for events using method {@link org.apache.ignite.IgniteEvents#waitForLocal(org.apache.ignite.lang.IgnitePredicate, int...)}.
+ * <h1 class="header">Events and Performance</h1>
+ * Note that by default all events in Ignite are enabled and therefore generated and stored
+ * by whatever event storage SPI is configured. Ignite can and often does generate thousands events per seconds
+ * under the load and therefore it creates a significant additional load on the system. If these events are
+ * not needed by the application this load is unnecessary and leads to significant performance degradation.
+ * <p>
+ * It is <b>highly recommended</b> to enable only those events that your application logic requires
+ * by using {@link org.apache.ignite.configuration.IgniteConfiguration#getIncludeEventTypes()} method in Ignite configuration. Note that certain
+ * events are required for Ignite's internal operations and such events will still be generated but not stored by
+ * event storage SPI if they are disabled in Ignite configuration.
  *
  * @see EventType#EVT_CONSISTENCY_VIOLATION
  */
-public class CacheConsistencyViolationEvent extends EventAdapter {
+public class CacheConsistencyViolationEvent<K, V> extends EventAdapter {
     /** Serial version UID. */
     private static final long serialVersionUID = 0L;
 
-    /** Original distribution. */
-    Map<UUID /*Node*/, Map<Object /*Key*/, Object /*Value*/>> locEntries;
+    /** Represents original values of entries that were affected by a cache operation.*/
+    final Map<UUID /*Node*/, Map<K,V>> originalEntries;
 
-    /** Fixed entries. */
-    Map<Object /*Key*/, Object /*Value*/> fixedEntries;
+    /** Collection of repaired entries. */
+    final Map<K,V> repairedEntries;
 
     /**
+     * Creates a new instance of CacheConsistencyViolationEvent.
      *
+     * @param node Local node.
+     * @param msg Event message.
+     * @param originalEntries Collection of original entries affected by a cache operation.
+     * @param repairedEntries Collection of repaired entries.
      */
     public CacheConsistencyViolationEvent(
         ClusterNode node,
         String msg,
-        Map<UUID, Map<Object, Object>> locEntries,
-        Map<Object, Object> fixedEntries) {
+        Map<UUID, Map<K, V>> originalEntries,
+        Map<K, V> repairedEntries) {
         super(node, msg, EVT_CONSISTENCY_VIOLATION);
 
-        this.locEntries = locEntries;
-        this.fixedEntries = fixedEntries;
+        this.originalEntries = originalEntries;
+        this.repairedEntries = repairedEntries;
     }
 
     /**
-     * Original distribution.
+     * Returns a mapping node ids to a collection of original entries affected by a cache operation.
+     * @return Collection of original entries.
      */
-    public Map<UUID, Map<Object, Object>> getEntries() {
-        return locEntries;
+    public Map<UUID, Map<K, V>> getEntries() {
+        return originalEntries;
     }
 
     /**
-     * Fixed entries.
-     * Will be fixed in case of transaction commit.
+     * Returns a collection of repaired entries.
+     * @return Collection of repaired entries.
      */
-    public Map<Object, Object> getFixedEntries() {
-        return fixedEntries;
+    public Map<K, V> getRepairedEntries() {
+        return repairedEntries;
     }
 }
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOperationContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOperationContext.java
index 47eea68..73f873c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOperationContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOperationContext.java
@@ -50,7 +50,7 @@ public class CacheOperationContext implements Serializable {
     /** */
     private final boolean recovery;
 
-    /** */
+    /** Read-repair flag. */
     private final boolean readRepair;
 
     /** Client ID which operates over this projection. */
@@ -89,7 +89,7 @@ public class CacheOperationContext implements Serializable {
      * @param keepBinary Keep binary flag.
      * @param expiryPlc Expiry policy.
      * @param dataCenterId Data center id.
-     * @param readRepair Read Repair.
+     * @param readRepair Read-repair flag.
      */
     public CacheOperationContext(
         boolean skipStore,
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GatewayProtectedCacheProxy.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GatewayProtectedCacheProxy.java
index 8023b00..11b24aa 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GatewayProtectedCacheProxy.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GatewayProtectedCacheProxy.java
@@ -236,22 +236,26 @@ public class GatewayProtectedCacheProxy<K, V> extends AsyncSupportAdapter<Ignite
         CacheOperationGate opGate = onEnter();
 
         try {
-            if (context().mvccEnabled()) // Can (should?) be supported in future.
-                throw new UnsupportedOperationException("Read Repair is not supported at MVCC mode.");
+            if (context().mvccEnabled()) {
+                throw new UnsupportedOperationException(
+                    "The TRANSACTIONAL_SNAPSHOT mode is incompatible with the read-repair feature.");
+            }
 
-            if (context().isNear()) // Can be supported in future.
-                throw new UnsupportedOperationException("Read Repair is not supported for near caches.");
+            if (context().isNear())
+                throw new UnsupportedOperationException("Read-repair is incompatible with near caches.");
 
-            if (context().readThrough()) // Can be supported in future.
+            if (context().readThrough()) {
                 // Read Repair get operation produces different versions for same entries loaded via readThrough feature.
-                throw new UnsupportedOperationException("Read Repair is not supported for caches with readThrough enabled.");
+                throw new UnsupportedOperationException("Read-repair is incompatible with caches that use readThrough.");
+            }
 
-            if (context().isLocal()) // Can't be supported in future.
-                throw new UnsupportedOperationException("Read Repair is not supported for local caches.");
+            if (context().isLocal())
+                throw new UnsupportedOperationException("Read-repair is incompatible with local caches.");
 
-            if (context().config().getBackups() == 0) // Can't be supported in future.
-                throw new UnsupportedOperationException("Read Repair is suitable only in case " +
+            if (context().config().getBackups() == 0) {
+                throw new UnsupportedOperationException("Read-repair is suitable only in case " +
                     "at least 1 backup configured for cache.");
+            }
 
             boolean readRepair = opCtx.readRepair();
 
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
index a6476fa..020b3a2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
@@ -5050,7 +5050,12 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
     }
 
     /**
-     * Checks and repairs entries across the topology.
+     * Checks the given {@code keys} and repairs entries across the topology if needed.
+     *
+     * @param keys Keys.
+     * @param opCtx Operation context.
+     * @param skipVals Skip values flag.
+     * @return Compound future that represents a result of repair action.
      */
     protected IgniteInternalFuture<Void> repairAsync(
         Collection<? extends K> keys,
@@ -5067,7 +5072,12 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
     }
 
     /**
-     * Checks and repairs entry across the topology.
+     * Checks the given {@code key} and repairs entry across the topology if needed.
+     *
+     * @param key Key.
+     * @param opCtx Operation context.
+     * @param skipVals Skip values flag.
+     * @return Recover future.
      */
     protected IgniteInternalFuture<Void> repairAsync(
         final K key,
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/consistency/GridNearReadRepairAbstractFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/consistency/GridNearReadRepairAbstractFuture.java
index 551f8eb..aba5b84 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/consistency/GridNearReadRepairAbstractFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/consistency/GridNearReadRepairAbstractFuture.java
@@ -90,7 +90,17 @@ public abstract class GridNearReadRepairAbstractFuture extends GridFutureAdapter
     private AffinityTopologyVersion topVer;
 
     /**
+     * Creates a new instance of GridNearReadRepairAbstractFuture.
      *
+     * @param topVer Topology version.
+     * @param ctx Cache context.
+     * @param keys Keys.
+     * @param readThrough Read-through flag.
+     * @param taskName Task name.
+     * @param deserializeBinary Deserialize binary flag.
+     * @param recovery Partition recovery flag.
+     * @param expiryPlc Expiry policy.
+     * @param tx Transaction. Can be {@code null} in case of atomic cache.
      */
     protected GridNearReadRepairAbstractFuture(
         AffinityTopologyVersion topVer,
@@ -117,7 +127,7 @@ public abstract class GridNearReadRepairAbstractFuture extends GridFutureAdapter
     }
 
     /**
-     *
+     * @param topVer Affinity topology version.
      */
     protected synchronized void map(AffinityTopologyVersion topVer) {
         this.topVer = topVer;
@@ -175,7 +185,9 @@ public abstract class GridNearReadRepairAbstractFuture extends GridFutureAdapter
     }
 
     /**
+     * Collects results of each 'get' future and prepares an overall result of the operation.
      *
+     * @param finished Future represents a result of GET operation.
      */
     protected synchronized void onResult(IgniteInternalFuture<Map<KeyCacheObject, EntryGetResult>> finished) {
         if (isDone() || /*remapping*/ topVer == null)
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/consistency/GridNearReadRepairCheckOnlyFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/consistency/GridNearReadRepairCheckOnlyFuture.java
index 0388e3f..e04ea27 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/consistency/GridNearReadRepairCheckOnlyFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/consistency/GridNearReadRepairCheckOnlyFuture.java
@@ -47,7 +47,19 @@ public class GridNearReadRepairCheckOnlyFuture extends GridNearReadRepairAbstrac
     private boolean keepCacheObjects;
 
     /**
+     * Creates a new instance of GridNearReadRepairCheckOnlyFuture.
      *
+     * @param ctx Cache context.
+     * @param keys Keys.
+     * @param readThrough Read-through flag.
+     * @param taskName Task name.
+     * @param deserializeBinary Deserialize binary flag.
+     * @param recovery Partition recovery flag.
+     * @param expiryPlc Expiry policy.
+     * @param skipVals Skip values flag.
+     * @param needVer Need version flag.
+     * @param keepCacheObjects Keep cache objects flag.
+     * @param tx Transaction. Can be {@code null} in case of atomic cache.
      */
     public GridNearReadRepairCheckOnlyFuture(
         GridCacheContext ctx,
@@ -103,7 +115,9 @@ public class GridNearReadRepairCheckOnlyFuture extends GridNearReadRepairAbstrac
     }
 
     /**
-     * Produces 1 entry's value.
+     * Returns a future represents 1 entry's value.
+     *
+     * @return Future represents 1 entry's value.
      */
     public <K, V> IgniteInternalFuture<V> single() {
         return chain((fut) -> {
@@ -142,7 +156,9 @@ public class GridNearReadRepairCheckOnlyFuture extends GridNearReadRepairAbstrac
     }
 
     /**
-     * Produces entry map.
+     * Returns a future represents entries map.
+     *
+     * @return Future represents entries map.
      */
     public <K, V> IgniteInternalFuture<Map<K, V>> multi() {
         return chain((fut) -> {
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/consistency/GridNearReadRepairFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/consistency/GridNearReadRepairFuture.java
index 35aae3c..f546fd7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/consistency/GridNearReadRepairFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/consistency/GridNearReadRepairFuture.java
@@ -41,7 +41,17 @@ import static org.apache.ignite.events.EventType.EVT_CONSISTENCY_VIOLATION;
  */
 public class GridNearReadRepairFuture extends GridNearReadRepairAbstractFuture {
     /**
+     * Creates a new instance of GridNearReadRepairFuture.
      *
+     * @param topVer Affinity topology version.
+     * @param ctx Cache context.
+     * @param keys Keys.
+     * @param readThrough Read-through flag.
+     * @param taskName Task name.
+     * @param deserializeBinary Deserialize binary flag.
+     * @param recovery Partition recovery flag.
+     * @param expiryPlc Expiry policy.
+     * @param tx Transaction.
      */
     public GridNearReadRepairFuture(
         AffinityTopologyVersion topVer,
@@ -157,7 +167,7 @@ public class GridNearReadRepairFuture extends GridNearReadRepairAbstractFuture {
             }
         }
 
-        evtMgr.record(new CacheConsistencyViolationEvent(
+        evtMgr.record(new CacheConsistencyViolationEvent<>(
             ctx.discovery().localNode(),
             "Consistency violation fixed.",
             originalMap,
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/consistency/AbstractReadRepairTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/consistency/AbstractReadRepairTest.java
index 30414ae..2ebcc00 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/consistency/AbstractReadRepairTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/consistency/AbstractReadRepairTest.java
@@ -158,7 +158,7 @@ public abstract class AbstractReadRepairTest extends GridCommonAbstractTest {
         while (!evtDeq.isEmpty()) {
             CacheConsistencyViolationEvent evt = evtDeq.remove();
 
-            fixed.putAll(evt.getFixedEntries()); // Optimistic and read commited transactions produce per key fixes.
+            fixed.putAll(evt.getRepairedEntries()); // Optimistic and read committed transactions produce per key fixes.
         }
 
         int misses = 0;