using LY.App.Extensions.DI; using StackExchange.Redis; using System.Text.Json; namespace LY.App.Common.Redis { /// /// redis 连接服务 /// public class RedisService { private readonly IDatabase _db; private readonly IServer _redis; /// /// 构造函数 /// /// public RedisService(string connectionString) { var redis = ConnectionMultiplexer.Connect(connectionString); _db = redis.GetDatabase(); } /// /// 泛型存储数据到 Redis /// public async Task SetAsync(string key, T value, TimeSpan? expiry = null) { string jsonData = JsonSerializer.Serialize(value); return await _db.StringSetAsync(key, jsonData, expiry); } /// /// 泛型获取数据 /// public async Task GetAsync(string key) { string jsonData = await _db.StringGetAsync(key); return jsonData is not null ? JsonSerializer.Deserialize(jsonData) : default; } /// /// 模糊 查询所有 Key /// /// /// public Task> GetAllKeysAsync(string pattern) { var redis = _db.Multiplexer; var keys = new List(); foreach (var endPoint in redis.GetEndPoints()) { var server = redis.GetServer(endPoint); if (!server.IsConnected) continue; // 使用 SCAN 获取匹配的 key,避免 KEYS 阻塞 var scanKeys = server.Keys(pattern: pattern, pageSize: 1000); keys.AddRange(scanKeys); } return Task.FromResult(keys); //var result = new Dictionary(); //if (keys.Count > 0) //{ // // 一次批量获取 value // var values = await _db.StringGetAsync(keys.ToArray()); // for (int i = 0; i < keys.Count; i++) // { // if (values[i].HasValue) // { // result[keys[i]] = values[i]; // } // } //} //return result; } /// /// 删除 Key /// public async Task DeleteAsync(string key) { return await _db.KeyDeleteAsync(key); } /// /// 检查 Key 是否存在 /// public async Task ExistsAsync(string key) { return await _db.KeyExistsAsync(key); } /// /// 获取数据,如果不存在则从数据源获取并存入 Redis /// /// 数据类型 /// Redis Key /// 数据源方法 /// 可选的过期时间 /// 获取到的值 public async Task GetOrSetAsync(string key, Func> factory, TimeSpan? expiry = null) { var value = await GetAsync(key); if (value is not null) { return value; } value = await factory(); if (value is not null) { await SetAsync(key, value, expiry); } return value; } } }