FusionCache核心方法详解:高效缓存管理实践
引言
在现代应用开发中,缓存是提升系统性能的关键组件。FusionCache作为一个功能强大的缓存解决方案,提供了简洁而强大的API来管理缓存数据。本文将深入解析FusionCache的六大核心方法,帮助开发者理解其工作原理和最佳实践。
核心方法概览
FusionCache提供了6个核心操作方法,每个方法都有同步和异步版本:
Set[Async]
- 设置缓存值GetOrSet[Async]
- 获取或设置缓存值GetOrDefault[Async]
- 获取缓存值或返回默认值TryGet[Async]
- 尝试获取缓存值Remove[Async]
- 移除缓存项Expire[Async]
- 使缓存项过期
这些方法都透明地工作在内存缓存和分布式缓存(如果配置了)两个层级上,开发者无需额外处理缓存层级间的协调。
方法详解
1. Set[Async]方法
Set
方法用于将指定键的值存入缓存,如果该键已存在,则覆盖原有值。
典型应用场景:
- 明确知道需要缓存什么值时
- 需要强制更新缓存时
示例代码:
// 使用默认选项设置缓存
cache.Set("user:123", userData);
// 指定缓存持续时间
cache.Set("product:456", productInfo, TimeSpan.FromMinutes(30));
2. GetOrSet[Async]方法
这是FusionCache中最强大且最常用的方法,它实现了"获取-否则设置"的模式。
工作流程:
- 尝试从缓存获取指定键的值
- 如果存在且未过期,直接返回
- 如果不存在或已过期,则:
- 使用提供的默认值设置缓存并返回,或
- 执行工厂方法获取值,设置缓存并返回
容错处理:
- 未启用Fail-Safe时,工厂方法执行失败会抛出异常
- 启用Fail-Safe时:
- 如果有过期(陈旧)数据可用,会使用它
- 否则使用指定的Fail-Safe默认值
示例代码:
// 基础用法:获取或设置默认值
var user = cache.GetOrSet("user:123", new User());
// 使用工厂方法从数据库获取
var product = cache.GetOrSet(
"product:456",
_ => FetchProductFromDatabase(456),
TimeSpan.FromHours(1)
);
// 启用Fail-Safe的高级用法
var stats = cache.GetOrSet(
"system:stats",
_ => CalculateSystemStats(),
new SystemStats(), // Fail-Safe默认值
options => options
.SetDuration(TimeSpan.FromMinutes(5))
.SetFailSafe(true, TimeSpan.FromHours(2), TimeSpan.FromSeconds(30))
);
3. GetOrDefault[Async]方法
此方法尝试获取缓存值,如果不存在则返回默认值,但不会修改缓存状态。
特点:
- 纯读取操作,不会写入缓存
- 适用于"有则用,无则算"的场景
- 无法区分"缓存中存的是默认值"和"缓存不存在返回默认值"的情况
示例代码:
// 获取用户偏好设置,不存在则返回false
var darkModeEnabled = cache.GetOrDefault<bool>("prefs:darkmode", false);
// 获取计数器值,不存在则返回0
var visitCount = cache.GetOrDefault<int>("stats:visits");
4. TryGet[Async]方法
此方法尝试获取缓存值,并通过MaybeValue<T>
类型返回结果状态和值。
与GetOrDefault的区别:
- 可以明确知道值是否存在缓存中
- 使用
MaybeValue<T>
包装结果,避免歧义
MaybeValue 特性 :
HasValue
属性指示是否存在值Value
属性获取实际值(不存在时抛出异常)GetValueOrDefault()
方法安全获取值- 支持与T类型的隐式转换
示例代码:
var maybeResult = cache.TryGet<AnalysisResult>("report:latest");
if (maybeResult.HasValue) {
// 使用缓存值
DisplayReport(maybeResult.Value);
} else {
// 生成新报告
var newReport = GenerateReport();
cache.Set("report:latest", newReport);
}
// 安全获取值
var cachedValue = maybeResult.GetValueOrDefault(defaultValue);
5. Remove[Async]方法
从缓存中完全移除指定键的项。
特点:
- 如果键不存在,不会执行任何操作
- 彻底删除,不留痕迹
示例代码:
// 用户注销时移除相关缓存
cache.Remove($"user:{userId}:profile");
6. Expire[Async]方法
使缓存项过期,但不完全移除。
与Remove的区别:
Remove
:彻底删除,无法恢复Expire
:标记为过期,但仍可作为备用
应用场景:
- 数据可能已过时,但紧急情况下仍可使用
- 配合Fail-Safe机制提供降级方案
示例代码:
// 设置缓存并启用Fail-Safe
cache.Set("config:features", featureFlags,
options => options
.SetDuration(TimeSpan.FromDays(1))
.SetFailSafe(true));
// 标记为过期(如收到配置变更通知)
cache.Expire("config:features");
// 普通读取获取不到
var features = cache.GetOrDefault<FeatureFlags>("config:features"); // 返回null/default
// 明确允许读取过期数据时可以获取
features = cache.GetOrDefault<FeatureFlags>("config:features",
options => options.SetAllowStaleOnReadOnly(true));
方法重载设计
FusionCache的方法提供了多种重载形式,便于不同场景使用:
- 无参数:使用默认选项(
DefaultEntryOptions
) - 直接选项对象:完全控制,但不继承默认选项
- 设置委托:基于默认选项的副本进行修改
- 持续时间:仅指定过期时间(最常见场景)
示例比较:
// 1. 无参数
cache.Set("key", value);
// 2. 直接选项对象
var options = new FusionCacheEntryOptions(TimeSpan.FromMinutes(30));
cache.Set("key", value, options);
// 3. 设置委托
cache.Set("key", value, opt => opt
.SetDuration(TimeSpan.FromMinutes(30))
.SetPriority(CacheItemPriority.High));
// 4. 仅持续时间
cache.Set("key", value, TimeSpan.FromMinutes(30));
设计哲学
FusionCache的API设计体现了几个重要原则:
- 明确性优于隐晦:如使用
GetOrDefault
而非简单的Get
,明确表达行为 - 安全默认值:避免因缓存缺失导致系统崩溃
- 灵活控制:提供细粒度的缓存行为控制
- 故障保护:内置Fail-Safe机制增强系统韧性
最佳实践建议
- 首选GetOrSet:大多数场景下这是最安全、最便捷的选择
- 合理设置过期时间:根据数据变更频率设置
- 启用Fail-Safe:提高系统可用性,特别是对关键数据
- 明确处理缓存缺失:使用TryGet当需要明确知道是否存在缓存
- 区分Remove和Expire:根据是否需要备用数据选择
总结
FusionCache提供了一套精心设计的缓存操作方法,既满足了常见需求,又为特殊场景提供了灵活性。理解这些核心方法的工作原理和适用场景,可以帮助开发者构建更健壮、高性能的应用程序。通过合理利用Fail-Safe、过期控制等高级特性,可以显著提升系统的稳定性和用户体验。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考