C# 中的缓存:Redis、Memcached 及内置解决方案
缓存是现代 Web 应用程序性能优化的关键工具之一。在 C# (.NET) 生态系统中,开发者可以使用内置机制(IMemoryCache、IDistributedCache)以及强大的外部解决方案(Redis、Memcached)。本文将分析它们的特点,比较性能,并提供实用的代码示例。
1. .NET 内置解决方案:IMemoryCache 和 IDistributedCache
ASP.NET Core 提供了两个主要的缓存接口:IMemoryCache(单个进程内存中的本地缓存)和 IDistributedCache(分布式缓存的抽象)。
IMemoryCache
适用于单体应用或不需要在实例之间同步的微服务。缓存存储在服务器的 RAM 中。
// 在 Program.cs 中注册builder.Services.AddMemoryCache();
// 在服务中使用public class DataService{ private readonly IMemoryCache _cache;
public DataService(IMemoryCache cache) { _cache = cache; }
public async Task<string> GetExpensiveDataAsync(int id) { string cacheKey = $"data_{id}"; if (_cache.TryGetValue(cacheKey, out string cachedData)) { return cachedData; }
// 模拟耗时操作 await Task.Delay(500); string data = $"Result for {id}";
var options = new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromMinutes(10)) .SetSlidingExpiration(TimeSpan.FromMinutes(2));
_cache.Set(cacheKey, data, options); return data; }}IDistributedCache
一个抽象层,允许在不更改应用程序代码的情况下连接不同的后端(Redis、SQL Server、NCache)。通过 AddDistributedRedisCache 或 AddDistributedSqlServerCache 注册。
// Redis 示例builder.Services.AddStackExchangeRedisCache(options =>{ options.Configuration = "localhost:6379"; options.InstanceName = "SampleInstance";});
// 使用public class DistributedService{ private readonly IDistributedCache _cache;
public DistributedService(IDistributedCache cache) { _cache = cache; }
public async Task<string> GetDataAsync(string key) { var cached = await _cache.GetStringAsync(key); if (cached != null) return cached;
var data = $"Computed at {DateTime.Now}"; await _cache.SetStringAsync(key, data, new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5) }); return data; }}2. Redis:适用于 C# 的强大分布式缓存
Redis 是一个内存数据存储,支持复杂数据结构(列表、集合、哈希)。对于 .NET,使用 StackExchange.Redis 客户端或高级封装 Microsoft.Extensions.Caching.StackExchangeRedis。
Redis 在 C# 中的优势:
- 速度:亚毫秒级延迟(平均 0.5-1 毫秒)。
- Pub/Sub:可以通知其他服务缓存已更改。
- 持久性:数据可以保存到磁盘(RDB/AOF)。
- 集群:开箱即用的水平扩展。
使用 JSON 序列化的高级示例:
using StackExchange.Redis;using System.Text.Json;
public class RedisCacheService{ private readonly IDatabase _db; private readonly ConnectionMultiplexer _redis;
public RedisCacheService(string connectionString) { _redis = ConnectionMultiplexer.Connect(connectionStri