BigMemory 4.4.0 | Product Documentation | BigMemory Max Configuration Guide | Defining a Distributed Configuration | Consistency Modes
 
Consistency Modes
Cache consistency modes are configuration settings and API methods that control the behavior of clustered caches with respect to balancing data consistency and application performance. A cache can be in one of the following consistency modes:
*Strong – This mode ensures that data in the cache remains consistent across the cluster at all times. It guarantees that a read gets an updated value only after all write operations to that value are completed, and that each put operation is in a separate transaction. The use of locking and transaction acknowledgments maximizes consistency at a potentially substantial cost in performance. This mode is set using the Ehcache configuration file and cannot be changed programmatically (see the consistency attribute in <terracotta> element).
*Eventual – This mode guarantees that data in the cache will eventually be consistent. Read/write performance is substantially boosted at the cost of potentially having an inconsistent cache for brief periods of time. This mode is set using the Ehcache configuration file and cannot be changed programmatically (see the consistency attribute in <terracotta> element).
To optimize consistency and performance, consider using eventually consistent caches while selectively using appropriate locking in your application where cluster-wide consistency is critical at all times. Eventual cache operations that are explicitly locked become strongly consistent with respect to each other (but not with respect to non locked operations). For example, a reservation system could be designed with an eventual cache that is only explicitly locked when a customer starts to make a reservation; with this design, eventually consistent data would be available during a customer's search, but during the reservation process, reads and writes would be strongly consistent.
*Bulk Load – This mode is optimized for bulk-loading data into the cache without the slowness introduced by locks or regular eviction. It is similar to the eventual mode, but has batching, higher write speeds, and weaker consistency guarantees. This mode is set using the bulk-load API only. For information, see "Bulk Loading" in the Developer Guide for BigMemory Max. When turned off, allows the configured consistency mode (either strong or eventual) to take effect again.
Use configuration to set the permanent consistency mode for a cache as required for your application, and the bulk-load mode only during the time when populating (warming) or refreshing the cache.
APIs Related to Consistency
The following APIs and settings also affect consistency:
*Explicit Locking – This API provides methods for cluster-wide (application-level) locking on specific elements in a cache. There is guaranteed consistency across the cluster at all times for operations on elements covered by a lock. When used with the strong consistency mode in a cache, each cache operation is committed in a single transaction. When used with the eventual consistency mode in a cache, all cache operations covered by an explicit lock are committed in a single transaction. While explicit locking of elements provides fine-grained locking, there is still the potential for contention, blocked threads, and increased performance overhead from managing clustered locks. For information, see "Explicit Locking" in the Developer Guide for BigMemory Max.
*Bulk-loading methods – Bulk-loading Cache methods putAll(), getAll(), and removeAll() provide high-performance and eventual consistency. These can also be used with strong consistency. If you can use them, it's unnecessary to use bulk-load mode.
*Atomic methods – To guarantee write consistency at all times and avoid potential race conditions for put operations, use atomic methods. The following Compare and Swap (CAS) operations are available:
*cache.replace(Element old, Element new) — Conditionally replaces the specified key's old value with the new value, if the currently existing value matches the old value.
*cache.replace(Element) — Maps the specified key to the specified value, if the key is currently mapped to some value.
*cache.putIfAbsent(Element) — Puts the specified key/value pair into the cache only if the key has no currently assigned value. Unlike put, which can replace an existing key/value pair, putIfAbsent creates the key/value pair only if it is not present in the cache.
*cache.removeElement(Element) — Conditionally removes the specified key, if it is mapped to the specified value.
Normally, these methods are used with strong consistency. Unless the property org.terracotta.clusteredStore.eventual.cas.enabled is set to "true", these methods throw an UnsupportedOperationException if used with eventual consistency since a race condition cannot be prevented. Other ways to guarantee the return value in eventual consistency are to use the cache decorator StronglyConsistentCacheAccessor, or to use explicit locking. The StronglyConsistentCacheAccessor will use locks with its special substituted versions of the atomic methods. Note that using locks may impact performance. For information about cache decorators and explicit locking, see "Cache Decorators" and "Explicit Locking" in the Developer Guide for BigMemory Max.