Skip to content
Go back

在 ASP.NET Core 中实现缓存:提升应用性能的实用指南

Published:  at  12:00 AM

在 ASP.NET Core 中实现缓存:提升应用性能的实用指南

缓存是一种极其高效的性能优化手段,它通过将数据临时存储在更快的访问位置,从而避免频繁的昂贵计算或数据库查询。ASP.NET Core 提供了多种缓存机制,方便我们在不同业务场景中灵活选择。

缓存如何提升性能

缓存的核心价值在于减少延迟、降低服务器负载,并提升用户体验。在一次实际项目中,仅通过引入 Redis 分布式缓存,我们就成功支撑了超过 100 万用户的访问量,而后台只运行了一台 SQL Server 主库和一个只读副本。缓存的威力可见一斑。

ASP.NET Core 缓存抽象

ASP.NET Core 提供了两大核心缓存接口:

注册方式非常简单:

builder.Services.AddMemoryCache();
builder.Services.AddDistributedMemoryCache();

IMemoryCache 为例,实现方式是先检查缓存中是否存在数据,如果不存在再从数据库获取并写入缓存:

app.MapGet("products/{id}", (int id, IMemoryCache cache, AppDbContext context) =>
{
    if (!cache.TryGetValue(id, out Product product))
    {
        product = context.Products.Find(id);
        var options = new MemoryCacheEntryOptions()
            .SetAbsoluteExpiration(TimeSpan.FromMinutes(10))
            .SetSlidingExpiration(TimeSpan.FromMinutes(2));
        cache.Set(id, product, options);
    }
    return Results.Ok(product);
});

通过 AbsoluteExpirationSlidingExpiration 我们可以精细控制缓存的有效期,防止数据陈旧。

Cache-Aside 模式

Cache-aside pattern

Cache-Aside(旁路缓存)是最常用的策略:先查缓存,未命中则查数据库并回填缓存。在分布式场景中,我们可以为 IDistributedCache 编写扩展方法,简化重复逻辑:

public static async Task<T> GetOrCreateAsync<T>(
    this IDistributedCache cache, string key, Func<Task<T>> factory,
    DistributedCacheEntryOptions? options = null)
{
    var cached = await cache.GetStringAsync(key);
    if (cached is not null)
        return JsonSerializer.Deserialize<T>(cached);

    var data = await factory();
    await cache.SetStringAsync(key, JsonSerializer.Serialize(data),
        options ?? new DistributedCacheEntryOptions
        {
            AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(2)
        });
    return data;
}

调用时只需一行:

var product = await cache.GetOrCreateAsync($"products-{id}",
    () => context.Products.FindAsync(id));

分布式缓存与 Redis 集成

在生产环境中,Redis 是最常用的分布式缓存。通过 Microsoft.Extensions.Caching.StackExchangeRedis 包,可以无缝将 IDistributedCache 接口绑定到 Redis。

builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = builder.Configuration.GetConnectionString("Redis");
});

或者使用 IConnectionMultiplexer 提升连接管理能力:

var mux = ConnectionMultiplexer.Connect(builder.Configuration.GetConnectionString("Redis"));
builder.Services.AddSingleton(mux);
builder.Services.AddStackExchangeRedisCache(options =>
{
    options.ConnectionMultiplexerFactory = () => Task.FromResult(mux);
});

缓存雪崩与并发控制

缓存雪崩(Cache Stampede)是在高并发下多请求同时未命中缓存、直击数据库的现象。ASP.NET Core 中可以利用 SemaphoreSlim 为同一 Key 加锁,避免重复查询。

private static readonly SemaphoreSlim Semaphore = new(1, 1);

await Semaphore.WaitAsync();
try
{
    // 双重检查后填充缓存
}
finally
{
    Semaphore.Release();
}

这种方式可进一步优化为“按 Key 粒度加锁”,减少全局锁竞争。

.NET 9 的 HybridCache

.NET 9 引入的 HybridCache 结合了内存缓存与分布式缓存的优点,旨在降低 IDistributedCache 的序列化开销并减少缓存击穿风险。它在本地维护一份副本,从而在分布式系统中依然能提供接近内存级的读取速度。

总结

ASP.NET Core 的缓存体系为性能优化提供了强大支持: IMemoryCache 适合单机、低延迟场景; IDistributedCache 与 Redis 则面向高可用、可扩展架构; .NET 9 的 HybridCache 则可能成为未来的首选方案。

合理选择缓存策略、控制失效时间、处理并发场景,才能让缓存真正为系统稳定性与性能加分。



Previous Post
Angular 20.2 引入 Native Animations:更轻量、更现代的动画方式
Next Post
Angular 20.2 稳定发布 Zoneless 模式,Signals 全面接管异步变更检测