编辑 | blame | 历史 | 原始文档

Redis 服务使用案例

1. 缓存(ICacheService)- 基础操作

通过构造函数注入 ICacheService,HybridCacheService 自动实现 L1(内存) + L2(Redis) 双层缓存。

public class MyService
{
    private readonly ICacheService _cache;

    public MyService(ICacheService cache)
    {
        _cache = cache;
    }

    // 缓存字符串,60秒过期
    public void CacheString()
    {
        _cache.Add("token:10001", "abc123", 60);
        var token = _cache.Get("token:10001");
    }

    // 缓存对象
    public void CacheObject()
    {
        var user = new { Id = 1, Name = "张三" };
        _cache.AddObject("user:1", user, 300);
        var cached = _cache.Get<dynamic>("user:1");
    }

    // 删除缓存
    public void RemoveCache()
    {
        _cache.Remove("user:1");
        _cache.Remove(new[] { "token:10001", "token:10002" });
    }
}

2. 缓存(ICacheService)- 扩展删除方法

public class CacheDeleteDemo
{
    private readonly ICacheService _cache;

    // 删除并获取值
    public string? RemoveAndGet(string key)
    {
        return _cache.RemoveAndGet(key); // 返回被删除的值
    }

    // 按前缀删除所有匹配的key
    public int ClearUserCache()
    {
        return _cache.RemoveByPrefix("user:"); // 删除所有 user: 开头的key
    }

    // 按模式删除(支持通配符)
    public int ClearSessionCache()
    {
        return _cache.RemoveByPattern("session:123:*"); // 删除 session:123: 开头的所有key
    }

    // 批量删除并返回成功数量
    public int RemoveMultiple()
    {
        var keys = new[] { "key1", "key2", "key3" };
        return _cache.RemoveAll(keys); // 返回实际删除的数量
    }

    // 条件删除
    public int RemoveTempCache()
    {
        return _cache.RemoveWhere(key => key.Contains("temp")); // 删除包含"temp"的key
    }
}

3. 缓存(ICacheService)- 添加和修改扩展方法

public class CacheAdvancedDemo
{
    private readonly ICacheService _cache;

    // 批量添加
    public void AddMultiple()
    {
        var items = new Dictionary<string, string>
        {
            { "user:1", "张三" },
            { "user:2", "李四" },
            { "user:3", "王五" }
        };
        _cache.AddAll(items, 300); // 批量添加,300秒过期
    }

    // 批量添加对象
    public void AddMultipleObjects()
    {
        var items = new Dictionary<string, object>
        {
            { "order:1", new { Id = 1, Amount = 100 } },
            { "order:2", new { Id = 2, Amount = 200 } }
        };
        _cache.AddAllObjects(items, 600);
    }

    // 替换(仅存在时替换)
    public bool ReplaceExisting()
    {
        return _cache.Replace("user:1", "新用户名"); // key不存在返回false
    }

    // 获取并刷新过期时间
    public string? GetAndRefresh(string key)
    {
        return _cache.GetAndRefresh(key, 1800); // 获取值并延长30分钟
    }

    // 刷新过期时间
    public bool RefreshExpire(string key)
    {
        return _cache.RefreshExpire(key, 3600); // 刷新为1小时后过期
    }

    // 设置N秒后过期
    public bool SetExpireIn(string key, int seconds)
    {
        return _cache.ExpireIn(key, seconds);
    }

    // 设置在指定时间点过期
    public bool SetExpireAt(string key, DateTime expireTime)
    {
        return _cache.ExpireAt(key, expireTime);
    }

    // 获取剩余过期时间
    public long? GetTTL(string key)
    {
        return _cache.GetExpire(key); // 返回剩余秒数,null表示永不过期或key不存在
    }
}

4. 缓存(ICacheService)- 原子操作方法

public class AtomicOperationDemo
{
    private readonly ICacheService _cache;

    // 原子添加(仅不存在时添加)- 分布式锁场景
    public bool AcquireLock(string lockKey, string lockValue)
    {
        return _cache.AddIfNotExists(lockKey, lockValue, 30); // 30秒自动过期
    }

    // 获取旧值并设置新值
    public string? GetAndSet(string key, string newValue)
    {
        return _cache.GetAndSet(key, newValue); // 返回旧值,设置新值
    }

    // 自增计数器
    public long IncrementCounter(string key)
    {
        return _cache.Increment(key); // 自增1,返回新值
    }

    // 自增指定值
    public long IncrementBy(string key, long value)
    {
        return _cache.Increment(key, value); // 自增value
    }

    // 自减计数器
    public long DecrementCounter(string key)
    {
        return _cache.Decrement(key); // 自减1
    }

    // 追加内容
    public long AppendContent(string key, string content)
    {
        return _cache.Append(key, content); // 返回追加后的字符串长度
    }
}

5. 缓存(ICacheService)- ConcurrentDictionary风格方法

public class ConcurrentStyleDemo
{
    private readonly ICacheService _cache;

    // 尝试添加(仅不存在时添加)
    public bool TryAdd(string key, string value)
    {
        return _cache.TryAdd(key, value, 60); // key存在返回false
    }

    // 尝试获取
    public bool TryGet(string key, out string? value)
    {
        return _cache.TryGetValue(key, out value);
    }

    // 尝试移除并返回值
    public bool TryRemove(string key, out string? value)
    {
        return _cache.TryRemove(key, out value);
    }

    // 尝试更新(仅存在时更新)
    public bool TryUpdate(string key, string newValue)
    {
        return _cache.TryUpdate(key, newValue, 60);
    }

    // 值改变时更新(避免无效写入)
    public bool TryUpdateIfChanged(string key, string newValue)
    {
        return _cache.TryUpdateIfChanged(key, newValue, 60); // 值相同返回false
    }

    // 获取或添加
    public string GetOrAdd(string key)
    {
        return _cache.GetOrAdd(key, "默认值", 60);
    }

    // 获取或添加(工厂方法)
    public T GetOrAdd<T>(string key, Func<string, T> factory) where T : class
    {
        return _cache.GetOrAdd(key, factory, 60);
    }
}

6. 分布式锁(IDistributedLockService)

public class OrderService
{
    private readonly IDistributedLockService _lock;

    public OrderService(IDistributedLockService lockService)
    {
        _lock = lockService;
    }

    // 方式一:手动获取和释放锁
    public void ProcessOrder(string orderId)
    {
        var token = _lock.AcquireLock($"order:{orderId}", TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(5));
        if (token == null)
        {
            Console.WriteLine("获取锁失败,其他进程正在处理");
            return;
        }
        try
        {
            // 业务逻辑...
        }
        finally
        {
            _lock.ReleaseLock($"order:{orderId}", token);
        }
    }

    // 方式二:自动管理锁的生命周期
    public void ProcessOrderAuto(string orderId)
    {
        var success = _lock.ExecuteWithLock($"order:{orderId}", TimeSpan.FromSeconds(30), () =>
        {
            // 业务逻辑...
        });
    }
}

7. 计数器(ICounterService)

public class StatisticsService
{
    private readonly ICounterService _counter;

    public StatisticsService(ICounterService counter)
    {
        _counter = counter;
    }

    // 任务计数
    public void OnTaskCompleted()
    {
        _counter.Increment("task:completed");
        var total = _counter.GetCount("task:completed");
    }

    // 带过期时间的计数(如:每小时请求数)
    public void OnApiRequest()
    {
        var count = _counter.IncrementWithExpiry("api:hourly", TimeSpan.FromHours(1));
    }
}

8. 发布/订阅(IMessageQueueService)

public class NotificationService
{
    private readonly IMessageQueueService _mq;

    public NotificationService(IMessageQueueService mq)
    {
        _mq = mq;
    }

    // 发布消息
    public void NotifyTaskComplete(int taskId)
    {
        _mq.Publish("task:complete", $"{{\"taskId\":{taskId}}}");
    }

    // 订阅消息
    public void SubscribeTaskEvents()
    {
        _mq.Subscribe("task:complete", (channel, message) =>
        {
            Console.WriteLine($"收到任务完成通知: {message}");
        });
    }

    // 简单队列:入队/出队
    public void UseQueue()
    {
        _mq.Enqueue("pending-tasks", "task_001");
        var task = _mq.Dequeue("pending-tasks");
    }
}

9. 限流(IRateLimitingService)

public class ApiController
{
    private readonly IRateLimitingService _rateLimiter;

    public ApiController(IRateLimitingService rateLimiter)
    {
        _rateLimiter = rateLimiter;
    }

    // 固定窗口限流:每分钟最多100次
    public bool CheckRateLimit(string clientIp)
    {
        return _rateLimiter.IsAllowed($"api:{clientIp}", 100, TimeSpan.FromMinutes(1));
    }

    // 滑动窗口限流
    public bool CheckSlidingRateLimit(string clientIp)
    {
        return _rateLimiter.IsAllowedSliding($"api:{clientIp}", 100, TimeSpan.FromMinutes(1));
    }

    // 令牌桶限流:桶容量50,每秒补充10个
    public bool CheckTokenBucket(string clientIp)
    {
        return _rateLimiter.TryAcquireToken($"api:{clientIp}", 50, 10, TimeSpan.FromSeconds(1));
    }
}

10. 分布式ID生成器(IDistributedIdGenerator)

public class TaskService
{
    private readonly IDistributedIdGenerator _idGen;

    public TaskService(IDistributedIdGenerator idGen)
    {
        _idGen = idGen;
    }

    // 自增ID
    public long CreateTask()
    {
        var id = _idGen.NextId("task");
        return id; // 1, 2, 3...
    }

    // 带日期前缀的ID
    public string CreateTaskCode()
    {
        var code = _idGen.NextIdWithDate("task");
        return code; // 20260302000001
    }
}

11. 排行榜(ILeaderboardService)

public class LeaderboardDemo
{
    private readonly ILeaderboardService _board;

    public LeaderboardDemo(ILeaderboardService board)
    {
        _board = board;
    }

    public void Demo()
    {
        // 添加/更新分数
        _board.AddOrUpdate("efficiency", "设备A", 95.5);
        _board.AddOrUpdate("efficiency", "设备B", 88.0);

        // 增加分数
        _board.IncrementScore("efficiency", "设备A", 2.0);

        // 获取排名和Top N
        var rank = _board.GetRank("efficiency", "设备A"); // 0 = 第一名
        var top10 = _board.GetTopN("efficiency", 10);
    }
}

12. 对象存储(IObjectStorageService)

public class DeviceService
{
    private readonly IObjectStorageService _storage;

    public DeviceService(IObjectStorageService storage)
    {
        _storage = storage;
    }

    public void Demo()
    {
        // 存储完整对象
        var device = new { Id = 1, Name = "堆垛机01", Status = "Running" };
        _storage.SetObject("device:1", device, TimeSpan.FromMinutes(30));

        // 读取对象
        var cached = _storage.GetObject<dynamic>("device:1");

        // Hash字段操作
        _storage.SetField("device:1:props", "temperature", "36.5");
        var temp = _storage.GetField("device:1:props", "temperature");
    }
}

13. 配置中心(IConfigurationCenterService)

public class ConfigDemo
{
    private readonly IConfigurationCenterService _config;

    public ConfigDemo(IConfigurationCenterService config)
    {
        _config = config;
    }

    public void Demo()
    {
        // 设置配置
        _config.Set("system", "MaxTaskCount", "100");
        _config.Set("system", "EnableAutoDispatch", "true");

        // 读取配置
        var maxTask = _config.Get("system", "MaxTaskCount");
        var allConfig = _config.GetSection("system");

        // 监听配置变更
        _config.Subscribe("system", (key, value) =>
        {
            Console.WriteLine($"配置变更: {key} = {value}");
        });
    }
}

14. 监控(IRedisMonitorService)

public class MonitorDemo
{
    private readonly IRedisMonitorService _monitor;

    public MonitorDemo(IRedisMonitorService monitor)
    {
        _monitor = monitor;
    }

    public void Demo()
    {
        // 健康检查
        var healthy = _monitor.HealthCheck();

        // 内存信息
        var mem = _monitor.GetMemoryInfo();
        Console.WriteLine($"内存使用: {mem.UsedMemoryHuman}, 使用率: {mem.UsagePercent}%");

        // 连接数和Key数量
        var clients = _monitor.GetClientCount();
        var dbSize = _monitor.GetDbSize();
    }
}

15. Session存储(ISessionStorage)

public class SessionDemo
{
    private readonly ISessionStorage _session;

    public SessionDemo(ISessionStorage session)
    {
        _session = session;
    }

    public void Demo()
    {
        var sid = Guid.NewGuid().ToString("N");

        // 设置Session数据,30分钟过期
        _session.Set(sid, "userId", "10001", TimeSpan.FromMinutes(30));
        _session.Set(sid, "role", "admin");

        // 读取
        var userId = _session.Get(sid, "userId");

        // 续期
        _session.RefreshSession(sid, TimeSpan.FromMinutes(30));

        // 销毁
        _session.DestroySession(sid);
    }
}

16. 布隆过滤器(IBloomFilterService)

public class BloomFilterDemo
{
    private readonly IBloomFilterService _bloom;

    public BloomFilterDemo(IBloomFilterService bloom)
    {
        _bloom = bloom;
    }

    // 防止缓存穿透
    public void Demo()
    {
        // 预热:将已有数据加入过滤器
        _bloom.AddRange("task:ids", new[] { "T001", "T002", "T003" });

        // 查询前先检查
        if (!_bloom.MayExist("task:ids", "T999"))
        {
            // 一定不存在,直接返回,避免查询数据库
            return;
        }
        // 可能存在,继续查询数据库...
    }
}

17. 缓存自动同步(CacheSyncBackgroundService)

Redis到内存缓存的自动同步后台服务,解决L1+L2混合缓存中外部修改Redis数据导致内存缓存不一致的问题。

配置说明

appsettings.json 中配置:

{
  "RedisConfig": {
    "EnableL1Cache": true,           // 启用L1内存缓存
    "EnableAutoSync": true,          // 启用自动同步
    "SyncIntervalSeconds": 30,       // 同步间隔:30秒
    "SyncBatchSize": 1000            // 单次批量获取key数量上限
  }
}

工作原理

  1. 启动时全量同步:服务启动后立即执行一次全量同步
  2. 定期增量同步:按照配置的间隔(默认30秒)定期执行同步
  3. 双向同步
  • 将Redis中的数据更新到内存缓存
  • 清理内存缓存中不存在于Redis的key
  1. 智能TTL同步:同步时会保留Redis中设置的过期时间

使用场景

  • 多系统共享Redis:当多个WCS实例共享同一个Redis,一个实例修改数据后,其他实例能自动同步
  • 外部修改Redis:通过Redis CLI或其他工具修改数据后,应用能自动获取最新值
  • 缓存一致性保障:避免启用L1缓存后,内存缓存和Redis数据不一致的问题

注意事项

  • 仅在 EnableL1Cache = trueEnableAutoSync = true 时运行
  • IMemoryCache不支持枚举,因此只能清理已跟踪的key
  • 同步间隔建议设置为30-60秒,过短会影响性能
  • 对于要求强一致性的场景,建议直接禁用L1缓存(EnableL1Cache: false
    ```