If your application is heavily reliant on a database, caching is crucial to overcome the issues associated with databases, especially in high-traffic scenarios. For online applications that use caching to speed up data retrieval, implementing a strong data replication is key to maintaining consistency and availability.
Data replication is critical for creating backups of essential cache data across multiple servers, preserving data integrity, and guaranteeing high availability. Similarly, such synchronization mechanisms are vital in preventing any application process discrepancies. Therefore, you must do your best to create a comprehensive data replication strategy. Luckily, NCache realizes the importance of such replication and synchronization mechanisms and offers users a variety of options to choose from, as detailed in the blog below.
NCache Topologies
Several caching topologies supported by NCache (the Mirrored, Replicated, and Partition-Replica Topology, which are explained below) emphasize this ability.
- Mirror Topology: In a Mirrored topology, a cache cluster has two nodes, only one of the two nodes is active at a time while the other one acts as a passive node. Essentially, for all read and write operations in the Mirrored Cache topology, the client nodes only connect to the cluster’s active server node. If the active node fails, the passive node seamlessly takes over ensuring high availability without any issues.
- Replicated Topology: This topology replicates cache data across all server nodes in the cluster. Every node contains a complete copy of the cache, so even if multiple nodes fail, no data is lost.
- Partition-Replica Topology: The Partition-Replica Topology not only creates dynamic partitions available in the Partitioned Topology for scalability. It also creates 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 cache data from the replica node and distributes it as required.
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 availability, consistency, and fault tolerance. By maintaining identical copies of data in different locations, systems can enhance performance, and reduce latency, while safeguarding against potential data loss or server failures. Data replication is either synchronous or asynchronous, depending upon the topology used as discussed below.
- Synchronous Replication: With synchronous replication, NCache ensures data is concurrently written to the primary cache server and its replica(s). However, while this method is ideal for when high availability is your priority, there is a chance your application performance may suffer since any cache write operations must wait for confirmation from all the replicas.
- Asynchronous Replication: Alternatively, asynchronous replication updates replicas after writing data to the primary cache server. This method improves performance by allowing write operations to be completed without waiting for replica confirmation. However, 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 offers its own set of characteristics, but 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. However, replication has its issues, for instance, when the data size grows exponentially it becomes necessary to partition your data.
Fortunately, the Partition-Replica Topology strikes a balance between availability, redundancy, and performance by combining the advantages of the Partitioned and Replicated Cache topologies. You can select the technique that suits you best based on your requirements.
Data Consistency Mechanisms
Data consistency refers to the reliability and accuracy of information across the application stack regardless of any user operations. To ensure data consistency, NCache provides a Distributed Locking mechanism that allows you to lock specific cache items during updates. So, several users can work on various cache items concurrently without compromising their data integrity by applying locks at the component level. Therefore, cache locks are useful for managing shared resources in a distributed environment.
NCache provides you with two types of locking: Optimistic Locking (Cache Item Versions) and Pessimistic Locking (Exclusive Locking). The 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 and item version.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// An item is added in the cache with itemVersion // Specify the key of the cacheItem string key = "Product:1001"; // Initialize the cacheItemVersion CacheItemVersion version = null; // Get the cacheItem previously added in the cache with the version CacheItem cacheItem = cache.GetCacheItem(key, ref version); // If result is not null and version is valid if (cacheItem != null && version != null) { // CacheItem is retrieved successfully with the version // If result is of type Product var prod = cacheItem.GetValue<Product>(); prod.UnitsInStock++; else { // Item could not be retrieved; it might not exist or the version is outdated Console.WriteLine("Cache item could not be retrieved or version is invalid."); } |
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 on that item, knowing that no other application can access or modify it until the lock is released. 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<Product>(); // 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); |
Additional Mechanisms for Data Replication and Consistency
Now that we have learned about the data replication and consistency mechanisms provided by NCache, let’s explore other strategies you can employ for data consistency and data replication. For instance, NCache supports time-based data invalidation strategies to expire cache data. Data invalidation through Expiration means you can set a specific time duration for which the data remains in the cache, after which it expires. In this way, your cache will have fresh data on the next client request, therefore, eliminating stale data and ensuring data consistency. Moreover, 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 capable of handling even the most complex data needs. Why wait? Download NCache today and take your application performance to the next level!