Exploring Hybrid Caching in .NET 9.0
By FoxLearn 2/21/2025 8:19:53 AM 24
In this post, we’ll explore the concept of Hybrid Caching, its advantages, how to implement it, and best practices for using it effectively.
What is Hybrid Caching?
Hybrid Caching is a caching strategy that merges in-memory caching with distributed caching to optimize both performance and scalability. It utilizes the speed of in-memory caching while benefiting from the persistence and scalability offered by distributed systems such as Redis or SQL Server.
Benefits of Hybrid Caching
- Improved Performance: Frequently accessed data is stored in memory, reducing response time.
- Scalability: Ensures data consistency across multiple servers through distributed caching solutions.
- Enhanced Reliability: Built-in failover mechanisms prevent data loss during system failures.
- Cost Efficiency: Reduces the reliance on expensive database queries, maximizing resource utilization.
- Cache Stampede Prevention: Prevents multiple simultaneous database requests by managing cache misses effectively.
Understanding Cache Stampede
A cache stampede occurs when several concurrent requests miss the cache, resulting in each request querying the data source simultaneously, which can overwhelm the system.
How Hybrid Caching Prevents Cache Stampede
Hybrid Caching in .NET 9.0 helps alleviate cache stampedes with the following strategies:
- Locking Mechanisms: Ensures only one request retrieves the data from the source while others wait.
- Serving Stale Data: Provides slightly outdated data temporarily while fresh data is being fetched.
- Preemptive Refresh: Refreshes cache entries before they expire to minimize the chances of cache misses.
Implementing Hybrid Caching in .NET 9.0
You can implement Hybrid Caching in .NET 9.0 using the Microsoft.Extensions.Caching.Hybrid
package.
Below is a step-by-step guide on how to integrate it into your application:
Step 1: Install Necessary Packages
To get started, install the required NuGet packages:
Microsoft.Extensions.Caching.StackExchangeRedis
Microsoft.Extensions.Caching.Hybrid
Step 2: Configure the Caching Service
In the Program.cs
file, configure the Hybrid Caching service as follows:
using HybridCachingDemo; using Microsoft.Extensions.Caching.Hybrid; using Scalar.AspNetCore; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddOpenApi(); builder.Services.AddSingleton<HybridCacheService>(); builder.Services.AddStackExchangeRedisCache(options => { options.Configuration = "your-redis-connection-string"; options.InstanceName = "HybridCache"; }); builder.Services.AddHybridCache(options => { options.MaximumPayloadBytes = 1024 * 1024 * 10; // 10MB options.MaximumKeyLength = 512; options.DefaultEntryOptions = new HybridCacheEntryOptions { Expiration = TimeSpan.FromMinutes(30), LocalCacheExpiration = TimeSpan.FromMinutes(30) }; }); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.MapOpenApi(); app.MapScalarApiReference(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
Step 3: Implement Hybrid Caching Logic
Create the HybridCacheService
class to handle caching logic:
using Microsoft.Extensions.Caching.Hybrid; namespace HybridCachingDemo { public class HybridCacheService { private readonly HybridCache _hybridCache; private readonly TimeSpan _cacheDuration = TimeSpan.FromMinutes(30); public HybridCacheService(HybridCache hybridCache) { _hybridCache = hybridCache; } public async Task<string> GetCachedDataAsync(string key, CancellationToken ct) { var product = await _hybridCache.GetOrCreateAsync( $"product-{key}", async token => await FetchData(key, token), cancellationToken: ct ); return product; } private async Task<string> FetchData(string key, CancellationToken ct) { await Task.Delay(5000, ct); // Simulate long-running operation return $"Product {key}"; } } }
Step 4: Inject and Use the HybridCacheService
Register the HybridCacheService
in Program.cs
:
builder.Services.AddSingleton<HybridCacheService>();
Then, use it in your controller:
using Microsoft.AspNetCore.Mvc; namespace HybridCachingDemo.Controllers { [Route("api/[controller]")] [ApiController] public class DataController : ControllerBase { private readonly HybridCacheService _hybridCacheService; public DataController(HybridCacheService hybridCacheService) { _hybridCacheService = hybridCacheService; } [HttpGet("get-data")] public async Task<IActionResult> Get(CancellationToken ct) { var data = await _hybridCacheService.GetCachedDataAsync("test", ct); return Ok(data); } } }
Step 5: Run the Application
Now, execute the application to observe the benefits of Hybrid Caching in action.
Best Practices for Effective Hybrid Caching
- Cache Expiration Policy: Set appropriate expiration times to avoid serving outdated data.
- Eviction Strategy: Use strategies like Least Recently Used (LRU) for effective cache management.
- Consistency Management: Ensure synchronization between in-memory and distributed caches.
- Performance Monitoring: Utilize logging to monitor cache hits and misses and improve performance.
- Cache Stampede Prevention: Implement locking and proactive cache refreshing techniques.
Redis as Level 2 (L2) Cache in Hybrid Caching
In a hybrid caching setup, Redis is typically used as the Level 2 (L2) cache. Here’s how the data flow works:
- L1 Cache (Local Cache): The application first checks the local cache (like
MemoryCache
). If the data is found, it is returned. - L2 Cache (Redis): If the data isn’t in the local cache, Redis is queried. If found, it’s cached in both L1 and L2 for future access.
- Database Fallback: If data is missing in both caches, the database is queried, and the data is cached in both caches for subsequent requests.
Hybrid Caching in .NET 9.0 offers an efficient way to boost application performance by combining the benefits of both in-memory and distributed caching. With the Microsoft.Extensions.Caching.Hybrid
package, developers can easily achieve faster response times, improved scalability, and enhanced system resilience.
By following best practices such as proper cache expiration, eviction strategies, and cache stampede prevention, you can implement a highly effective caching system in your .NET applications.
- Using the OrderBy and OrderByDescending in LINQ
- Querying with LINQ
- Optimizing Performance with Compiled Queries in LINQ
- MinBy() and MaxBy() Extension Methods in .NET
- SortBy, FilterBy, and CombineBy in NET 9
- Using Entity Framework with IDbContext in .NET 9.0
- Primitive types in C#
- Connection string password with special characters in C#