If your application relies heavily on data and frequently interacts with a database, caching becomes crucial to mitigate any associated costs. Online applications that use caching to speed up data retrieval, implementing strong data replication and consistency is a must.
Data replication is critical for creating backup of critical data across multiple servers, ensuring accurate and accessible information. Similarly, such consistency mechanisms are vital when synchronizing these distributed copies seamlessly, preventing any discrepancies in the application process. Therefore, to guarantee that your application interacts with accurate and up-to-date data, you must employ these features for backups, high availability, and data consistency.
Luckily, NCache provides a reliable set of replication and synchronization mechanisms for just such distributed systems. This blog details how NCache fulfills these conditions.
NCache Topologies
The caching topologies supported by NCache include the Mirrored Topology, Replicated Topology, Partition and Partition-Replica Topology, and Client Cache Topology.
- Mirror Topology: For all read and write operations in the Mirrored Cache topology, the client nodes only connect to the cluster’s active server node. The client applications immediately establish a connection with the previously passive node if the active server node goes down.
- Replicated Topology: The Replicated Topology ensures that if multiple servers fail at the same time, data is not lost as each server has the same copy of data.
- Partition Topology: By connecting all client applications to cache servers, the Partition Topology offers high data availability by dividing data into chunks – therefore, connecting all the client applications to the cache servers. In this way, the application gets the required data even if the connected server goes down, by requesting the other servers.
- Partition-Replica Topology: The Partition-Replica Topology not only creates dynamic partitions, but also dynamic replicas of these partitions on other server nodes, which act as a backup in the event of a connection failure or node failure. In these situations, NCache obtains data from the replica node and distributes it.
- Client Cache Topology: In the Client Cache Topology, the cache resides very close to your application and lets you quickly cache the data from the distributed cache.
Learn more about topologies in the blog: Scaling Out and Staying Up: Exploring Topologies in NCache.
Data Replication in NCache
The primary goal of data replication is to ensure data consistency, availability, and fault tolerance. By maintaining identical copies of data in different locations, systems can enhance performance, reduce latency, and safeguard against potential data loss or server failures.
It is either synchronous or asynchronous, depending upon the topology used. In synchronous replication, NCache ensures data is concurrently written to the primary cache server and its replica(s). However, strong data consistency is ensured by this method, but performance may suffer, since any cache write operations must wait for confirmation from all the replicas.
Alternatively, asynchronous replication updates replicas after writing data to the primary cache server. Since these caches write operations don’t wait for replica confirmation, this strategy offers greater performance gains. Although this strategy may result in temporary data inconsistencies between the replicas and the primary cache server.
Topologies for Synchronous & Asynchronous Data Replication
Each of the topologies discussed offer their own set of characteristics, not all of them cater to data replication. For instance, synchronized replication, employed in the Mirrored Cache Topology, guarantees data consistency by simultaneously writing to the primary and replica nodes. On the other hand, by writing to primary nodes first and updating replicas later, asynchronous replication, used in the Replicated Cache Topology, improves efficiency but may occasionally result in errors.
Fortunately, the Partition-Replica Topology strikes a balance between redundancy, availability, and performance by combining the advantages of the Partitioned and Replicated Cache topologies. Users can select the best technique based on their requirements.
Data Consistency Mechanisms
Data consistency refers to the reliability and accuracy of information across a system or database, ensuring that data remains accurate and reliable throughout various operations. To ensure data consistency, NCache provides a mechanism of Distributed Locking that allows you to lock specific cache items during concurrent updates. Several users can work on various cache items concurrently without compromising data integrity by applying locks. Therefore, cache locks are useful for managing shared resources in a distributed environment.
To maintain data consistency, NCache acts as a distributed lock manager and provides you with two types of locking: Optimistic Locking (Cache Item Versions) and Pessimistic Locking (Exclusive Locking). Optimistic Locking uses Cache Item Versioning. In this type of locking, the Add method adds a new item in the cache and saves the item version for the first time, while the insert method overwrites the value of an existing item and updates its item version. The following example creates a LockHandle and then locks an item with the key Product:1001 for a time interval of 10 seconds, so that the item will be unlocked automatically after 10 seconds.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// Prerequisite: Cache is already connected // Item is already added in the cache // Specify the key of the item string key = $"Product:1001"; // Create a new LockHandle LockHandle lockHandle = null; // Specify time span of 10 seconds for which the item remains locked TimeSpan lockSpan = TimeSpan.FromSeconds(10); // Lock the item for a time span of 10 seconds bool lockAcquired = cache.Lock(key, lockSpan, out lockHandle); // Verify if the item is locked successfully if (lockAcquired == true) { // Item has been successfully locked } else { // Key does not exist // Item is already locked with a different LockHandle } |
Alternatively, Pessimistic Locking locks the item using the Lock Handle, blocking all other users from performing any write operation on that cache item. Upon successfully acquiring the lock while fetching the item, the application can now safely perform operations, knowing that no other application can get or update this item as long as you have this lock. The following example locks an item in the cache and then gets the item using the lockHandle. The item is then updated and then reinserted in the cache using the Insert API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// Specify the key of the item string key = $"Product:1001"; // Set acquireLock flag as true bool acquireLock = true; // Specify time span of 10 seconds for which the item remains locked TimeSpan lockSpan = new TimeSpan(0, 0, 10); // Initialize the lockHandle LockHandle lockHandle = null; CacheItem item = cache.GetCacheItem(key, acquireLock, lockSpan, ref lockHandle); var product = new Product(); product = item.GetValue(); // Update the unitsinstock for the product product.UnitsInStock = 200; bool releaseLock = true; // Item is already locked with a LockHandle // Update the item and release the lock as well since releaseLock is set true // Make sure that the LockHandle matches with the already added LockHandle cache.Insert(key, item, null, lockHandle, releaseLock); |
Best Practices for Data Replication and Consistency
Now that we have learned about the data replication and consistency mechanisms provided by NCache, let’s explore the recommended practices in this context. The Replicated Topology is the best choice for an application that needs high availability and can survive (n-1) nodes failure without any data loss. Whereas, the Partition-Replica Topology provides both high availability and the capacity to satisfy expanding data needs.
While it is not as highly available as the Replicated Topology, it can still withstand node failure without any data loss. Each partition has a backup; thus, each node essentially has a partition and a backup of another partition. On the other hand, the Mirrored Topology offers data reliability and availability through asynchronous replication from the Active Node to Passive Node.
NCache also supports time-based data invalidation strategies to expire cache data. Data invalidation through Expiration means you can specify the time duration during which the data remains in the cache, after which it expires. In this way, your cache will have the fresh data on the next client request, therefore, eliminating stale data – ensuring data consistency. Invalidation through Dependencies ensures that the cache data is removed whenever changes occur in the database.
Conclusion
Data replication and consistency are the backbone of a reliable and high-performance application. Fortunately, with NCache, you have access to robust features that enable you to create highly scalable, fault-tolerant applications that can handle even the most complex data needs.