【问题标题】:How to implement auto-refresh with Redis cache如何使用 Redis 缓存实现自动刷新
【发布时间】:2020-08-11 22:53:48
【问题描述】:

MemoryCache 有一个Set 方法,让我可以指定一个委托,在通过CacheItemPolicy 参数从缓存中删除缓存条目之前调用该委托。

这可以用于定期auto refresh the cache,而无需使用 Hangfire 或其他一些任务运行器。

如何在 .NET 中使用 StackExchange.Redis 实现这一点?

我无法在Redis command reference 中找到任何适合我的目的的方法,并且我在网上找到的所有ObjectCache 实现都在它们的实现中抛出了NotSupportedException

https://github.com/justinfinch/Redis-Object-Cache/blob/master/src/RedisObjectCache/RedisCache.cs https://www.leadtools.com/help/sdk/v20/dh/to/azure-redis-cache-example.html https://github.com/Azure/aspnet-redis-providers/pull/72/commits/2930ede272fe09abf930208dfe935c602c1bb510

【问题讨论】:

    标签: .net caching redis stackexchange.redis


    【解决方案1】:

    Redis 中没有内置这样的东西。

    但是,Redis 确实支持keyspace notifications,它提供了一种注册Expired 事件的方法。 您可以注册一个将对此类事件做出反应并刷新缓存的客户端。

    另一种选择是在expired--> register(eventTypes=['exired']) 事件上使用RedisGearsregister,这样每次触发过期事件时,您在Redis 中运行的函数都会刷新数据。

    【讨论】:

    • 我认为问题在于,当缓存中没有任何内容时,在引发 Expired 事件和刷新数据可用之间会有一段时间。我的理解是MemoryCache 在处理CacheItemPolicy.UpdateCallback 时缓存仍然可用。也许我可以使用 MemoryCache 来存储一个在主 RedisCache 之前过期的小项目,并使用它的过期时间来刷新两者
    • 另一种模式是将每个键在 Redis 中保留两次,一次用于数据,一次只是为了在发泄中过期并对其做出反应(第二次没有实际价值)
    【解决方案2】:

    缓存中的典型模式是调用缓存的数据,当找不到时,加载它。

    public T Get<T>(string key)
    {
        T ret = GetFromRedis<T>(key); // I am not going to go into implementation of GetFromRedis for purpose of this question
        if (ret == null)
        {
            // in the multi-server situation, this lock can be 
            // implemented as UPDATE record lock on DB transaction ***
            lock(_loadLock) 
            {
                ret = GetFromRedis<T>(key);
                if (ret == null)
                {
                    ret = DataProvider.Load<T>();
                    SetInRedis(key, ret);   
                }
            }
        }
        return ret; 
    }
    

    *** 我不会过分强调那个锁!!multiple!!服务器。是的,您可能最终在第一次加载时加载数据两次或更多,但您的 redis SET 可以使用 When.NotExists。这样,当多个线程尝试这样做时,实际缓存将不会被替换。因此,这是按需缓存与持续缓存。例如,在大型应用程序中,有些部件未使用。为什么要填充缓存?然后,用户开始点击零件,瞧!

    【讨论】:

    • 我认为这并不能真正回答问题。我已经有一个通读缓存策略 - 绝对到期。问题是每次缓存过期时延迟都会增加。使用 MemoryCache,我可以通过 CacheItemPolicy 实现的自动刷新来避免这个问题(一旦应用程序预热)。问题是我如何使用 Redis 实现同样的目标
    • 我想,我的意思是——“你需要不断地把东西保存在缓存中吗?......真的吗?”在我的系统中,我目前使用System.Runtime.Caching(之前是企业库缓存),并且缓存过期并被炸毁。然后,正如您在我的回答中看到的那样,它会根据第一次需求重新填充。是的,这个答案不是关于如何保持缓存填充,而是如何不保持它不断填充。我现在将 Redis 作为通信层添加到我的本地缓存中。本地速度要快得多。当数据发生变化时,redis 会 ping 本地缓存提供程序以清除 key,然后在第一次请求时重新加载。保持新鲜
    • 我想知道您的方法是否是 2 个线程,一个数据检索器依赖缓存,另一个负责加载。在这种情况下,您必须有缓存。我的方法是 1 个线程同时负责 - 加载和检索缓存,它可以故障回复到数据源,并且不需要单独的加载线程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    • 2019-07-05
    • 1970-01-01
    • 2018-01-09
    • 2017-11-22
    • 1970-01-01
    相关资源
    最近更新 更多