#region using StackExchange.Redis; using Web.Core.Common.Helper; #endregion namespace Web.Core.Common.Redis; public class RedisCacheManager : IRedisCacheManager { private readonly string redisConnenctionString; private readonly string DefaultKey; //默认的 Key 值(用来当作 RedisKey 的前缀) public volatile ConnectionMultiplexer redisConnection; private readonly IDatabase _db; private readonly object redisConnectionLock = new(); public RedisCacheManager() { var redisConfiguration = AppSettings.GetConnectionString("Redis"); //获取连接字符串 var dbnum = AppSettings.GetValue("RedisInfo:DefaultDB", 15); if (string.IsNullOrWhiteSpace(redisConfiguration)) { throw new ArgumentException("redis config is empty", nameof(redisConfiguration)); } redisConnenctionString = redisConfiguration; redisConnection = GetRedisConnection(); _db = redisConnection.GetDatabase(dbnum); DefaultKey = AppSettings.GetLogLevel("RedisInfo:DefaultKey"); } /// /// 核心代码,获取连接实例 /// 通过双if 夹lock的方式,实现单例模式 /// /// private ConnectionMultiplexer GetRedisConnection() { //如果已经连接实例,直接返回 if (redisConnection != null && redisConnection.IsConnected) { return redisConnection; } //加锁,防止异步编程中,出现单例无效的问题 lock (redisConnectionLock) { if (redisConnection != null) { //释放redis连接 redisConnection.Dispose(); } try { redisConnection = ConnectionMultiplexer.Connect(redisConnenctionString); } catch (Exception) { throw new Exception("Redis服务未启用,请开启该服务"); } } return redisConnection; } /// /// 添加 Key 的前缀 /// /// /// private string AddKeyPrefix(string key) { return $"{DefaultKey}:{key}"; } public void Clear() { foreach (var endPoint in GetRedisConnection().GetEndPoints()) { var server = GetRedisConnection().GetServer(endPoint); foreach (var key in server.Keys()) { _db.KeyDelete(key); } } } public bool Get(string key) { return _db.KeyExists(AddKeyPrefix(key)); } public string GetValue(string key) { return _db.StringGet(key); } public TEntity Get(string key) { var value = _db.StringGet(key); if (value.HasValue) { //需要用的反序列化,将Redis存储的Byte[],进行反序列化 return SerializeHelper.Deserialize(value); } else { return default; } } public void Remove(string key) { _db.KeyDelete(AddKeyPrefix(key)); } public void Set(string key, object value, TimeSpan cacheTime) { if (value != null) { //序列化,将object值生成RedisValue //_db.StringSet(AddKeyPrefix(key), SerializeHelper.Serialize(value), cacheTime); _db.StringSet(key, SerializeHelper.Serialize(value), cacheTime); } } public bool SetValue(string key, byte[] value) { return _db.StringSet(AddKeyPrefix(key), value, TimeSpan.FromSeconds(120)); } public async Task ClearAsync() { foreach (var endPoint in GetRedisConnection().GetEndPoints()) { var server = GetRedisConnection().GetServer(endPoint); foreach (var key in server.Keys()) { await _db.KeyDeleteAsync(key); } } } public async Task GetAsync(string key) { return await _db.KeyExistsAsync(AddKeyPrefix(key)); } public async Task GetValueAsync(string key) { return await _db.StringGetAsync(AddKeyPrefix(key)); } public async Task GetAsync(string key) { var value = await _db.StringGetAsync(AddKeyPrefix(key)); if (value.HasValue) { //需要用的反序列化,将Redis存储的Byte[],进行反序列化 return SerializeHelper.Deserialize(value); } else { return default; } } public async Task RemoveAsync(string key) { await _db.KeyDeleteAsync(AddKeyPrefix(key)); } public async Task RemoveByKey(string key) { var redisResult = await _db.ScriptEvaluateAsync(LuaScript.Prepare( //Redis的keys模糊查询: " local res = redis.call('KEYS', @keypattern) " + " return res "), new { @keypattern = AddKeyPrefix(key) }); if (!redisResult.IsNull) { var keys = (string[])redisResult; foreach (var k in keys) _db.KeyDelete(k); } } public async Task SetAsync(string key, object value, TimeSpan cacheTime) { if (value != null) { //序列化,将object值生成RedisValue await _db.StringSetAsync(AddKeyPrefix(key), SerializeHelper.Serialize(value), cacheTime); } } public async Task SetValueAsync(string key, byte[] value) { return await _db.StringSetAsync(AddKeyPrefix(key), value, TimeSpan.FromSeconds(120)); } #region set帮助 /// /// Set新增 /// /// /// /// public bool SetAdd(string redisKey, string member,bool IgnorePrefix=false) { redisKey = IgnorePrefix?redisKey:AddKeyPrefix(redisKey); return _db.SetAdd(redisKey, member); } /// /// Set新增 /// /// /// /// public async Task SetAddAsync(string redisKey, string member,bool IgnorePrefix=false) { redisKey = IgnorePrefix?redisKey:AddKeyPrefix(redisKey); return await _db.SetAddAsync(redisKey, member); } /// /// Set判断元素是否包含 /// /// /// /// public bool SetContains(string redisKey, string member,bool IgnorePrefix=false) { redisKey = IgnorePrefix?redisKey:AddKeyPrefix(redisKey); return _db.SetContains(redisKey, member); } /// /// Set判断元素是否包含 /// /// /// /// public async Task SetContainsAsync(string redisKey, string member,bool IgnorePrefix=false) { redisKey = IgnorePrefix?redisKey:AddKeyPrefix(redisKey); return await _db.SetContainsAsync(redisKey, member); } /// /// Set移除元素 /// /// /// /// public bool SetRemove(string redisKey, string member,bool IgnorePrefix=false) { redisKey = IgnorePrefix?redisKey:AddKeyPrefix(redisKey); return _db.SetRemove(redisKey, member); } /// /// Set移除元素 /// /// /// /// public async Task SetRemoveAsync(string redisKey, string member,bool IgnorePrefix=false) { redisKey = IgnorePrefix?redisKey:AddKeyPrefix(redisKey); return await _db.SetRemoveAsync(redisKey, member); } #endregion }