Redis:基于依赖项的缓存项失效?

Posted

技术标签:

【中文标题】Redis:基于依赖项的缓存项失效?【英文标题】:Redis: cache item invalidation based on dependencies? 【发布时间】:2020-08-08 08:53:12 【问题描述】:

当其他指定项从缓存中删除时,Redis 中是否有一种本地方式使缓存项无效?是否有基于依赖关系的驱逐策略?

这是我想要完成的一个示例。

假设在 Redis 中有一个缓存项,其键为 ma​​inKey。如果另一个特定项目被删除,我希望自动删除该项目。例如,如果 ma​​inKey 依赖于键 d1d2,那么我希望 ma​​inKeyd1d2 从缓存中删除后立即从缓存中删除。

例如,在 .Net 中,使用 MemoryCache 编写这样的代码相当容易。

[TestMethod]
public void TestCacheItemIsRemovedWhenADependencyGetsRemoved() 
    // ARRANGE

    var cache = new MemoryCache(name: "MyCache");

    // insert dependencies cache items
    var dummyValue = 1;
    cache.Set("d1", dummyValue, absoluteExpiration: DateTime.Now.AddDays(1));
    cache.Set("d2", dummyValue, absoluteExpiration: DateTime.Now.AddDays(1));

    // build cache policy for main cache item
    var policy = new CacheItemPolicy 
        SlidingExpiration = TimeSpan.FromMinutes(10)
    ;
    var dependencies = new[]  "d1", "d2" ;
    var changeMonitor = cache.CreateCacheEntryChangeMonitor(dependencies);
    policy.ChangeMonitors.Add(changeMonitor);

    // insert main cache item
    cache.Set("mainKey", "this is the main value", policy);

    // ACT

    // remove a dependency key
    cache.Remove("d1");

    // ASSERT

    // mainKey is removed as a consequence of removing "d1"
    Assert.IsFalse(cache.Contains("mainKey"));
    // only "d2" remains in the cache
    Assert.AreEqual(1, cache.GetCount());
    Assert.IsTrue(cache.Contains("d2"));

【问题讨论】:

【参考方案1】:

这是缓存失效的一个已知障碍,您需要Cache Tagging 来克服它。

例如,mainKey 依赖于键 d1 和 d2,那么我希望在从缓存中删除 d1 或 d2 后立即从缓存中删除 mainKey。

TL;DR - 您需要标记相互依赖的键,并且当其中一个发生某些操作(更新或删除)时,您需要删除共享相同标记的所有缓存项.

【讨论】:

以上是关于Redis:基于依赖项的缓存项失效?的主要内容,如果未能解决你的问题,请参考以下文章

Asp.Net 何时删除过期的缓存项?

Java 实现 LRU 缓存算法

转载使用缓存的9大误区(下)

使用缓存的9大误区(下)(转)

laravel框架学习-缓存,事件

在 symfony4 中为 redis 设置无键前缀