【问题标题】:Best way to remove cache entry based on predicate in infinispan?根据infinispan中的谓词删除缓存条目的最佳方法?
【发布时间】:2017-09-13 18:02:44
【问题描述】:

如果缓存中的键与某些模式匹配,我想删除一些缓存条目。

例如,我在缓存中有以下键值对,

("key-1", "value-1"), ("key-2", "value-2"), ("key-3", "value-3"), ("key-4", "value-4")

由于缓存实现了地图接口,我可以这样做

cache.entrySet().removeIf(entry -> entry.getKey().indexOf("key-") > 0);

在 infinispan 中是否有更好的方法来做到这一点(可能是使用函数式或缓存流 api)?

【问题讨论】:

    标签: caching infinispan remove-if infinispan-9


    【解决方案1】:

    entrySet 上的 removeIf 方法应该可以正常工作。但是对于分布式缓存来说,它会非常慢,因为它会拉下缓存中的每个条目并在本地评估谓词,然后对每个匹配的条目执行删除。即使在复制缓存中,它仍然必须执行所有删除调用(至少迭代器将是本地的)。此方法将来可能会更改,因为我们已经在更新 Map 方法 [a]。

    另一种选择是使用您所说的功能 API [1]。不幸的是,它的实现方式仍然是首先在本地提取所有条目。如果功能性地图 API 变得更流行,这可能会在以后更改。

    另一个选择是缓存流 API,它使用起来可能有点麻烦,但会为您提供所有选项中的最佳性能。很高兴您提到它:) 我建议首先应用任何中间操作(幸运的是,在您的情况下,您可以使用过滤器,因为您的密钥不会同时更改)。然后使用在该节点 [2] 上传递缓存的 forEach 终端操作(注意这是一个覆盖)。在 forEach 可调用对象中,您可以随意调用 remove 命令。

    cache.entrySet().parallelStream() // stream() if you want single thread per node
       .filter(e -> e.getKey().indexOf("key-") > 0)
       .forEach((cache, e) -> cache.remove(e.getKey()));
    

    您也可以使用索引来避免容器的迭代,但我不会在这里讨论。索引是完全不同的野兽。

    [a]https://issues.jboss.org/browse/ISPN-5728

    [1]https://docs.jboss.org/infinispan/9.0/apidocs/org/infinispan/commons/api/functional/FunctionalMap.ReadWriteMap.html#evalAll-java.util.function.Function-

    [2]https://docs.jboss.org/infinispan/9.0/apidocs/org/infinispan/CacheStream.html#forEach-org.infinispan.util.function.SerializableBiConsumer-

    【讨论】:

    • 感谢您的宝贵回答,我无法使用功能性 readwritemap api 来删除基于 evalMany 的少量条目。但是您的基于缓存流 api 的解决方案解决了我的问题。
    猜你喜欢
    • 1970-01-01
    • 2010-10-02
    • 2011-05-23
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-22
    • 1970-01-01
    相关资源
    最近更新 更多