登录社区云,与社区用户共同成长
邀请您加入社区
缓存的本质是利用时间局部性(Temporal Locality)和空间局部性(Spatial Locality)原理,将频繁访问的数据存储在更快的存储介质中。本文将深入探讨C#环境下多级缓存的架构设计与实现,重点分析内存缓存(Memory Cache)与Redis分布式缓存的协同工作机制,并详细阐述如何通过Redis的发布-订阅(Pub/Sub)模式实现不同节点间的缓存状态同步。// 简化的大小计
樟刨鹊稍引言
在现代分布式应用架构中,缓存已成为提升系统性能和用户体验的关键技术组件。随着业务规模的不断扩大和并发量的持续增长,单一级别的缓存往往无法满足复杂的性能需求。多级缓存架构通过在不同层次构建缓存体系,能够显著提升数据访问效率,降低数据库负载,并提供更好的系统可扩展性。
本文将深入探讨C#环境下多级缓存的架构设计与实现,重点分析内存缓存(Memory Cache)与Redis分布式缓存的协同工作机制,并详细阐述如何通过Redis的发布-订阅(Pub/Sub)模式实现不同节点间的缓存状态同步。
1. 多级缓存理论基础
1.1 缓存层次结构理论
缓存的本质是利用时间局部性(Temporal Locality)和空间局部性(Spatial Locality)原理,将频繁访问的数据存储在更快的存储介质中。在计算机系统中,从CPU缓存到内存,从内存到磁盘,都遵循着这种层次化的存储架构。
1.1.1 缓存访问模式
CPU Cache (L1/L2/L3) → Memory → Disk Storage
↑ ↑ ↑
快速访问 中等速度 慢速访问
小容量 中等容量 大容量
昂贵 适中 便宜
在应用层面,多级缓存同样遵循类似的原理:
L1缓存(进程内存缓存): 访问速度最快,容量相对较小,仅在当前进程内有效
L2缓存(分布式缓存): 访问速度中等,容量较大,在多个节点间共享
L3缓存(数据库查询缓存): 访问速度最慢,但提供持久化存储
1.2 缓存一致性理论
1.2.1 CAP定理在缓存系统中的应用
根据CAP定理(Consistency, Availability, Partition tolerance),在分布式缓存系统中,我们无法同时保证:
一致性(Consistency): 所有节点在同一时间具有相同的数据
可用性(Availability): 系统持续可用,即使某些节点出现故障
分区容错性(Partition Tolerance): 系统能够容忍网络分区故障
在实际应用中,我们通常采用最终一致性(Eventually Consistency)模型,通过合理的同步策略和过期机制来平衡性能与一致性。
1.2.2 缓存穿透、击穿、雪崩问题
缓存穿透(Cache Penetration):
现象:查询不存在的数据,绕过缓存直接访问数据库
解决方案:布隆过滤器、空值缓存
缓存击穿(Cache Breakdown):
现象:热点数据过期时,大量并发请求同时访问数据库
解决方案:分布式锁、热点数据永不过期
缓存雪崩(Cache Avalanche):
现象:大量缓存同时失效,导致数据库压力骤增
解决方案:过期时间随机化、多级缓存、熔断机制
2. 架构设计与技术选型
2.0 系统架构流程图
2.0.1 多级缓存整体架构
数据层
多级缓存系统
监控系统
同步机制
缓存层
应用层
L2缓存 - Redis分布式缓存
L1缓存 - 内存缓存
客户端应用
Controller层
Service层
多级缓存管理器
IMemoryCache
高级内存缓存
Redis连接管理器
Redis分布式缓存
Redis集群
Redis Pub/Sub
缓存同步服务
事件队列
监控服务
健康检查
性能指标
数据库
外部API
2.0.2 缓存操作流程图
同步服务
L2 Redis缓存
L1内存缓存
客户端
读取操作流程 (GetOrSet)
par
[并行设置缓存]
[发布同步事件]
alt
[L2 缓存命中]
[L2 缓存未命中]
[L1 缓存命中]
[L1 缓存未命中]
更新操作流程
[并行更新所有级别]
删除操作流程
[并行删除所有级别]
GetOrSet(key, factory)
Get(key)
返回数据
返回结果 (L1 Hit)
返回 null
Set(key, data) [异步提升]
返回结果 (L2 Hit)
factory() 执行
返回原始数据
Set(key, data)
PublishSync(SET, key)
返回结果 (DB Hit)
通知其他节点更新L1缓存
返回结果
Remove(key)
PublishSync(REMOVE, key)
通知其他节点删除L1缓存
2.0.3 Redis发布-订阅同步机制
节点C
节点B
节点A
Unsupported markdown: list
应用A
L1缓存A
L2缓存A
同步服务A
应用B
L1缓存B
L2缓存B
同步服务B
应用C
L1缓存C
L2缓存C
同步服务C
Redis Pub/Sub频道
cache_sync:events
2.0.4 缓存降级策略流程
是
否
L1Only
DirectAccess
ThrowException
开始缓存操作
L1缓存
是否可用?
尝试L1缓存操作
L1操作
成功?
返回L1结果
L2缓存
尝试L2缓存操作
L2操作
返回L2结果
降级策略
仅使用L1缓存
直接访问数据库
抛出异常
尝试L1操作
执行数据库查询
返回数据库结果
返回错误
结束
2.1 整体架构设计
多级缓存架构采用分层设计模式,每一层都有明确的职责和边界:
┌─────────────────────────────────────────────────────┐
│ 应用层 │
├─────────────────────────────────────────────────────┤
│ 多级缓存管理器 │
├─────────────────┬───────────────────────────────────┤
│ L1内存缓存 │ L2 Redis缓存 │
│ (MemoryCache) │ (StackExchange.Redis) │
├─────────────────┴───────────────────────────────────┤
│ Redis Pub/Sub 同步机制 │
│ 数据持久层 │
└─────────────────────────────────────────────────────┘
2.2 技术选型分析
2.2.1 内存缓存选型
Microsoft.Extensions.Caching.Memory:
优势:.NET官方支持,与DI容器无缝集成,支持过期策略和内存压力驱逐
适用场景:单体应用、微服务单实例缓存
特性:线程安全、支持泛型、内置压缩和序列化
System.Runtime.Caching.MemoryCache:
优势:.NET Framework传统方案,功能成熟
劣势:不支持.NET Core,API相对古老
2.2.2 分布式缓存选型
StackExchange.Redis:
优势:高性能、功能全面、支持集群、活跃的社区支持
特性:异步操作、连接复用、故障转移、Lua脚本支持
版本选择:推荐使用2.6+版本,支持.NET 6+的新特性
ServiceStack.Redis:
优势:易用性好,文档完善
劣势:商业许可限制,性能相对较低
2.3 架构模式选择
2.3.1 Cache-Aside Pattern(缓存旁路模式)
这是最常用的缓存模式,应用程序负责管理缓存的读取和更新:
读取流程:
1. 应用程序尝试从缓存读取数据
2. 如果缓存命中,直接返回数据
3. 如果缓存未命中,从数据库读取数据
4. 将数据写入缓存,然后返回给应用程序
更新流程:
1. 更新数据库
2. 删除或更新缓存中的对应数据
2.3.2 Write-Through Pattern(写透模式)
写入流程:
1. 应用程序写入缓存
2. 缓存服务同步写入数据库
3. 确认写入完成后返回成功
2.3.3 Write-Behind Pattern(写回模式)
2. 立即返回成功
3. 缓存服务异步批量写入数据库
3. 内存缓存层实现详解
3.1 IMemoryCache 核心接口分析
Microsoft.Extensions.Caching.Memory.IMemoryCache接口提供了缓存操作的核心方法:
public interface IMemoryCache : IDisposable
{
bool TryGetValue(object key, out object value);
ICacheEntry CreateEntry(object key);
void Remove(object key);
}
3.2 高级内存缓存封装实现
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Runtime.Serialization;
///
/// 缓存异常基类
public abstract class CacheException : Exception
protected CacheException(string message) : base(message) { }
protected CacheException(string message, Exception innerException) : base(message, innerException) { }
/// 缓存连接异常
public class CacheConnectionException : CacheException
public CacheConnectionException(string message) : base(message) { }
public CacheConnectionException(string message, Exception innerException) : base(message, innerException) { }
/// 缓存序列化异常
public class CacheSerializationException : CacheException
public CacheSerializationException(string message) : base(message) { }
public CacheSerializationException(string message, Exception innerException) : base(message, innerException) { }
/// 缓存超时异常
public class CacheTimeoutException : CacheException
public CacheTimeoutException(string message) : base(message) { }
public CacheTimeoutException(string message, Exception innerException) : base(message, innerException) { }
/// 缓存验证异常
public class CacheValidationException : CacheException
public CacheValidationException(string message) : base(message) { }
public CacheValidationException(string message, Exception innerException) : base(message, innerException) { }
/// 线程安全的缓存统计追踪器
public class CacheStatisticsTracker
private long _totalOperations = 0;
private long _l1Hits = 0;
private long _l2Hits = 0;
private long _totalMisses = 0;
private readonly object _lock = new object();
public void RecordOperation()
Interlocked.Increment(ref _totalOperations);
public void RecordHit(CacheLevel level)
switch (level)
case CacheLevel.L1:
Interlocked.Increment(ref _l1Hits);
break;
case CacheLevel.L2:
Interlocked.Increment(ref _l2Hits);
public void RecordMiss()
Interlocked.Increment(ref _totalMisses);
public CacheStatisticsSnapshot GetSnapshot()
return new CacheStatisticsSnapshot
TotalOperations = Interlocked.Read(ref _totalOperations),
L1Hits = Interlocked.Read(ref _l1Hits),
L2Hits = Interlocked.Read(ref _l2Hits),
TotalMisses = Interlocked.Read(ref _totalMisses)
};
public void Reset()
lock (_lock)
Interlocked.Exchange(ref _totalOperations, 0);
Interlocked.Exchange(ref _l1Hits, 0);
Interlocked.Exchange(ref _l2Hits, 0);
Interlocked.Exchange(ref _totalMisses, 0);
/// 缓存统计快照
public class CacheStatisticsSnapshot
public long TotalOperations { get; init; }
public long L1Hits { get; init; }
public long L2Hits { get; init; }
public long TotalMisses { get; init; }
public long TotalHits => L1Hits + L2Hits;
public double OverallHitRatio => TotalOperations == 0 ? 0 : (double)TotalHits / TotalOperations;
public double L1HitRatio => TotalOperations == 0 ? 0 : (double)L1Hits / TotalOperations;
public double L2HitRatio => TotalOperations == 0 ? 0 : (double)L2Hits / TotalOperations;
/// 缓存数据验证器接口
public interface ICacheDataValidator
bool IsValid(T value);
void ValidateKey(string key);
bool IsSafeForSerialization(T value);
/// 默认缓存数据验证器
public class DefaultCacheDataValidator : ICacheDataValidator
private readonly ILogger _logger;
private readonly HashSet _forbiddenTypes;
private readonly Regex _keyValidationRegex;
public DefaultCacheDataValidator(ILogger logger)
_logger = logger;
_forbiddenTypes = new HashSet
typeof(System.IO.FileStream),
typeof(System.Net.Sockets.Socket),
typeof(System.Threading.Thread),
typeof(System.Threading.Tasks.Task)
// 限制key格式:只允许字母数字下划线冒号和点
_keyValidationRegex = new Regex(@"^[a-zA-Z0-9_:.-]+$", RegexOptions.Compiled);
public bool IsValid(T value)
if (value == null) return true;
var valueType = value.GetType();
// 检查禁止类型
if (_forbiddenTypes.Contains(valueType))
_logger.LogWarning("Forbidden type in cache: {Type}", valueType.Name);
return false;
// 检查循环引用(简化版)
if (HasCircularReference(value))
_logger.LogWarning("Circular reference detected in cache value");
return true;
public void ValidateKey(string key)
if (string.IsNullOrWhiteSpace(key))
throw new CacheValidationException("Cache key cannot be null or empty");
if (key.Length > 250)
throw new CacheValidationException($"Cache key too long: {key.Length} characters");
if (!_keyValidationRegex.IsMatch(key))
throw new CacheValidationException($"Invalid characters in cache key: {key}");
public bool IsSafeForSerialization(T value)
// 检查是否有序列化属性
if (valueType.IsSerializable ||
valueType.GetCustomAttributes(typeof(DataContractAttribute), false).Length > 0)
// 原始类型和字符串通常安全
return valueType.IsPrimitive || valueType == typeof(string) || valueType == typeof(DateTime);
private bool HasCircularReference(object obj, HashSet visited = null) { if (obj == null) return false; visited ??= new HashSet(); if (visited.Contains(obj)) return true; visited.Add(obj); // 简化的循环检测,只检查一层 var type = obj.GetType(); if (type.IsPrimitive || type == typeof(string)) return false; visited.Remove(obj); return false; } } /// /// 安全缓存管理器装饰器 /// public class SecureCacheManagerDecorator : IAdvancedMemoryCache { private readonly IAdvancedMemoryCache _innerCache; private readonly ICacheDataValidator _validator; private readonly ILogger _logger; public SecureCacheManagerDecorator( IAdvancedMemoryCache innerCache, ICacheDataValidator validator, ILogger logger) { _innerCache = innerCache ?? throw new ArgumentNullException(nameof(innerCache)); _validator = validator ?? throw new ArgumentNullException(nameof(validator)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public async Task GetOrSetAsync(string key, Func> factory, TimeSpan? expiry = null) { _validator.ValidateKey(key); return await _innerCache.GetOrSetAsync(key, async () => { var value = await factory(); if (!_validator.IsValid(value)) { throw new CacheValidationException($"Invalid cache value for key: {key}"); } return value; }, expiry); } public async Task GetAsync(string key) { _validator.ValidateKey(key); return await _innerCache.GetAsync(key); } public async Task SetAsync(string key, T value, TimeSpan? expiry = null) { _validator.ValidateKey(key); if (!_validator.IsValid(value)) { throw new CacheValidationException($"Invalid cache value for key: {key}"); } if (!_validator.IsSafeForSerialization(value)) { _logger.LogWarning("Potentially unsafe serialization for key: {Key}, type: {Type}", key, value?.GetType().Name); } await _innerCache.SetAsync(key, value, expiry); } public async Task RemoveAsync(string key) { _validator.ValidateKey(key); await _innerCache.RemoveAsync(key); } public async Task RemoveByPatternAsync(string pattern) { if (string.IsNullOrWhiteSpace(pattern)) throw new CacheValidationException("Pattern cannot be null or empty"); await _innerCache.RemoveByPatternAsync(pattern); } public CacheStatistics GetStatistics() => _innerCache.GetStatistics(); public void ClearStatistics() => _innerCache.ClearStatistics(); } /// /// 序列化器接口 /// public interface ICacheSerializer { byte[] Serialize(T value); T Deserialize(byte[] data); string SerializerName { get; } bool SupportsType(Type type); } /// /// JSON序列化器(默认) /// public class JsonCacheSerializer : ICacheSerializer { private readonly JsonSerializerOptions _options; public string SerializerName => "JSON"; public JsonCacheSerializer() { _options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true }; } public byte[] Serialize(T value) { if (value == null) return null; if (typeof(T) == typeof(string)) return System.Text.Encoding.UTF8.GetBytes(value.ToString()); var json = JsonSerializer.Serialize(value, _options); return System.Text.Encoding.UTF8.GetBytes(json); } public T Deserialize(byte[] data) { if (data == null || data.Length == 0) return default(T); if (typeof(T) == typeof(string)) return (T)(object)System.Text.Encoding.UTF8.GetString(data); var json = System.Text.Encoding.UTF8.GetString(data); return JsonSerializer.Deserialize(json, _options); } public bool SupportsType(Type type) { return true; // JSON支持所有类型 } } /// /// 二进制序列化器(用于简单类型) /// public class BinaryCacheSerializer : ICacheSerializer { public string SerializerName => "Binary"; private static readonly HashSet SupportedTypes = new() { typeof(int), typeof(long), typeof(double), typeof(float), typeof(bool), typeof(byte), typeof(short), typeof(DateTime), typeof(DateTimeOffset), typeof(TimeSpan), typeof(Guid), typeof(decimal) }; public byte[] Serialize(T value) { if (value == null) return null; var type = typeof(T); // 专门处理常见类型,提高性能 return type switch { _ when type == typeof(int) => BitConverter.GetBytes((int)(object)value), _ when type == typeof(long) => BitConverter.GetBytes((long)(object)value), _ when type == typeof(double) => BitConverter.GetBytes((double)(object)value), _ when type == typeof(float) => BitConverter.GetBytes((float)(object)value), _ when type == typeof(bool) => BitConverter.GetBytes((bool)(object)value), _ when type == typeof(DateTime) => BitConverter.GetBytes(((DateTime)(object)value).ToBinary()), _ when type == typeof(Guid) => ((Guid)(object)value).ToByteArray(), _ when type == typeof(string) => System.Text.Encoding.UTF8.GetBytes(value.ToString()), _ => throw new NotSupportedException($"Type {type.Name} is not supported by BinaryCacheSerializer") }; } public T Deserialize(byte[] data) { if (data == null || data.Length == 0) return default(T); var type = typeof(T); object result = type switch { _ when type == typeof(int) => BitConverter.ToInt32(data, 0), _ when type == typeof(long) => BitConverter.ToInt64(data, 0), _ when type == typeof(double) => BitConverter.ToDouble(data, 0), _ when type == typeof(float) => BitConverter.ToSingle(data, 0), _ when type == typeof(bool) => BitConverter.ToBoolean(data, 0), _ when type == typeof(DateTime) => DateTime.FromBinary(BitConverter.ToInt64(data, 0)), _ when type == typeof(Guid) => new Guid(data), _ when type == typeof(string) => System.Text.Encoding.UTF8.GetString(data), _ => throw new NotSupportedException($"Type {type.Name} is not supported by BinaryCacheSerializer") }; return (T)result; } public bool SupportsType(Type type) { return SupportedTypes.Contains(type) || type == typeof(string); } } /// /// 智能序列化器管理器 /// public class SmartCacheSerializer : ICacheSerializer { private readonly ICacheSerializer[] _serializers; private readonly ILogger _logger; public string SerializerName => "Smart"; public SmartCacheSerializer(ILogger logger) { _logger = logger; _serializers = new ICacheSerializer[] { new BinaryCacheSerializer(), // 优先使用二进制序列化 new JsonCacheSerializer() // 备选JSON序列化 }; } public byte[] Serialize(T value) { if (value == null) return null; var type = typeof(T); foreach (var serializer in _serializers) { if (serializer.SupportsType(type)) { try { var data = serializer.Serialize(value); // 在数据开头添加序列化器标识 var header = System.Text.Encoding.UTF8.GetBytes(serializer.SerializerName.PadRight(8)); var result = new byte[header.Length + data.Length]; Array.Copy(header, 0, result, 0, header.Length); Array.Copy(data, 0, result, header.Length, data.Length); return result; } catch (Exception ex) { _logger.LogWarning(ex, "Serializer {SerializerName} failed for type {TypeName}", serializer.SerializerName, type.Name); continue; } } } throw new CacheSerializationException($"No suitable serializer found for type: {type.Name}"); } public T Deserialize(byte[] data) { if (data == null || data.Length < 8) return default(T); // 读取序列化器标识 var headerBytes = new byte[8]; Array.Copy(data, 0, headerBytes, 0, 8); var serializerName = System.Text.Encoding.UTF8.GetString(headerBytes).Trim(); // 获取实际数据 var actualData = new byte[data.Length - 8]; Array.Copy(data, 8, actualData, 0, actualData.Length); // 找到对应的序列化器 var serializer = _serializers.FirstOrDefault(s => s.SerializerName == serializerName); if (serializer == null) { _logger.LogWarning("Unknown serializer: {SerializerName}, falling back to JSON", serializerName); serializer = new JsonCacheSerializer(); } try { return serializer.Deserialize(actualData); } catch (Exception ex) { _logger.LogError(ex, "Failed to deserialize with {SerializerName}", serializerName); throw new CacheSerializationException($"Deserialization failed with {serializerName}", ex); } } public bool SupportsType(Type type) { return _serializers.Any(s => s.SupportsType(type)); } } /// /// 断路器状态 /// public enum CircuitBreakerState { Closed, // 正常状态 Open, // 断路器打开,拒绝请求 HalfOpen // 半开状态,允许少量请求通过 } /// /// 缓存断路器配置 /// public class CacheCircuitBreakerOptions { public int FailureThreshold { get; set; } = 5; // 连续失败阈值 public TimeSpan OpenTimeout { get; set; } = TimeSpan.FromMinutes(1); // 断路器打开时间 public int SuccessThreshold { get; set; } = 2; // 半开状态成功阈值 public TimeSpan SamplingDuration { get; set; } = TimeSpan.FromMinutes(2); // 采样时间窗口 } /// /// 缓存断路器 /// public class CacheCircuitBreaker { private readonly CacheCircuitBreakerOptions _options; private readonly ILogger _logger; private readonly object _lock = new object(); private CircuitBreakerState _state = CircuitBreakerState.Closed; private int _failureCount = 0; private int _successCount = 0; private DateTime _lastFailureTime = DateTime.MinValue; private DateTime _lastStateChangeTime = DateTime.UtcNow; public CacheCircuitBreaker( CacheCircuitBreakerOptions options, ILogger logger) { _options = options ?? throw new ArgumentNullException(nameof(options)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public CircuitBreakerState State => _state; /// /// 执行带断路器保护的操作 /// public async Task ExecuteAsync(Func> operation, string operationName = null) { if (!CanExecute()) { throw new CacheException($"Circuit breaker is OPEN for operation: {operationName}"); } try { var result = await operation(); OnSuccess(); return result; } catch (Exception ex) { OnFailure(ex, operationName); throw; } } /// /// 检查是否可以执行操作 /// private bool CanExecute() { lock (_lock) { switch (_state) { case CircuitBreakerState.Closed: return true; case CircuitBreakerState.Open: // 检查是否可以转入半开状态 if (DateTime.UtcNow - _lastStateChangeTime >= _options.OpenTimeout) { _state = CircuitBreakerState.HalfOpen; _successCount = 0; _lastStateChangeTime = DateTime.UtcNow; _logger.LogInformation("Circuit breaker entering HALF_OPEN state"); return true; } return false; case CircuitBreakerState.HalfOpen: return true; default: return false; } } } /// /// 操作成功回调 /// private void OnSuccess() { lock (_lock) { if (_state == CircuitBreakerState.HalfOpen) { _successCount++; if (_successCount >= _options.SuccessThreshold) { _state = CircuitBreakerState.Closed; _failureCount = 0; _successCount = 0; _lastStateChangeTime = DateTime.UtcNow; _logger.LogInformation("Circuit breaker entering CLOSED state"); } } else if (_state == CircuitBreakerState.Closed) { // 在采样时间窗口内重置失败计数 if (DateTime.UtcNow - _lastFailureTime > _options.SamplingDuration) { _failureCount = 0; } } } } /// /// 操作失败回调 /// private void OnFailure(Exception ex, string operationName) { lock (_lock) { _failureCount++; _lastFailureTime = DateTime.UtcNow; _logger.LogWarning(ex, "Circuit breaker recorded failure #{FailureCount} for operation: {Operation}", _failureCount, operationName); if (_state == CircuitBreakerState.Closed && _failureCount >= _options.FailureThreshold) { _state = CircuitBreakerState.Open; _lastStateChangeTime = DateTime.UtcNow; _logger.LogError("Circuit breaker entering OPEN state after {FailureCount} failures", _failureCount); } else if (_state == CircuitBreakerState.HalfOpen) { _state = CircuitBreakerState.Open; _lastStateChangeTime = DateTime.UtcNow; _logger.LogWarning("Circuit breaker returning to OPEN state from HALF_OPEN due to failure"); } } } /// /// 获取当前状态信息 /// public object GetState() { lock (_lock) { return new { State = _state.ToString(), FailureCount = _failureCount, SuccessCount = _successCount, LastFailureTime = _lastFailureTime, LastStateChangeTime = _lastStateChangeTime, CanExecute = CanExecute() }; } } } /// /// 带断路器的Redis缓存装饰器 /// public class CircuitBreakerRedisCache : IRedisDistributedCache { private readonly IRedisDistributedCache _innerCache; private readonly CacheCircuitBreaker _circuitBreaker; private readonly ILogger _logger; public CircuitBreakerRedisCache( IRedisDistributedCache innerCache, CacheCircuitBreaker circuitBreaker, ILogger logger) { _innerCache = innerCache ?? throw new ArgumentNullException(nameof(innerCache)); _circuitBreaker = circuitBreaker ?? throw new ArgumentNullException(nameof(circuitBreaker)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public async Task GetAsync(string key) { try { return await _circuitBreaker.ExecuteAsync(() => _innerCache.GetAsync(key), $"GET:{key}"); } catch (CacheException) when (_circuitBreaker.State == CircuitBreakerState.Open) { _logger.LogWarning("Circuit breaker open, returning default for key: {Key}", key); return default(T); } } public async Task SetAsync(string key, T value, TimeSpan? expiry = null) { try { await _circuitBreaker.ExecuteAsync(() => _innerCache.SetAsync(key, value, expiry), $"SET:{key}"); } catch (CacheException) when (_circuitBreaker.State == CircuitBreakerState.Open) { _logger.LogWarning("Circuit breaker open, skipping cache set for key: {Key}", key); // 不继续抛出异常,允许应用继续运行 } } // 继续实现其他接口方法... public Task ExistsAsync(string key) => _circuitBreaker.ExecuteAsync(() => _innerCache.ExistsAsync(key), $"EXISTS:{key}"); public Task RemoveAsync(string key) => _circuitBreaker.ExecuteAsync(() => _innerCache.RemoveAsync(key), $"REMOVE:{key}"); public Task RemoveByPatternAsync(string pattern) => _circuitBreaker.ExecuteAsync(() => _innerCache.RemoveByPatternAsync(pattern), $"REMOVE_PATTERN:{pattern}"); public Task GetOrSetAsync(string key, Func> factory, TimeSpan? expiry = null) => _circuitBreaker.ExecuteAsync(() => _innerCache.GetOrSetAsync(key, factory, expiry), $"GET_OR_SET:{key}"); public Task> GetMultipleAsync(IEnumerable keys) => _circuitBreaker.ExecuteAsync(() => _innerCache.GetMultipleAsync(keys), "GET_MULTIPLE"); public Task SetMultipleAsync(Dictionary keyValuePairs, TimeSpan? expiry = null) => _circuitBreaker.ExecuteAsync(() => _innerCache.SetMultipleAsync(keyValuePairs, expiry), "SET_MULTIPLE"); public Task IncrementAsync(string key, long value = 1, TimeSpan? expiry = null) => _circuitBreaker.ExecuteAsync(() => _innerCache.IncrementAsync(key, value, expiry), $"INCREMENT:{key}"); public Task IncrementAsync(string key, double value, TimeSpan? expiry = null) => _circuitBreaker.ExecuteAsync(() => _innerCache.IncrementAsync(key, value, expiry), $"INCREMENT_DOUBLE:{key}"); public Task SetIfNotExistsAsync(string key, T value, TimeSpan? expiry = null) => _circuitBreaker.ExecuteAsync(() => _innerCache.SetIfNotExistsAsync(key, value, expiry), $"SET_IF_NOT_EXISTS:{key}"); public Task GetExpiryAsync(string key) => _circuitBreaker.ExecuteAsync(() => _innerCache.GetExpiryAsync(key), $"GET_EXPIRY:{key}"); public Task ExpireAsync(string key, TimeSpan expiry) => _circuitBreaker.ExecuteAsync(() => _innerCache.ExpireAsync(key, expiry), $"EXPIRE:{key}"); } /// /// LRU缓存容器,用于防止内存泄漏 /// public class LRUCache { private readonly int _maxSize; private readonly Dictionary>> _cache; private readonly LinkedList> _lruList; private readonly object _lock = new object(); public LRUCache(int maxSize) { if (maxSize <= 0) throw new ArgumentException("Max size must be greater than 0", nameof(maxSize)); _maxSize = maxSize; _cache = new Dictionary>>(maxSize); _lruList = new LinkedList>(); } public int Count { get { lock (_lock) { return _cache.Count; } } } public bool TryGet(TKey key, out TValue value) { lock (_lock) { if (_cache.TryGetValue(key, out var node)) { // 移到链表头部(最近使用) _lruList.Remove(node); _lruList.AddFirst(node); value = node.Value.Value; return true; } value = default(TValue); return false; } } public void Add(TKey key, TValue value) { lock (_lock) { if (_cache.TryGetValue(key, out var existingNode)) { // 更新已存在的项 existingNode.Value.Value = value; existingNode.Value.LastAccessed = DateTime.UtcNow; // 移到链表头部 _lruList.Remove(existingNode); _lruList.AddFirst(existingNode); } else { // 检查容量限制 if (_cache.Count >= _maxSize) { // 移除最久未使用的项 var lastNode = _lruList.Last; if (lastNode != null) { _cache.Remove(lastNode.Value.Key); _lruList.RemoveLast(); } } // 添加新项 var newItem = new CacheItem { Key = key, Value = value, LastAccessed = DateTime.UtcNow }; var newNode = _lruList.AddFirst(newItem); _cache[key] = newNode; } } } public bool Remove(TKey key) { lock (_lock) { if (_cache.TryGetValue(key, out var node)) { _cache.Remove(key); _lruList.Remove(node); return true; } return false; } } public void Clear() { lock (_lock) { _cache.Clear(); _lruList.Clear(); } } public IEnumerable Keys { get { lock (_lock) { return _cache.Keys.ToList(); } } } /// /// 清理过期项 /// public int CleanupExpired(TimeSpan maxAge) { var cutoffTime = DateTime.UtcNow - maxAge; var expiredKeys = new List(); lock (_lock) { foreach (var item in _lruList) { if (item.LastAccessed < cutoffTime) { expiredKeys.Add(item.Key); } } foreach (var key in expiredKeys) { Remove(key); } } return expiredKeys.Count; } } /// /// LRU缓存项 /// class CacheItem { public TKey Key { get; set; } public TValue Value { get; set; } public DateTime LastAccessed { get; set; } } /// /// 高级内存缓存管理器 /// 提供泛型支持、统计信息、性能监控等功能 /// public interface IAdvancedMemoryCache { Task GetOrSetAsync(string key, Func> factory, TimeSpan? expiry = null); Task GetAsync(string key); Task SetAsync(string key, T value, TimeSpan? expiry = null); Task RemoveAsync(string key); Task RemoveByPatternAsync(string pattern); CacheStatistics GetStatistics(); void ClearStatistics(); } /// /// 缓存统计信息 /// public class CacheStatistics { public long HitCount { get; set; } public long MissCount { get; set; } public long SetCount { get; set; } public long RemoveCount { get; set; } public double HitRatio => HitCount + MissCount == 0 ? 0 : (double)HitCount / (HitCount + MissCount); public DateTime StartTime { get; set; } public TimeSpan Duration => DateTime.UtcNow - StartTime; } /// /// 缓存配置选项 /// public class AdvancedMemoryCacheOptions { public int SizeLimit { get; set; } = 1000; public TimeSpan DefaultExpiry { get; set; } = TimeSpan.FromMinutes(30); public bool EnableStatistics { get; set; } = true; public bool EnablePatternRemoval { get; set; } = true; public double CompactionPercentage { get; set; } = 0.1; } /// /// 高级内存缓存实现 /// 基于IMemoryCache构建的功能增强版本 /// public class AdvancedMemoryCache : IAdvancedMemoryCache, IDisposable { private readonly IMemoryCache _cache; private readonly ILogger _logger; private readonly AdvancedMemoryCacheOptions _options; private readonly CacheStatistics _statistics; private readonly ConcurrentDictionary _keyTracker; private readonly SemaphoreSlim _semaphore; private readonly Timer _cleanupTimer; public AdvancedMemoryCache( IMemoryCache cache, ILogger logger, IOptions options) { _cache = cache ?? throw new ArgumentNullException(nameof(cache)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _options = options?.Value ?? new AdvancedMemoryCacheOptions(); _statistics = new CacheStatistics { StartTime = DateTime.UtcNow }; _keyTracker = new ConcurrentDictionary(); _semaphore = new SemaphoreSlim(1, 1); // 定期清理过期的key追踪记录 _cleanupTimer = new Timer(CleanupKeyTracker, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); } /// /// 获取或设置缓存项 /// 这是最常用的方法,实现了Cache-Aside模式 /// /// 缓存项类型 /// 缓存键 /// 数据工厂方法 /// 过期时间 /// 缓存的值 public async Task GetOrSetAsync(string key, Func> factory, TimeSpan? expiry = null) { if (string.IsNullOrEmpty(key)) throw new ArgumentException("Key cannot be null or empty", nameof(key)); if (factory == null) throw new ArgumentNullException(nameof(factory)); // 尝试从缓存获取 var cachedValue = await GetAsync(key); if (cachedValue != null) { _logger.LogDebug("Cache hit for key: {Key}", key); return cachedValue; } // 使用信号量防止并发执行相同的factory方法 await _semaphore.WaitAsync(); try { // 双重检查锁定模式 cachedValue = await GetAsync(key); if (cachedValue != null) { _logger.LogDebug("Cache hit on second check for key: {Key}", key); return cachedValue; } // 执行工厂方法获取数据 _logger.LogDebug("Cache miss for key: {Key}, executing factory method", key); var value = await factory(); // 将结果存入缓存 await SetAsync(key, value, expiry); return value; } catch (CacheConnectionException ex) { _logger.LogWarning(ex, "Cache connection failed for key: {Key}, using fallback", key); // 缓存连接失败时,仍执行工厂方法但不缓存结果 return await factory(); } catch (CacheSerializationException ex) { _logger.LogError(ex, "Serialization failed for key: {Key}", key); throw; } catch (CacheTimeoutException ex) { _logger.LogWarning(ex, "Cache operation timeout for key: {Key}", key); return await factory(); } catch (Exception ex) { _logger.LogError(ex, "Unexpected error occurred while executing factory method for key: {Key}", key); throw new CacheException($"Cache operation failed for key: {key}", ex); } finally { _semaphore.Release(); } } /// /// 异步获取缓存项 /// /// 缓存项类型 /// 缓存键 /// 缓存的值,如果不存在则返回默认值 public Task GetAsync(string key) { if (string.IsNullOrEmpty(key)) throw new ArgumentException("Key cannot be null or empty", nameof(key)); var found = _cache.TryGetValue(key, out var value); if (_options.EnableStatistics) { if (found) Interlocked.Increment(ref _statistics.HitCount); else Interlocked.Increment(ref _statistics.MissCount); } if (found && value is T typedValue) { return Task.FromResult(typedValue); } return Task.FromResult(default(T)); } /// /// 异步设置缓存项 /// /// 缓存项类型 /// 缓存键 /// 缓存值 /// 过期时间 public Task SetAsync(string key, T value, TimeSpan? expiry = null) { if (string.IsNullOrEmpty(key)) throw new ArgumentException("Key cannot be null or empty", nameof(key)); var cacheExpiry = expiry ?? _options.DefaultExpiry; using var entry = _cache.CreateEntry(key); entry.Value = value; entry.AbsoluteExpirationRelativeToNow = cacheExpiry; entry.Size = 1; // 简化的大小计算,实际应用中可根据对象大小设置 // 设置过期回调 entry.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration { EvictionCallback = OnCacheEntryEvicted, State = key }); // 追踪缓存键 if (_options.EnablePatternRemoval) { _keyTracker.TryAdd(key, 0); } if (_options.EnableStatistics) { Interlocked.Increment(ref _statistics.SetCount); } _logger.LogDebug("Set cache entry for key: {Key}, expiry: {Expiry}", key, cacheExpiry); return Task.CompletedTask; } /// /// 异步移除缓存项 /// /// 缓存键 public Task RemoveAsync(string key) { if (string.IsNullOrEmpty(key)) throw new ArgumentException("Key cannot be null or empty", nameof(key)); _cache.Remove(key); _keyTracker.TryRemove(key, out _); if (_options.EnableStatistics) { Interlocked.Increment(ref _statistics.RemoveCount); } _logger.LogDebug("Removed cache entry for key: {Key}", key); return Task.CompletedTask; } /// /// 根据模式异步移除缓存项 /// 支持通配符匹配,如 "user:*", "*:settings" /// /// 匹配模式 public async Task RemoveByPatternAsync(string pattern) { if (string.IsNullOrEmpty(pattern)) throw new ArgumentException("Pattern cannot be null or empty", nameof(pattern)); if (!_options.EnablePatternRemoval) { _logger.LogWarning("Pattern removal is disabled"); return; } var keysToRemove = new List(); var regexPattern = ConvertWildcardToRegex(pattern); var regex = new System.Text.RegularExpressions.Regex(regexPattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase); foreach (var key in _keyTracker.Keys) { if (regex.IsMatch(key)) { keysToRemove.Add(key); } } foreach (var key in keysToRemove)
if (obj == null) return false;
visited ??= new HashSet(); if (visited.Contains(obj)) return true; visited.Add(obj); // 简化的循环检测,只检查一层 var type = obj.GetType(); if (type.IsPrimitive || type == typeof(string)) return false; visited.Remove(obj); return false; } } /// /// 安全缓存管理器装饰器 /// public class SecureCacheManagerDecorator : IAdvancedMemoryCache { private readonly IAdvancedMemoryCache _innerCache; private readonly ICacheDataValidator _validator; private readonly ILogger _logger; public SecureCacheManagerDecorator( IAdvancedMemoryCache innerCache, ICacheDataValidator validator, ILogger logger) { _innerCache = innerCache ?? throw new ArgumentNullException(nameof(innerCache)); _validator = validator ?? throw new ArgumentNullException(nameof(validator)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public async Task GetOrSetAsync(string key, Func> factory, TimeSpan? expiry = null) { _validator.ValidateKey(key); return await _innerCache.GetOrSetAsync(key, async () => { var value = await factory(); if (!_validator.IsValid(value)) { throw new CacheValidationException($"Invalid cache value for key: {key}"); } return value; }, expiry); } public async Task GetAsync(string key) { _validator.ValidateKey(key); return await _innerCache.GetAsync(key); } public async Task SetAsync(string key, T value, TimeSpan? expiry = null) { _validator.ValidateKey(key); if (!_validator.IsValid(value)) { throw new CacheValidationException($"Invalid cache value for key: {key}"); } if (!_validator.IsSafeForSerialization(value)) { _logger.LogWarning("Potentially unsafe serialization for key: {Key}, type: {Type}", key, value?.GetType().Name); } await _innerCache.SetAsync(key, value, expiry); } public async Task RemoveAsync(string key) { _validator.ValidateKey(key); await _innerCache.RemoveAsync(key); } public async Task RemoveByPatternAsync(string pattern) { if (string.IsNullOrWhiteSpace(pattern)) throw new CacheValidationException("Pattern cannot be null or empty"); await _innerCache.RemoveByPatternAsync(pattern); } public CacheStatistics GetStatistics() => _innerCache.GetStatistics(); public void ClearStatistics() => _innerCache.ClearStatistics(); } /// /// 序列化器接口 /// public interface ICacheSerializer { byte[] Serialize(T value); T Deserialize(byte[] data); string SerializerName { get; } bool SupportsType(Type type); } /// /// JSON序列化器(默认) /// public class JsonCacheSerializer : ICacheSerializer { private readonly JsonSerializerOptions _options; public string SerializerName => "JSON"; public JsonCacheSerializer() { _options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true }; } public byte[] Serialize(T value) { if (value == null) return null; if (typeof(T) == typeof(string)) return System.Text.Encoding.UTF8.GetBytes(value.ToString()); var json = JsonSerializer.Serialize(value, _options); return System.Text.Encoding.UTF8.GetBytes(json); } public T Deserialize(byte[] data) { if (data == null || data.Length == 0) return default(T); if (typeof(T) == typeof(string)) return (T)(object)System.Text.Encoding.UTF8.GetString(data); var json = System.Text.Encoding.UTF8.GetString(data); return JsonSerializer.Deserialize(json, _options); } public bool SupportsType(Type type) { return true; // JSON支持所有类型 } } /// /// 二进制序列化器(用于简单类型) /// public class BinaryCacheSerializer : ICacheSerializer { public string SerializerName => "Binary"; private static readonly HashSet SupportedTypes = new() { typeof(int), typeof(long), typeof(double), typeof(float), typeof(bool), typeof(byte), typeof(short), typeof(DateTime), typeof(DateTimeOffset), typeof(TimeSpan), typeof(Guid), typeof(decimal) }; public byte[] Serialize(T value) { if (value == null) return null; var type = typeof(T); // 专门处理常见类型,提高性能 return type switch { _ when type == typeof(int) => BitConverter.GetBytes((int)(object)value), _ when type == typeof(long) => BitConverter.GetBytes((long)(object)value), _ when type == typeof(double) => BitConverter.GetBytes((double)(object)value), _ when type == typeof(float) => BitConverter.GetBytes((float)(object)value), _ when type == typeof(bool) => BitConverter.GetBytes((bool)(object)value), _ when type == typeof(DateTime) => BitConverter.GetBytes(((DateTime)(object)value).ToBinary()), _ when type == typeof(Guid) => ((Guid)(object)value).ToByteArray(), _ when type == typeof(string) => System.Text.Encoding.UTF8.GetBytes(value.ToString()), _ => throw new NotSupportedException($"Type {type.Name} is not supported by BinaryCacheSerializer") }; } public T Deserialize(byte[] data) { if (data == null || data.Length == 0) return default(T); var type = typeof(T); object result = type switch { _ when type == typeof(int) => BitConverter.ToInt32(data, 0), _ when type == typeof(long) => BitConverter.ToInt64(data, 0), _ when type == typeof(double) => BitConverter.ToDouble(data, 0), _ when type == typeof(float) => BitConverter.ToSingle(data, 0), _ when type == typeof(bool) => BitConverter.ToBoolean(data, 0), _ when type == typeof(DateTime) => DateTime.FromBinary(BitConverter.ToInt64(data, 0)), _ when type == typeof(Guid) => new Guid(data), _ when type == typeof(string) => System.Text.Encoding.UTF8.GetString(data), _ => throw new NotSupportedException($"Type {type.Name} is not supported by BinaryCacheSerializer") }; return (T)result; } public bool SupportsType(Type type) { return SupportedTypes.Contains(type) || type == typeof(string); } } /// /// 智能序列化器管理器 /// public class SmartCacheSerializer : ICacheSerializer { private readonly ICacheSerializer[] _serializers; private readonly ILogger _logger; public string SerializerName => "Smart"; public SmartCacheSerializer(ILogger logger) { _logger = logger; _serializers = new ICacheSerializer[] { new BinaryCacheSerializer(), // 优先使用二进制序列化 new JsonCacheSerializer() // 备选JSON序列化 }; } public byte[] Serialize(T value) { if (value == null) return null; var type = typeof(T); foreach (var serializer in _serializers) { if (serializer.SupportsType(type)) { try { var data = serializer.Serialize(value); // 在数据开头添加序列化器标识 var header = System.Text.Encoding.UTF8.GetBytes(serializer.SerializerName.PadRight(8)); var result = new byte[header.Length + data.Length]; Array.Copy(header, 0, result, 0, header.Length); Array.Copy(data, 0, result, header.Length, data.Length); return result; } catch (Exception ex) { _logger.LogWarning(ex, "Serializer {SerializerName} failed for type {TypeName}", serializer.SerializerName, type.Name); continue; } } } throw new CacheSerializationException($"No suitable serializer found for type: {type.Name}"); } public T Deserialize(byte[] data) { if (data == null || data.Length < 8) return default(T); // 读取序列化器标识 var headerBytes = new byte[8]; Array.Copy(data, 0, headerBytes, 0, 8); var serializerName = System.Text.Encoding.UTF8.GetString(headerBytes).Trim(); // 获取实际数据 var actualData = new byte[data.Length - 8]; Array.Copy(data, 8, actualData, 0, actualData.Length); // 找到对应的序列化器 var serializer = _serializers.FirstOrDefault(s => s.SerializerName == serializerName); if (serializer == null) { _logger.LogWarning("Unknown serializer: {SerializerName}, falling back to JSON", serializerName); serializer = new JsonCacheSerializer(); } try { return serializer.Deserialize(actualData); } catch (Exception ex) { _logger.LogError(ex, "Failed to deserialize with {SerializerName}", serializerName); throw new CacheSerializationException($"Deserialization failed with {serializerName}", ex); } } public bool SupportsType(Type type) { return _serializers.Any(s => s.SupportsType(type)); } } /// /// 断路器状态 /// public enum CircuitBreakerState { Closed, // 正常状态 Open, // 断路器打开,拒绝请求 HalfOpen // 半开状态,允许少量请求通过 } /// /// 缓存断路器配置 /// public class CacheCircuitBreakerOptions { public int FailureThreshold { get; set; } = 5; // 连续失败阈值 public TimeSpan OpenTimeout { get; set; } = TimeSpan.FromMinutes(1); // 断路器打开时间 public int SuccessThreshold { get; set; } = 2; // 半开状态成功阈值 public TimeSpan SamplingDuration { get; set; } = TimeSpan.FromMinutes(2); // 采样时间窗口 } /// /// 缓存断路器 /// public class CacheCircuitBreaker { private readonly CacheCircuitBreakerOptions _options; private readonly ILogger _logger; private readonly object _lock = new object(); private CircuitBreakerState _state = CircuitBreakerState.Closed; private int _failureCount = 0; private int _successCount = 0; private DateTime _lastFailureTime = DateTime.MinValue; private DateTime _lastStateChangeTime = DateTime.UtcNow; public CacheCircuitBreaker( CacheCircuitBreakerOptions options, ILogger logger) { _options = options ?? throw new ArgumentNullException(nameof(options)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public CircuitBreakerState State => _state; /// /// 执行带断路器保护的操作 /// public async Task ExecuteAsync(Func> operation, string operationName = null) { if (!CanExecute()) { throw new CacheException($"Circuit breaker is OPEN for operation: {operationName}"); } try { var result = await operation(); OnSuccess(); return result; } catch (Exception ex) { OnFailure(ex, operationName); throw; } } /// /// 检查是否可以执行操作 /// private bool CanExecute() { lock (_lock) { switch (_state) { case CircuitBreakerState.Closed: return true; case CircuitBreakerState.Open: // 检查是否可以转入半开状态 if (DateTime.UtcNow - _lastStateChangeTime >= _options.OpenTimeout) { _state = CircuitBreakerState.HalfOpen; _successCount = 0; _lastStateChangeTime = DateTime.UtcNow; _logger.LogInformation("Circuit breaker entering HALF_OPEN state"); return true; } return false; case CircuitBreakerState.HalfOpen: return true; default: return false; } } } /// /// 操作成功回调 /// private void OnSuccess() { lock (_lock) { if (_state == CircuitBreakerState.HalfOpen) { _successCount++; if (_successCount >= _options.SuccessThreshold) { _state = CircuitBreakerState.Closed; _failureCount = 0; _successCount = 0; _lastStateChangeTime = DateTime.UtcNow; _logger.LogInformation("Circuit breaker entering CLOSED state"); } } else if (_state == CircuitBreakerState.Closed) { // 在采样时间窗口内重置失败计数 if (DateTime.UtcNow - _lastFailureTime > _options.SamplingDuration) { _failureCount = 0; } } } } /// /// 操作失败回调 /// private void OnFailure(Exception ex, string operationName) { lock (_lock) { _failureCount++; _lastFailureTime = DateTime.UtcNow; _logger.LogWarning(ex, "Circuit breaker recorded failure #{FailureCount} for operation: {Operation}", _failureCount, operationName); if (_state == CircuitBreakerState.Closed && _failureCount >= _options.FailureThreshold) { _state = CircuitBreakerState.Open; _lastStateChangeTime = DateTime.UtcNow; _logger.LogError("Circuit breaker entering OPEN state after {FailureCount} failures", _failureCount); } else if (_state == CircuitBreakerState.HalfOpen) { _state = CircuitBreakerState.Open; _lastStateChangeTime = DateTime.UtcNow; _logger.LogWarning("Circuit breaker returning to OPEN state from HALF_OPEN due to failure"); } } } /// /// 获取当前状态信息 /// public object GetState() { lock (_lock) { return new { State = _state.ToString(), FailureCount = _failureCount, SuccessCount = _successCount, LastFailureTime = _lastFailureTime, LastStateChangeTime = _lastStateChangeTime, CanExecute = CanExecute() }; } } } /// /// 带断路器的Redis缓存装饰器 /// public class CircuitBreakerRedisCache : IRedisDistributedCache { private readonly IRedisDistributedCache _innerCache; private readonly CacheCircuitBreaker _circuitBreaker; private readonly ILogger _logger; public CircuitBreakerRedisCache( IRedisDistributedCache innerCache, CacheCircuitBreaker circuitBreaker, ILogger logger) { _innerCache = innerCache ?? throw new ArgumentNullException(nameof(innerCache)); _circuitBreaker = circuitBreaker ?? throw new ArgumentNullException(nameof(circuitBreaker)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public async Task GetAsync(string key) { try { return await _circuitBreaker.ExecuteAsync(() => _innerCache.GetAsync(key), $"GET:{key}"); } catch (CacheException) when (_circuitBreaker.State == CircuitBreakerState.Open) { _logger.LogWarning("Circuit breaker open, returning default for key: {Key}", key); return default(T); } } public async Task SetAsync(string key, T value, TimeSpan? expiry = null) { try { await _circuitBreaker.ExecuteAsync(() => _innerCache.SetAsync(key, value, expiry), $"SET:{key}"); } catch (CacheException) when (_circuitBreaker.State == CircuitBreakerState.Open) { _logger.LogWarning("Circuit breaker open, skipping cache set for key: {Key}", key); // 不继续抛出异常,允许应用继续运行 } } // 继续实现其他接口方法... public Task ExistsAsync(string key) => _circuitBreaker.ExecuteAsync(() => _innerCache.ExistsAsync(key), $"EXISTS:{key}"); public Task RemoveAsync(string key) => _circuitBreaker.ExecuteAsync(() => _innerCache.RemoveAsync(key), $"REMOVE:{key}"); public Task RemoveByPatternAsync(string pattern) => _circuitBreaker.ExecuteAsync(() => _innerCache.RemoveByPatternAsync(pattern), $"REMOVE_PATTERN:{pattern}"); public Task GetOrSetAsync(string key, Func> factory, TimeSpan? expiry = null) => _circuitBreaker.ExecuteAsync(() => _innerCache.GetOrSetAsync(key, factory, expiry), $"GET_OR_SET:{key}"); public Task> GetMultipleAsync(IEnumerable keys) => _circuitBreaker.ExecuteAsync(() => _innerCache.GetMultipleAsync(keys), "GET_MULTIPLE"); public Task SetMultipleAsync(Dictionary keyValuePairs, TimeSpan? expiry = null) => _circuitBreaker.ExecuteAsync(() => _innerCache.SetMultipleAsync(keyValuePairs, expiry), "SET_MULTIPLE"); public Task IncrementAsync(string key, long value = 1, TimeSpan? expiry = null) => _circuitBreaker.ExecuteAsync(() => _innerCache.IncrementAsync(key, value, expiry), $"INCREMENT:{key}"); public Task IncrementAsync(string key, double value, TimeSpan? expiry = null) => _circuitBreaker.ExecuteAsync(() => _innerCache.IncrementAsync(key, value, expiry), $"INCREMENT_DOUBLE:{key}"); public Task SetIfNotExistsAsync(string key, T value, TimeSpan? expiry = null) => _circuitBreaker.ExecuteAsync(() => _innerCache.SetIfNotExistsAsync(key, value, expiry), $"SET_IF_NOT_EXISTS:{key}"); public Task GetExpiryAsync(string key) => _circuitBreaker.ExecuteAsync(() => _innerCache.GetExpiryAsync(key), $"GET_EXPIRY:{key}"); public Task ExpireAsync(string key, TimeSpan expiry) => _circuitBreaker.ExecuteAsync(() => _innerCache.ExpireAsync(key, expiry), $"EXPIRE:{key}"); } /// /// LRU缓存容器,用于防止内存泄漏 /// public class LRUCache { private readonly int _maxSize; private readonly Dictionary>> _cache; private readonly LinkedList> _lruList; private readonly object _lock = new object(); public LRUCache(int maxSize) { if (maxSize <= 0) throw new ArgumentException("Max size must be greater than 0", nameof(maxSize)); _maxSize = maxSize; _cache = new Dictionary>>(maxSize); _lruList = new LinkedList>(); } public int Count { get { lock (_lock) { return _cache.Count; } } } public bool TryGet(TKey key, out TValue value) { lock (_lock) { if (_cache.TryGetValue(key, out var node)) { // 移到链表头部(最近使用) _lruList.Remove(node); _lruList.AddFirst(node); value = node.Value.Value; return true; } value = default(TValue); return false; } } public void Add(TKey key, TValue value) { lock (_lock) { if (_cache.TryGetValue(key, out var existingNode)) { // 更新已存在的项 existingNode.Value.Value = value; existingNode.Value.LastAccessed = DateTime.UtcNow; // 移到链表头部 _lruList.Remove(existingNode); _lruList.AddFirst(existingNode); } else { // 检查容量限制 if (_cache.Count >= _maxSize) { // 移除最久未使用的项 var lastNode = _lruList.Last; if (lastNode != null) { _cache.Remove(lastNode.Value.Key); _lruList.RemoveLast(); } } // 添加新项 var newItem = new CacheItem { Key = key, Value = value, LastAccessed = DateTime.UtcNow }; var newNode = _lruList.AddFirst(newItem); _cache[key] = newNode; } } } public bool Remove(TKey key) { lock (_lock) { if (_cache.TryGetValue(key, out var node)) { _cache.Remove(key); _lruList.Remove(node); return true; } return false; } } public void Clear() { lock (_lock) { _cache.Clear(); _lruList.Clear(); } } public IEnumerable Keys { get { lock (_lock) { return _cache.Keys.ToList(); } } } /// /// 清理过期项 /// public int CleanupExpired(TimeSpan maxAge) { var cutoffTime = DateTime.UtcNow - maxAge; var expiredKeys = new List(); lock (_lock) { foreach (var item in _lruList) { if (item.LastAccessed < cutoffTime) { expiredKeys.Add(item.Key); } } foreach (var key in expiredKeys) { Remove(key); } } return expiredKeys.Count; } } /// /// LRU缓存项 /// class CacheItem { public TKey Key { get; set; } public TValue Value { get; set; } public DateTime LastAccessed { get; set; } } /// /// 高级内存缓存管理器 /// 提供泛型支持、统计信息、性能监控等功能 /// public interface IAdvancedMemoryCache { Task GetOrSetAsync(string key, Func> factory, TimeSpan? expiry = null); Task GetAsync(string key); Task SetAsync(string key, T value, TimeSpan? expiry = null); Task RemoveAsync(string key); Task RemoveByPatternAsync(string pattern); CacheStatistics GetStatistics(); void ClearStatistics(); } /// /// 缓存统计信息 /// public class CacheStatistics { public long HitCount { get; set; } public long MissCount { get; set; } public long SetCount { get; set; } public long RemoveCount { get; set; } public double HitRatio => HitCount + MissCount == 0 ? 0 : (double)HitCount / (HitCount + MissCount); public DateTime StartTime { get; set; } public TimeSpan Duration => DateTime.UtcNow - StartTime; } /// /// 缓存配置选项 /// public class AdvancedMemoryCacheOptions { public int SizeLimit { get; set; } = 1000; public TimeSpan DefaultExpiry { get; set; } = TimeSpan.FromMinutes(30); public bool EnableStatistics { get; set; } = true; public bool EnablePatternRemoval { get; set; } = true; public double CompactionPercentage { get; set; } = 0.1; } /// /// 高级内存缓存实现 /// 基于IMemoryCache构建的功能增强版本 /// public class AdvancedMemoryCache : IAdvancedMemoryCache, IDisposable { private readonly IMemoryCache _cache; private readonly ILogger _logger; private readonly AdvancedMemoryCacheOptions _options; private readonly CacheStatistics _statistics; private readonly ConcurrentDictionary _keyTracker; private readonly SemaphoreSlim _semaphore; private readonly Timer _cleanupTimer; public AdvancedMemoryCache( IMemoryCache cache, ILogger logger, IOptions options) { _cache = cache ?? throw new ArgumentNullException(nameof(cache)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _options = options?.Value ?? new AdvancedMemoryCacheOptions(); _statistics = new CacheStatistics { StartTime = DateTime.UtcNow }; _keyTracker = new ConcurrentDictionary(); _semaphore = new SemaphoreSlim(1, 1); // 定期清理过期的key追踪记录 _cleanupTimer = new Timer(CleanupKeyTracker, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); } /// /// 获取或设置缓存项 /// 这是最常用的方法,实现了Cache-Aside模式 /// /// 缓存项类型 /// 缓存键 /// 数据工厂方法 /// 过期时间 /// 缓存的值 public async Task GetOrSetAsync(string key, Func> factory, TimeSpan? expiry = null) { if (string.IsNullOrEmpty(key)) throw new ArgumentException("Key cannot be null or empty", nameof(key)); if (factory == null) throw new ArgumentNullException(nameof(factory)); // 尝试从缓存获取 var cachedValue = await GetAsync(key); if (cachedValue != null) { _logger.LogDebug("Cache hit for key: {Key}", key); return cachedValue; } // 使用信号量防止并发执行相同的factory方法 await _semaphore.WaitAsync(); try { // 双重检查锁定模式 cachedValue = await GetAsync(key); if (cachedValue != null) { _logger.LogDebug("Cache hit on second check for key: {Key}", key); return cachedValue; } // 执行工厂方法获取数据 _logger.LogDebug("Cache miss for key: {Key}, executing factory method", key); var value = await factory(); // 将结果存入缓存 await SetAsync(key, value, expiry); return value; } catch (CacheConnectionException ex) { _logger.LogWarning(ex, "Cache connection failed for key: {Key}, using fallback", key); // 缓存连接失败时,仍执行工厂方法但不缓存结果 return await factory(); } catch (CacheSerializationException ex) { _logger.LogError(ex, "Serialization failed for key: {Key}", key); throw; } catch (CacheTimeoutException ex) { _logger.LogWarning(ex, "Cache operation timeout for key: {Key}", key); return await factory(); } catch (Exception ex) { _logger.LogError(ex, "Unexpected error occurred while executing factory method for key: {Key}", key); throw new CacheException($"Cache operation failed for key: {key}", ex); } finally { _semaphore.Release(); } } /// /// 异步获取缓存项 /// /// 缓存项类型 /// 缓存键 /// 缓存的值,如果不存在则返回默认值 public Task GetAsync(string key) { if (string.IsNullOrEmpty(key)) throw new ArgumentException("Key cannot be null or empty", nameof(key)); var found = _cache.TryGetValue(key, out var value); if (_options.EnableStatistics) { if (found) Interlocked.Increment(ref _statistics.HitCount); else Interlocked.Increment(ref _statistics.MissCount); } if (found && value is T typedValue) { return Task.FromResult(typedValue); } return Task.FromResult(default(T)); } /// /// 异步设置缓存项 /// /// 缓存项类型 /// 缓存键 /// 缓存值 /// 过期时间 public Task SetAsync(string key, T value, TimeSpan? expiry = null) { if (string.IsNullOrEmpty(key)) throw new ArgumentException("Key cannot be null or empty", nameof(key)); var cacheExpiry = expiry ?? _options.DefaultExpiry; using var entry = _cache.CreateEntry(key); entry.Value = value; entry.AbsoluteExpirationRelativeToNow = cacheExpiry; entry.Size = 1; // 简化的大小计算,实际应用中可根据对象大小设置 // 设置过期回调 entry.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration { EvictionCallback = OnCacheEntryEvicted, State = key }); // 追踪缓存键 if (_options.EnablePatternRemoval) { _keyTracker.TryAdd(key, 0); } if (_options.EnableStatistics) { Interlocked.Increment(ref _statistics.SetCount); } _logger.LogDebug("Set cache entry for key: {Key}, expiry: {Expiry}", key, cacheExpiry); return Task.CompletedTask; } /// /// 异步移除缓存项 /// /// 缓存键 public Task RemoveAsync(string key) { if (string.IsNullOrEmpty(key)) throw new ArgumentException("Key cannot be null or empty", nameof(key)); _cache.Remove(key); _keyTracker.TryRemove(key, out _); if (_options.EnableStatistics) { Interlocked.Increment(ref _statistics.RemoveCount); } _logger.LogDebug("Removed cache entry for key: {Key}", key); return Task.CompletedTask; } /// /// 根据模式异步移除缓存项 /// 支持通配符匹配,如 "user:*", "*:settings" /// /// 匹配模式 public async Task RemoveByPatternAsync(string pattern) { if (string.IsNullOrEmpty(pattern)) throw new ArgumentException("Pattern cannot be null or empty", nameof(pattern)); if (!_options.EnablePatternRemoval) { _logger.LogWarning("Pattern removal is disabled"); return; } var keysToRemove = new List(); var regexPattern = ConvertWildcardToRegex(pattern); var regex = new System.Text.RegularExpressions.Regex(regexPattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase); foreach (var key in _keyTracker.Keys) { if (regex.IsMatch(key)) { keysToRemove.Add(key); } } foreach (var key in keysToRemove)
if (visited.Contains(obj))
visited.Add(obj);
// 简化的循环检测,只检查一层
var type = obj.GetType();
if (type.IsPrimitive || type == typeof(string))
visited.Remove(obj);
/// 安全缓存管理器装饰器
public class SecureCacheManagerDecorator : IAdvancedMemoryCache
private readonly IAdvancedMemoryCache _innerCache;
private readonly ICacheDataValidator _validator;
public SecureCacheManagerDecorator(
IAdvancedMemoryCache innerCache,
ICacheDataValidator validator,
ILogger logger)
_innerCache = innerCache ?? throw new ArgumentNullException(nameof(innerCache));
_validator = validator ?? throw new ArgumentNullException(nameof(validator));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
public async Task GetOrSetAsync(string key, Func> factory, TimeSpan? expiry = null)
_validator.ValidateKey(key);
return await _innerCache.GetOrSetAsync(key, async () =>
var value = await factory();
if (!_validator.IsValid(value))
throw new CacheValidationException($"Invalid cache value for key: {key}");
return value;
}, expiry);
public async Task GetAsync(string key)
return await _innerCache.GetAsync(key);
public async Task SetAsync(string key, T value, TimeSpan? expiry = null)
if (!_validator.IsSafeForSerialization(value))
_logger.LogWarning("Potentially unsafe serialization for key: {Key}, type: {Type}",
key, value?.GetType().Name);
await _innerCache.SetAsync(key, value, expiry);
public async Task RemoveAsync(string key)
await _innerCache.RemoveAsync(key);
public async Task RemoveByPatternAsync(string pattern)
if (string.IsNullOrWhiteSpace(pattern))
throw new CacheValidationException("Pattern cannot be null or empty");
await _innerCache.RemoveByPatternAsync(pattern);
public CacheStatistics GetStatistics() => _innerCache.GetStatistics();
public void ClearStatistics() => _innerCache.ClearStatistics();
/// 序列化器接口
public interface ICacheSerializer
byte[] Serialize(T value);
T Deserialize(byte[] data);
string SerializerName { get; }
bool SupportsType(Type type);
/// JSON序列化器(默认)
public class JsonCacheSerializer : ICacheSerializer
private readonly JsonSerializerOptions _options;
public string SerializerName => "JSON";
public JsonCacheSerializer()
_options = new JsonSerializerOptions
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = false,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNameCaseInsensitive = true
public byte[] Serialize(T value)
if (value == null) return null;
if (typeof(T) == typeof(string)) return System.Text.Encoding.UTF8.GetBytes(value.ToString());
var json = JsonSerializer.Serialize(value, _options);
return System.Text.Encoding.UTF8.GetBytes(json);
public T Deserialize(byte[] data)
if (data == null || data.Length == 0) return default(T);
if (typeof(T) == typeof(string)) return (T)(object)System.Text.Encoding.UTF8.GetString(data);
var json = System.Text.Encoding.UTF8.GetString(data);
return JsonSerializer.Deserialize(json, _options);
public bool SupportsType(Type type)
return true; // JSON支持所有类型
/// 二进制序列化器(用于简单类型)
public class BinaryCacheSerializer : ICacheSerializer
public string SerializerName => "Binary";
private static readonly HashSet SupportedTypes = new()
typeof(int), typeof(long), typeof(double), typeof(float),
typeof(bool), typeof(byte), typeof(short),
typeof(DateTime), typeof(DateTimeOffset), typeof(TimeSpan),
typeof(Guid), typeof(decimal)
var type = typeof(T);
// 专门处理常见类型,提高性能
return type switch
_ when type == typeof(int) => BitConverter.GetBytes((int)(object)value),
_ when type == typeof(long) => BitConverter.GetBytes((long)(object)value),
_ when type == typeof(double) => BitConverter.GetBytes((double)(object)value),
_ when type == typeof(float) => BitConverter.GetBytes((float)(object)value),
_ when type == typeof(bool) => BitConverter.GetBytes((bool)(object)value),
_ when type == typeof(DateTime) => BitConverter.GetBytes(((DateTime)(object)value).ToBinary()),
_ when type == typeof(Guid) => ((Guid)(object)value).ToByteArray(),
_ when type == typeof(string) => System.Text.Encoding.UTF8.GetBytes(value.ToString()),
_ => throw new NotSupportedException($"Type {type.Name} is not supported by BinaryCacheSerializer")
object result = type switch
_ when type == typeof(int) => BitConverter.ToInt32(data, 0),
_ when type == typeof(long) => BitConverter.ToInt64(data, 0),
_ when type == typeof(double) => BitConverter.ToDouble(data, 0),
_ when type == typeof(float) => BitConverter.ToSingle(data, 0),
_ when type == typeof(bool) => BitConverter.ToBoolean(data, 0),
_ when type == typeof(DateTime) => DateTime.FromBinary(BitConverter.ToInt64(data, 0)),
_ when type == typeof(Guid) => new Guid(data),
_ when type == typeof(string) => System.Text.Encoding.UTF8.GetString(data),
return (T)result;
return SupportedTypes.Contains(type) || type == typeof(string);
/// 智能序列化器管理器
public class SmartCacheSerializer : ICacheSerializer
private readonly ICacheSerializer[] _serializers;
public string SerializerName => "Smart";
public SmartCacheSerializer(ILogger logger)
_serializers = new ICacheSerializer[]
new BinaryCacheSerializer(), // 优先使用二进制序列化
new JsonCacheSerializer() // 备选JSON序列化
foreach (var serializer in _serializers)
if (serializer.SupportsType(type))
try
var data = serializer.Serialize(value);
// 在数据开头添加序列化器标识
var header = System.Text.Encoding.UTF8.GetBytes(serializer.SerializerName.PadRight(8));
var result = new byte[header.Length + data.Length];
Array.Copy(header, 0, result, 0, header.Length);
Array.Copy(data, 0, result, header.Length, data.Length);
return result;
catch (Exception ex)
_logger.LogWarning(ex, "Serializer {SerializerName} failed for type {TypeName}",
serializer.SerializerName, type.Name);
continue;
throw new CacheSerializationException($"No suitable serializer found for type: {type.Name}");
if (data == null || data.Length < 8) return default(T);
// 读取序列化器标识
var headerBytes = new byte[8];
Array.Copy(data, 0, headerBytes, 0, 8);
var serializerName = System.Text.Encoding.UTF8.GetString(headerBytes).Trim();
// 获取实际数据
var actualData = new byte[data.Length - 8];
Array.Copy(data, 8, actualData, 0, actualData.Length);
// 找到对应的序列化器
var serializer = _serializers.FirstOrDefault(s => s.SerializerName == serializerName);
if (serializer == null)
_logger.LogWarning("Unknown serializer: {SerializerName}, falling back to JSON", serializerName);
serializer = new JsonCacheSerializer();
return serializer.Deserialize(actualData);
_logger.LogError(ex, "Failed to deserialize with {SerializerName}", serializerName);
throw new CacheSerializationException($"Deserialization failed with {serializerName}", ex);
return _serializers.Any(s => s.SupportsType(type));
/// 断路器状态
public enum CircuitBreakerState
Closed, // 正常状态
Open, // 断路器打开,拒绝请求
HalfOpen // 半开状态,允许少量请求通过
/// 缓存断路器配置
public class CacheCircuitBreakerOptions
public int FailureThreshold { get; set; } = 5; // 连续失败阈值
public TimeSpan OpenTimeout { get; set; } = TimeSpan.FromMinutes(1); // 断路器打开时间
public int SuccessThreshold { get; set; } = 2; // 半开状态成功阈值
public TimeSpan SamplingDuration { get; set; } = TimeSpan.FromMinutes(2); // 采样时间窗口
/// 缓存断路器
public class CacheCircuitBreaker
private readonly CacheCircuitBreakerOptions _options;
private CircuitBreakerState _state = CircuitBreakerState.Closed;
private int _failureCount = 0;
private int _successCount = 0;
private DateTime _lastFailureTime = DateTime.MinValue;
private DateTime _lastStateChangeTime = DateTime.UtcNow;
public CacheCircuitBreaker(
CacheCircuitBreakerOptions options,
_options = options ?? throw new ArgumentNullException(nameof(options));
public CircuitBreakerState State => _state;
/// 执行带断路器保护的操作
public async Task ExecuteAsync(Func> operation, string operationName = null)
if (!CanExecute())
throw new CacheException($"Circuit breaker is OPEN for operation: {operationName}");
var result = await operation();
OnSuccess();
OnFailure(ex, operationName);
throw;
/// 检查是否可以执行操作
private bool CanExecute()
switch (_state)
case CircuitBreakerState.Closed:
case CircuitBreakerState.Open:
// 检查是否可以转入半开状态
if (DateTime.UtcNow - _lastStateChangeTime >= _options.OpenTimeout)
_state = CircuitBreakerState.HalfOpen;
_successCount = 0;
_lastStateChangeTime = DateTime.UtcNow;
_logger.LogInformation("Circuit breaker entering HALF_OPEN state");
case CircuitBreakerState.HalfOpen:
default:
/// 操作成功回调
private void OnSuccess()
if (_state == CircuitBreakerState.HalfOpen)
_successCount++;
if (_successCount >= _options.SuccessThreshold)
_state = CircuitBreakerState.Closed;
_failureCount = 0;
_logger.LogInformation("Circuit breaker entering CLOSED state");
else if (_state == CircuitBreakerState.Closed)
// 在采样时间窗口内重置失败计数
if (DateTime.UtcNow - _lastFailureTime > _options.SamplingDuration)
/// 操作失败回调
private void OnFailure(Exception ex, string operationName)
_failureCount++;
_lastFailureTime = DateTime.UtcNow;
_logger.LogWarning(ex, "Circuit breaker recorded failure #{FailureCount} for operation: {Operation}",
_failureCount, operationName);
if (_state == CircuitBreakerState.Closed && _failureCount >= _options.FailureThreshold)
_state = CircuitBreakerState.Open;
_logger.LogError("Circuit breaker entering OPEN state after {FailureCount} failures", _failureCount);
else if (_state == CircuitBreakerState.HalfOpen)
_logger.LogWarning("Circuit breaker returning to OPEN state from HALF_OPEN due to failure");
/// 获取当前状态信息
public object GetState()
return new
State = _state.ToString(),
FailureCount = _failureCount,
SuccessCount = _successCount,
LastFailureTime = _lastFailureTime,
LastStateChangeTime = _lastStateChangeTime,
CanExecute = CanExecute()
/// 带断路器的Redis缓存装饰器
public class CircuitBreakerRedisCache : IRedisDistributedCache
private readonly IRedisDistributedCache _innerCache;
private readonly CacheCircuitBreaker _circuitBreaker;
public CircuitBreakerRedisCache(
IRedisDistributedCache innerCache,
CacheCircuitBreaker circuitBreaker,
_circuitBreaker = circuitBreaker ?? throw new ArgumentNullException(nameof(circuitBreaker));
return await _circuitBreaker.ExecuteAsync(() => _innerCache.GetAsync(key), $"GET:{key}");
catch (CacheException) when (_circuitBreaker.State == CircuitBreakerState.Open)
_logger.LogWarning("Circuit breaker open, returning default for key: {Key}", key);
return default(T);
await _circuitBreaker.ExecuteAsync(() => _innerCache.SetAsync(key, value, expiry), $"SET:{key}");
_logger.LogWarning("Circuit breaker open, skipping cache set for key: {Key}", key);
// 不继续抛出异常,允许应用继续运行
// 继续实现其他接口方法...
public Task ExistsAsync(string key) =>
_circuitBreaker.ExecuteAsync(() => _innerCache.ExistsAsync(key), $"EXISTS:{key}");
public Task RemoveAsync(string key) =>
_circuitBreaker.ExecuteAsync(() => _innerCache.RemoveAsync(key), $"REMOVE:{key}");
public Task RemoveByPatternAsync(string pattern) =>
_circuitBreaker.ExecuteAsync(() => _innerCache.RemoveByPatternAsync(pattern), $"REMOVE_PATTERN:{pattern}");
public Task GetOrSetAsync(string key, Func> factory, TimeSpan? expiry = null) =>
_circuitBreaker.ExecuteAsync(() => _innerCache.GetOrSetAsync(key, factory, expiry), $"GET_OR_SET:{key}");
public Task> GetMultipleAsync(IEnumerable keys) =>
_circuitBreaker.ExecuteAsync(() => _innerCache.GetMultipleAsync(keys), "GET_MULTIPLE");
public Task SetMultipleAsync(Dictionary keyValuePairs, TimeSpan? expiry = null) =>
_circuitBreaker.ExecuteAsync(() => _innerCache.SetMultipleAsync(keyValuePairs, expiry), "SET_MULTIPLE");
public Task IncrementAsync(string key, long value = 1, TimeSpan? expiry = null) =>
_circuitBreaker.ExecuteAsync(() => _innerCache.IncrementAsync(key, value, expiry), $"INCREMENT:{key}");
public Task IncrementAsync(string key, double value, TimeSpan? expiry = null) =>
_circuitBreaker.ExecuteAsync(() => _innerCache.IncrementAsync(key, value, expiry), $"INCREMENT_DOUBLE:{key}");
public Task SetIfNotExistsAsync(string key, T value, TimeSpan? expiry = null) =>
_circuitBreaker.ExecuteAsync(() => _innerCache.SetIfNotExistsAsync(key, value, expiry), $"SET_IF_NOT_EXISTS:{key}");
public Task GetExpiryAsync(string key) =>
_circuitBreaker.ExecuteAsync(() => _innerCache.GetExpiryAsync(key), $"GET_EXPIRY:{key}");
public Task ExpireAsync(string key, TimeSpan expiry) =>
_circuitBreaker.ExecuteAsync(() => _innerCache.ExpireAsync(key, expiry), $"EXPIRE:{key}");
/// LRU缓存容器,用于防止内存泄漏
public class LRUCache
private readonly int _maxSize;
private readonly Dictionary>> _cache;
private readonly LinkedList> _lruList;
public LRUCache(int maxSize)
if (maxSize <= 0)
throw new ArgumentException("Max size must be greater than 0", nameof(maxSize));
_maxSize = maxSize;
_cache = new Dictionary>>(maxSize);
_lruList = new LinkedList>();
public int Count
get
return _cache.Count;
public bool TryGet(TKey key, out TValue value)
if (_cache.TryGetValue(key, out var node))
// 移到链表头部(最近使用)
_lruList.Remove(node);
_lruList.AddFirst(node);
value = node.Value.Value;
value = default(TValue);
public void Add(TKey key, TValue value)
if (_cache.TryGetValue(key, out var existingNode))
// 更新已存在的项
existingNode.Value.Value = value;
existingNode.Value.LastAccessed = DateTime.UtcNow;
// 移到链表头部
_lruList.Remove(existingNode);
_lruList.AddFirst(existingNode);
else
// 检查容量限制
if (_cache.Count >= _maxSize)
// 移除最久未使用的项
var lastNode = _lruList.Last;
if (lastNode != null)
_cache.Remove(lastNode.Value.Key);
_lruList.RemoveLast();
// 添加新项
var newItem = new CacheItem
Key = key,
Value = value,
LastAccessed = DateTime.UtcNow
var newNode = _lruList.AddFirst(newItem);
_cache[key] = newNode;
public bool Remove(TKey key)
_cache.Remove(key);
public void Clear()
_cache.Clear();
_lruList.Clear();
public IEnumerable Keys
return _cache.Keys.ToList();
/// 清理过期项
public int CleanupExpired(TimeSpan maxAge)
var cutoffTime = DateTime.UtcNow - maxAge;
var expiredKeys = new List();
foreach (var item in _lruList)
if (item.LastAccessed < cutoffTime)
expiredKeys.Add(item.Key);
foreach (var key in expiredKeys)
Remove(key);
return expiredKeys.Count;
/// LRU缓存项
class CacheItem
public TKey Key { get; set; }
public TValue Value { get; set; }
public DateTime LastAccessed { get; set; }
/// 高级内存缓存管理器
/// 提供泛型支持、统计信息、性能监控等功能
public interface IAdvancedMemoryCache
Task GetOrSetAsync(string key, Func> factory, TimeSpan? expiry = null);
Task GetAsync(string key);
Task SetAsync(string key, T value, TimeSpan? expiry = null);
Task RemoveAsync(string key);
Task RemoveByPatternAsync(string pattern);
CacheStatistics GetStatistics();
void ClearStatistics();
/// 缓存统计信息
public class CacheStatistics
public long HitCount { get; set; }
public long MissCount { get; set; }
public long SetCount { get; set; }
public long RemoveCount { get; set; }
public double HitRatio => HitCount + MissCount == 0 ? 0 : (double)HitCount / (HitCount + MissCount);
public DateTime StartTime { get; set; }
public TimeSpan Duration => DateTime.UtcNow - StartTime;
/// 缓存配置选项
public class AdvancedMemoryCacheOptions
public int SizeLimit { get; set; } = 1000;
public TimeSpan DefaultExpiry { get; set; } = TimeSpan.FromMinutes(30);
public bool EnableStatistics { get; set; } = true;
public bool EnablePatternRemoval { get; set; } = true;
public double CompactionPercentage { get; set; } = 0.1;
/// 高级内存缓存实现
/// 基于IMemoryCache构建的功能增强版本
public class AdvancedMemoryCache : IAdvancedMemoryCache, IDisposable
private readonly IMemoryCache _cache;
private readonly AdvancedMemoryCacheOptions _options;
private readonly CacheStatistics _statistics;
private readonly ConcurrentDictionary _keyTracker;
private readonly SemaphoreSlim _semaphore;
private readonly Timer _cleanupTimer;
public AdvancedMemoryCache(
IMemoryCache cache,
ILogger logger,
IOptions options)
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
_options = options?.Value ?? new AdvancedMemoryCacheOptions();
_statistics = new CacheStatistics { StartTime = DateTime.UtcNow };
_keyTracker = new ConcurrentDictionary();
_semaphore = new SemaphoreSlim(1, 1);
// 定期清理过期的key追踪记录
_cleanupTimer = new Timer(CleanupKeyTracker, null,
TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
/// 获取或设置缓存项
/// 这是最常用的方法,实现了Cache-Aside模式
/// 缓存项类型
/// 缓存键
/// 数据工厂方法
/// 过期时间
/// 缓存的值
if (string.IsNullOrEmpty(key))
throw new ArgumentException("Key cannot be null or empty", nameof(key));
if (factory == null)
throw new ArgumentNullException(nameof(factory));
// 尝试从缓存获取
var cachedValue = await GetAsync(key);
if (cachedValue != null)
_logger.LogDebug("Cache hit for key: {Key}", key);
return cachedValue;
// 使用信号量防止并发执行相同的factory方法
await _semaphore.WaitAsync();
// 双重检查锁定模式
cachedValue = await GetAsync(key);
_logger.LogDebug("Cache hit on second check for key: {Key}", key);
// 执行工厂方法获取数据
_logger.LogDebug("Cache miss for key: {Key}, executing factory method", key);
// 将结果存入缓存
await SetAsync(key, value, expiry);
catch (CacheConnectionException ex)
_logger.LogWarning(ex, "Cache connection failed for key: {Key}, using fallback", key);
// 缓存连接失败时,仍执行工厂方法但不缓存结果
return await factory();
catch (CacheSerializationException ex)
_logger.LogError(ex, "Serialization failed for key: {Key}", key);
catch (CacheTimeoutException ex)
_logger.LogWarning(ex, "Cache operation timeout for key: {Key}", key);
_logger.LogError(ex, "Unexpected error occurred while executing factory method for key: {Key}", key);
throw new CacheException($"Cache operation failed for key: {key}", ex);
finally
_semaphore.Release();
/// 异步获取缓存项
/// 缓存的值,如果不存在则返回默认值
public Task GetAsync(string key)
var found = _cache.TryGetValue(key, out var value);
if (_options.EnableStatistics)
if (found)
Interlocked.Increment(ref _statistics.HitCount);
Interlocked.Increment(ref _statistics.MissCount);
if (found && value is T typedValue)
return Task.FromResult(typedValue);
return Task.FromResult(default(T));
/// 异步设置缓存项
/// 缓存值
public Task SetAsync(string key, T value, TimeSpan? expiry = null)
var cacheExpiry = expiry ?? _options.DefaultExpiry;
using var entry = _cache.CreateEntry(key);
entry.Value = value;
entry.AbsoluteExpirationRelativeToNow = cacheExpiry;
entry.Size = 1; // 简化的大小计算,实际应用中可根据对象大小设置
// 设置过期回调
entry.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration
EvictionCallback = OnCacheEntryEvicted,
State = key
});
// 追踪缓存键
if (_options.EnablePatternRemoval)
_keyTracker.TryAdd(key, 0);
Interlocked.Increment(ref _statistics.SetCount);
_logger.LogDebug("Set cache entry for key: {Key}, expiry: {Expiry}", key, cacheExpiry);
return Task.CompletedTask;
/// 异步移除缓存项
public Task RemoveAsync(string key)
_keyTracker.TryRemove(key, out _);
Interlocked.Increment(ref _statistics.RemoveCount);
_logger.LogDebug("Removed cache entry for key: {Key}", key);
/// 根据模式异步移除缓存项
/// 支持通配符匹配,如 "user:*", "*:settings"
/// 匹配模式
if (string.IsNullOrEmpty(pattern))
throw new ArgumentException("Pattern cannot be null or empty", nameof(pattern));
if (!_options.EnablePatternRemoval)
_logger.LogWarning("Pattern removal is disabled");
return;
var keysToRemove = new List();
var regexPattern = ConvertWildcardToRegex(pattern);
var regex = new System.Text.RegularExpressions.Regex(regexPattern,
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
foreach (var key in _keyTracker.Keys)
if (regex.IsMatch(key))
keysToRemove.Add(key);
foreach (var key in keysToRemove)
更多推荐
机器学习与人工智能
python# 创建基类# 定义一对多关系# 定义多对一关系# 定义多对多关系(通过关联表)# 关联表(用于多对多关系)SQLAlchemy ORM提供了强大而灵活的数据库操作方式,通过本文的介绍,您应该能够:安装和配置SQLAlchemy定义数据模型和关系执行基本的CRUD操作构建复杂查询管理数据库事务遵循最佳实践SQLAlchemy还有更多高级特性,如混合属性、事件监听、自定义查询等,值得进一
【ASP.NET类中方法无法显示的原因与解决办法】,回郧晾揽扇
大模型时代的上下文工程:让AI更懂你-摘要
扫一扫分享内容
所有评论(0)