在面向高并发的企业级应用中,不合理的缓存设计往往是系统雪崩的催化剂:
- 直连 Redis 导致网络瓶颈:每次读操作都跨网络发起 Redis 调用,高 QPS 下网卡打满、连接池枯竭;
- 缓存击穿与雪崩(Cache Stampede):热点 Key 一旦过期,成千上万个并发请求同时打向数据库,瞬间引发数据库 CPU 100% 锁死;
- 跨租户脏读(Data Leakage):Key 命名随意,没有强类型租户与环境前缀,导致 A 租户读到了 B 租户的敏感数据!
BitzOrcas.Modern 采用基于 FusionCache 的 L1(进程内内存)+ L2(分布式 Redis)多级缓存架构,并通过强类型 ICacheKeyBuilder 与 ICacheStore 为全平台提供了工业级的缓存保护。
多级缓存读写与失效全景
第一步:使用 ICacheKeyBuilder 构造防越权缓存键
BitzOrcas 严禁手写拼接 Redis 字符串 Key。所有 Key 必须通过 ICacheKeyBuilder 构造,框架会自动追加 {app}:{env}:v{version}:{area}:{scope}:{parts}:
using BitzOrcas.Application.Abstractions.Caching;
public sealed class CatalogOfferingCacheService( ICacheKeyBuilder cacheKeys, ICacheStore cache){ public async Task<OfferingView?> GetOfferingAsync(string offeringId, CancellationToken ct) { // ① 显式指定租户作用域,框架自动从 ICurrentUserAccessor 注入 TenantId var key = cacheKeys.Build( area: "catalog-offering", scope: CacheScope.Tenant, version: 1, offeringId);
// ② 配置缓存策略:10 分钟正常过期,20 秒负缓存,启用 10% 随机抖动防雪崩 var policy = new CachePolicy(TimeSpan.FromMinutes(10)) { NegativeTtl = TimeSpan.FromSeconds(20), JitterRatio = 0.10, AreaTag = "catalog", Tags = [$"offering:{offeringId}"] };
// ③ 读穿模式:自动执行单飞回源(Single-Flight),拦截并发击穿 var result = await cache.GetOrCreateAsync( key, async token => await LoadFromDbAsync(offeringId, token), policy, ct);
return result.Value; }
private Task<OfferingView?> LoadFromDbAsync(string id, CancellationToken ct) => Task.FromResult<OfferingView?>(null);}第二步:三态读取与负缓存(Negative Caching)防御
针对恶意扫描或不存在的资源查询,如果数据库返回 null 就放弃缓存,会导致高频穿透。BitzOrcas 支持标准的三态结果(Hit / Negative / Miss):
var cached = await cache.TryGetAsync<OfferingView>(key, cancellationToken);
if (cached.HasValue){ // 1. 正常命中有效数据 return Result<OfferingView>.Success(cached.Value!);}
if (cached.IsNegative){ // 2. 命中负缓存(该资源已被确认为不存在,直接短路返回 404) return Result<OfferingView>.Failure(OfferingErrors.NotFound);}
// 3. 真正未命中(Miss)时才允许回源数据库return await LoadFromDbAndPopulateAsync(offeringId, cancellationToken);第三步:事务提交后精准标签失效(Tag Invalidation)
当商品数据发生变更时,严禁在事务未提交前清空缓存(否则事务若回滚,缓存已被污染)。标准模式是:事务成功提交 -> 调用 RemoveByTagAsync 广播失效:
public async ValueTask<Result> Handle(UpdateOfferingCommand command, CancellationToken ct){ // 1. 保存聚合变更(TransactionPipeline 自动提交事务) var saveResult = await repository.SaveAsync(offering, ct); if (saveResult.IsFailure) return saveResult;
// 2. 事务成功后,按 Tag 批量广播失效当前商品的所有多维度缓存 await cache.RemoveByTagAsync($"offering:{command.Id}", ct);
return Result.Success();}总结
BitzOrcas 的多级缓存机制实现了极速与可靠的平衡:
- L1 内存零延迟:高频数据纳秒级直出;
- 并发单飞锁:彻底杜绝热点 Key 击穿数据库;
- 严格租户隔离:强类型 KeyBuilder 防止跨租户数据串流。