ExternalAPI_NET8/Common/Redis/RedisCacheManager.cs
2026-05-21 17:23:36 +08:00

280 lines
8.0 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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");
}
/// <summary>
/// 核心代码,获取连接实例
/// 通过双if 夹lock的方式实现单例模式
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
/// 添加 Key 的前缀
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
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<TEntity>(string key)
{
var value = _db.StringGet(key);
if (value.HasValue)
{
//需要用的反序列化将Redis存储的Byte[],进行反序列化
return SerializeHelper.Deserialize<TEntity>(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<bool> GetAsync(string key)
{
return await _db.KeyExistsAsync(AddKeyPrefix(key));
}
public async Task<string> GetValueAsync(string key)
{
return await _db.StringGetAsync(AddKeyPrefix(key));
}
public async Task<TEntity> GetAsync<TEntity>(string key)
{
var value = await _db.StringGetAsync(AddKeyPrefix(key));
if (value.HasValue)
{
//需要用的反序列化将Redis存储的Byte[],进行反序列化
return SerializeHelper.Deserialize<TEntity>(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<bool> SetValueAsync(string key, byte[] value)
{
return await _db.StringSetAsync(AddKeyPrefix(key), value, TimeSpan.FromSeconds(120));
}
#region set帮助
/// <summary>
/// Set新增
/// </summary>
/// <param name="redisKey"></param>
/// <param name="member"></param>
/// <returns></returns>
public bool SetAdd(string redisKey, string member,bool IgnorePrefix=false)
{
redisKey = IgnorePrefix?redisKey:AddKeyPrefix(redisKey);
return _db.SetAdd(redisKey, member);
}
/// <summary>
/// Set新增
/// </summary>
/// <param name="redisKey"></param>
/// <param name="member"></param>
/// <returns></returns>
public async Task<bool> SetAddAsync(string redisKey, string member,bool IgnorePrefix=false)
{
redisKey = IgnorePrefix?redisKey:AddKeyPrefix(redisKey);
return await _db.SetAddAsync(redisKey, member);
}
/// <summary>
/// Set判断元素是否包含
/// </summary>
/// <param name="redisKey"></param>
/// <param name="member"></param>
/// <returns></returns>
public bool SetContains(string redisKey, string member,bool IgnorePrefix=false)
{
redisKey = IgnorePrefix?redisKey:AddKeyPrefix(redisKey);
return _db.SetContains(redisKey, member);
}
/// <summary>
/// Set判断元素是否包含
/// </summary>
/// <param name="redisKey"></param>
/// <param name="member"></param>
/// <returns></returns>
public async Task<bool> SetContainsAsync(string redisKey, string member,bool IgnorePrefix=false)
{
redisKey = IgnorePrefix?redisKey:AddKeyPrefix(redisKey);
return await _db.SetContainsAsync(redisKey, member);
}
/// <summary>
/// Set移除元素
/// </summary>
/// <param name="redisKey"></param>
/// <param name="member"></param>
/// <returns></returns>
public bool SetRemove(string redisKey, string member,bool IgnorePrefix=false)
{
redisKey = IgnorePrefix?redisKey:AddKeyPrefix(redisKey);
return _db.SetRemove(redisKey, member);
}
/// <summary>
/// Set移除元素
/// </summary>
/// <param name="redisKey"></param>
/// <param name="member"></param>
/// <returns></returns>
public async Task<bool> SetRemoveAsync(string redisKey, string member,bool IgnorePrefix=false)
{
redisKey = IgnorePrefix?redisKey:AddKeyPrefix(redisKey);
return await _db.SetRemoveAsync(redisKey, member);
}
#endregion
}