ASP.NET Core is popular for developing web applications due to its streamlined and lightweight architecture, as well as its cross-platform capabilities. These applications often experience high traffic and are typically deployed in load-balanced, multi-server environments. As their transaction loads grow, additional servers can be added to effortlessly manage such heavy traffic. However, despite the boost in scalability, your database can still become a bottleneck, potentially slowing down your ASP.NET Core application.
This performance bottleneck occurs due to the databases’ inability to handle heavy loads as effectively as application tier can. Essentially, you can add more servers to the application tier but cannot do the same with your database tier. Below are the two types of data storage that become a performance bottleneck in these applications.
-
- Database Server (SQL Server)
- ASP.NET Core Sessions
The Solution: Distributed Cache
To remove these performance bottlenecks, your best bet is to use a distributed cache like NCache. NCache is a .NET-based, in-memory distributed cache that is much faster than the database. Unlike your database, NCache is linearly scalable as it lets you create a cache cluster and scale it as your transaction loads increase.
Moreover, NCache allows you to cache application data, significantly reducing costly database trips by up to 80%. This approach reduces the database load, enabling it to perform more efficient reads/writes, and preventing it from becoming a performance bottleneck.
NCache also acts as a scalable distributed store for your ASP.NET Core sessions. It replicates your sessions to multiple servers to prevent data loss in case any cache server goes down. Below is a diagram demonstrating how a distributed cache like NCache fits into your application stack.
Application Data Caching through ASP.NET Core IDistributedCache
Before the introduction of ASP.NET Core, ASP.NET offered a stand-alone ASP.NET Cache that was not suitable for multi-server environments. Therefore, ASP.NET Core offers the IDistributedCache interface, a basic distributed caching API that allows developers to write code against a standardized interface and easily integrate third-party distributed caching solutions.
Here is an example of how to use the IDistributedCache interface:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
IDistributedCache _cache; private byte[] LoadCustomer(string custId) { string key = "Customers:CustomerID:" + custId; // Is the customer in the cache? byte[] customer = _cache.Get(key); if (customer == null) { // The cache doesn't have it, so load from DB customer = LoadFromDB(key); // And, cache it for next time _cache.Set(key, customer); } return customer; } |
NCache also provides an implementation for the IDistributedCache interface, that you can easily integrate into your applications. This way, you don’t have to modify any code specific to NCache. Here is what the IDistributedCache interface looks like (please note that these methods also have an Async overload).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
namespace Microsoft.Extensions.Caching.Distributed { public interface IDistributedCache { // Each of these methods also has an “Async” overload byte[] Get(string key); void Refresh(string key); void Remove(string key); // Specify absolute & sliding expiration through options void Set(string key, byte[] value, DistributedCacheEntryOptions options); } } |
Configuring NCache as IDistributedCache Provider
The following code snippet will help you to configure NCache as your IDistributedCache provider in your application’s Startup class.
1 2 3 4 5 6 7 8 9 10 11 |
public class Startup { ... public void ConfigureServices (IServiceCollection services) { ... services.AddNCacheDistributedCache(); ... } ... } |
Why Choose NCache API Over IDistributedCache?
If your caching needs are fairly basic and you require the flexibility of changing the distributed caching platforms seamlessly, then IDistributedCache interface would be the perfect choice for you. As it lets you change your caching vendor seamlessly. But weigh that against the cost of not having the option to employ numerous other valuable features.
Alternatively, you can use the NCache API within your Core application. The NCache API is very similar to the legacy ASP.NET Cache API, simplifying the transition. Remember, the more data you cache, the greater the performance and scalability benefits for your application. However, relying solely on the IDistributedCache provider often restricts you to caching read-only or data, meaning you miss out on NCache’s powerful advanced caching features. Explore the full range of caching capabilities that NCache offers beyond the IDistributedCache provider.
Storing ASP.NET Core Sessions in Distributed Cache
Before ASP.NET Core, ASP.NET offered a Session State Provider framework that allowed third-party session storage providers to integrate. ASP.NET Core continues this approach with a similar mechanism for third-party session storage providers. Below are two ways to use NCache as session storage provider in Core applications.
Use NCache for ASP.NET Core Sessions thru IDistributedCache
Once NCache is configured as IDistributedCache provider for your Core application. It automatically becomes the default storage option for ASP.NET Core sessions with no further changes. But please note that this implementation offers a limited feature set as compared to the older ASP.NET Session State.
Here are some of the things the default ASP.NET Core Sessions implementation lacks:
- No session locking is provided in ASP.NET Core. This is something even older ASP.NET Session State had provided.
- Byte [] array for custom objects: ASP.NET Core forces you to convert all your custom objects into a byte array before you can store it in the session. Even older ASP.NET Session State supports custom objects.
Use NCache as ASP.NET Core Sessions Provider
To work around the default ASP.NET Core Sessions implementation through IDistributedCache
provider, NCache has implemented its own ASP.NET Core Sessions provider. This implementation has a lot more features than the default one.
The following code lines will help you configure it in your Startup
class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class Startup { // Other methods and properties public void ConfigureServices(IServiceCollection services) { // Configure other services services.AddNCacheDistributedCache(); // Additional service configurations } // Other methods and properties } |
You can specify the Core Session configurations for the above in appsettings.json
file as following:
1 2 3 4 5 6 7 8 9 10 11 |
{ ... "NCacheSessions": { "CacheName": "demoCache", "EnableLogs": "True", "RequestTimeout": "90", "EnableDetailLogs": "False", "ExceptionsEnabled": "True", "WriteExceptionsToEventLog": "False"} ... } |
Conclusion
In conclusion, while ASP.NET Core applications can scale effortlessly with additional servers, database and session management often become performance bottlenecks. NCache addresses these challenges by providing a fast, in-memory distributed cache that reduces database load and enhances application performance. As a native .NET solution, NCache integrates seamlessly with Core applications and offers advanced features that outperform other options like SQL Server and Redis. By using NCache for data and session caching, you can significantly improve the scalability and responsiveness of your ASP.NET Core applications.