【问题标题】:Cache key organization problem缓存键组织问题
【发布时间】:2023-04-01 14:22:01
【问题描述】:

我的实体有两个唯一的 ID(是的,这是错误的,但这是必需的)。我想组织此类实例的缓存。可以通过 id1 OR id2 OR id1 和 id2 在缓存中进行搜索。通过 id1 和 id2 搜索都可以 - 我将制作复合键。但是如何处理仅通过其中一个 id 进行搜索。缓存键应该是什么?我正在使用 ehcache。

我有一个情况,几个键可能指同一个 对象。

就像ehcache不支持这个功能一样 对象将为每个键存储(n 个实例 同一个对象,其中 n 是不同键的数量 可以引用该对象)。

在某些时候,我知道计算 其他键,但不是在我需要它们之前。

情况:

基因钥匙 (1) 检查对象是否在缓存中 (2) TRUE : 恢复它

FALSE : 处理新对象 (3) 放在ehcache中 返回对象

在第 (1) 点只知道其中一个键。在这一点上 (3) 有可能知道所有密钥 对象可能在 ehcache 中与它相关联。 问题是第 (2) 点需要密钥。

谢谢

【问题讨论】:

  • 我发现了一个与我的情况相同的 ehache 错误,该错误已关闭,因为无法用 cmets 修复存在某种名为 jofti 的索引实用程序,但我猜它已经死了。也许有人知道这个 jotfi 使用什么模式来实现多键在缓存中搜索?

标签: java programming-languages theory ehcache


【解决方案1】:

要完成您想要的,您可以通过传递性来实现,不仅将对象存储在缓存中,而且还使用每个键存储指向您的对象的索引。 例如:
缓存["key1"]=theIndex;
缓存["key2"]=theIndex;
缓存[theIndex]=对象;

所以,当您请求缓存["key1"] 时,您将获得一个索引(您必须知道它是一个索引),然后使用该索引获取实际对象。

代码可能类似于:

 public class CacheUtil {

   ... any necessary code here

   public static void put(String key, Serializable obj) {
    if (obj instance of Cacheable) { 
      //Cacheable interface identifies the cacheable object that has the getKeys method
      String[] keys = obj.getKeys();
      if (keys != null && keys.length > 0) {

        for (String myKey : keys) {
          //CacheIndex identifies the index
          cache.put(new Element(myKey, new CacheIndex(hashCode))); 
        }
        key = hashCode(keys); //change the key. Can be a hashcode of the keys
      }
    }

    cache.put(new Element(key, obj));
  }

  public static Serializable get(String key) {

    Serializable obj = cache.get(key);

    return ((null != serializable) && (serializable instanceof CacheIndex)) ?
            get(((CacheIndex)serializable).getIndex(), area) : obj;
  }

}

【讨论】:

    【解决方案2】:

    我不知道 ehcache,但我一直有类似的问题 HashMap 用作缓存。我只是将每个值在 Map 中放了两次,它并不昂贵,而且效果很好。

    由于我的密钥类型不同,我使用了Map<Object, V>

    【讨论】:

    • 是的,我明白了,但是我的实体需要大量内存来缓存它两次)
    • 实体只存储一次,不是吗?我看到 ehcache 没有。所以使用两个缓存,另外一个用于将另一个 id 映射到一个由真正的缓存使用。但是由于两次访问而不是一次访问,速度要慢两倍,这可能重要也可能不重要。
    • 是的,这是最重要的问题 :) 所以我仍在寻找一种解决方案,即只有一个对象缓存能够通过多个键进行搜索。
    【解决方案3】:

    一种选择是使用两个地图。每个 id 集一个,但两者都指向同一组值。

    如果在 id1 上搜索,则在第一个映射中查找值,如果在 id2 上,则在第二个映射中查找。如果您需要同时搜索这两个值,请查找这两个值并查看值是否相同。

    根据您对以下问题和 cmets 的更新进行了更新: 在你的缓存中使用这两个键。是的,这将占用更多空间,并且有时您要查找的对象已经在另一个键下的缓存中。但是,缓存应该存储常见的查找键。它不应该关心该值可能存在于另一个键下。因此,我不会因为尝试优化缓存以基于两个键进行查找而给自己带来压力。

    【讨论】:

    • 也许你的某种缓存模式可以应用于这种情况?
    • @user,我不太明白您在上述评论中的问题。能否改写一下或举个例子?
    • 抱歉评论有误,我在问你其他一些可以解决这种情况的模式或工具)
    • @user,您能否详细解释一下您的情况,尤其是使用地图的原因,以便我们了解您从解决方案中寻找什么。谢谢
    • 问题是我的 ehcache 在 15 分钟不活动后清理缓存(这是由于对象的数量和大小的要求),并且创建链接键的附加映射使其一直增长在大小上,所以如果我有几百万个对象,对象的缓存将会有一定的大小,键的映射会非常大。我会在一分钟内用示例更新故事的标题。
    猜你喜欢
    • 2011-01-31
    • 2015-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-13
    • 2016-10-24
    • 1970-01-01
    相关资源
    最近更新 更多