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;