These days many businesses require the processing of extremely high numbers of transactional and reference data during peak times, like banks processing customer transactions during holidays. However, a big challenge is to process data without hampering your application’s performance. Generally, application tiers are linearly scalable, but databases are not. High transactional loads can result in a database bottleneck and affect your business.
You can resolve this bottleneck by introducing an in-memory distributed cache to your .NET application for faster data access. An in-memory distributed cache spans multiple servers, but works as a single cache instance and is totally transparent to the applications which are using it. This reduces the load from backend servers & databases as any active or transient data is served from the cache.
NCache is an open source in-memory distributed cache for both .NET and Java-based applications. NCache helps you in achieving extremely fast transactional speeds and data consistency as new servers can be added to this cache cluster to meet your growing performance needs.
The following figure illustrates this architecture:
Cached data is equally distributed between all servers and is even replicated to avoid data loss and ensure high availability. This allows the distributed cache to handle hundreds of thousands of requests per second, preventing downtime during peak loads.
This distributed structure ensures no single point of failure as if even one cache server is down, data is served from the other server nodes. Hence, your business will not get affected and can easily add more servers to the distributed cache if needed.
To achieve maximum performance of distributed caches, the data best-suited data for caching is read frequently but changed occasionally. Distributed caches store the data as key-value pairs, thus making it simple to use and access.
NCache Details Dynamic Clustering Caching Topologies
Using NCache as a Distributed Cache
You can easily incorporate a distributed cache in your .NET application by connecting to the cache and creating a key against your cache item which has been fetched from the database. You can then insert the item to the cache with the expiration of 30 minutes and fetch it using this connection.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // Specify the cache name to connect with it ICache cache = CacheManager.GetCache("demoCache"); // Get product from database var product = FetchProductFromDB(1001); // Generate a key for the cache item string key = "Product:1001"; // Create cache item and add 30sec sliding expiration var cacheItem = new CacheItem(product); cacheItem.Expiration = new Expiration(ExpirationType.Sliding, TimeSpan.FromMinutes(30)); // Now add this item in cache for future use cache.Insert(key, cacheItem); // Fetch item from cache product = cache.Get<Product>(key); |
Along with a dramatic performance boost to your .NET applications, distributed caches such as NCache provide multiple advanced features which make cache usage even more flexible in order to cater to different use cases and business needs. Here are a few highlighted features.
Sync Cache with Database
There might be a case where the database data (which has been cached) is changed. This raises an integrity issue rendering your cached data stale while your application is unaware of it. To solve this problem, NCache can auto-synchronize your cache with the database. Consequently, whenever any change occurs in the database for a cached record, it will be removed from the cache automatically to ensure data freshness.
NCache Details DB Synchronization NCache Docs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // Get connection string from application (app/web) config file string conString = ConfigurationManager.AppSettings["conString"]; // Create SQL query to select the data from database string query = "SELECT CustomerID, Address, City FROM dbo.Customers WHERE CustomerID = 'ALFKI';"; // Get orders against customerID from DB var order = FetchOrderByCustomerID("ALFKI"); // Generate unique cache key for the order string key = $"Order:{order.OrderID}"; // Create new CacheItem and add SQL dependency to it CacheItem item = new CacheItem(order); item.Dependency = new SqlCacheDependency(conString, query); // Add your data in cache with SQL dependency cache.Insert(key, item); |
SQL/LINQ Searching
Although NCache is a key-value store and provides a very rich set of APIs for data access using keys, it also provides SQL / LINQ based searching to fetch the data from the cache, just like you do with your database. It provides ADO.NET compliant APIs like ExecuteReader, ExecuteScalar, ExecuteNonQuery to search (SELECT) and remove (DELETE) data from the cache.
NCache Details SQL Search Docs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // Create SQL query to execute it on cache, by using FQN of your class string key = "SELECT * FROM Data.Product Where Category = ?"; var queryCommand = new QueryCommand(query); queryCommand.Parameters.Add("Category", “Electronics”); // Executing Query ICacheReader reader = cache.SearchService.ExecuteReader(queryCommand); while (reader.Read()) { // Use the retrieved attributes of the product ... } |
Concluding Thoughts
NCache not only provides performance and scalability but also many other useful features too. And yet, it hides its implementation related complexity to provide a straightforward way to use it. If you are looking for a .NET based distributed cache, without compromising on performance and scalability, then look no further than NCache. It is a pure .NET solution, with all the bells and whistles of modern distributed caching solutions.