多级优先级缓存

时间:2015-03-03 09:37:05

标签: java caching multi-level

我们对缓存(java)有以下要求。

  • 缓存条目在驱逐方面具有不同的优先级 - 条目的以下属性将是此优先级的一个因素
    • 插入或上次使用时(LRU)
    • 重新计算条目所需的资源(被驱逐时)。这个因素会发生变化,因为我们不时会从缓存中获取一个条目,然后向它添加信息,并且需要更多的资源来在驱逐后重新计算。在这个参数上,条目的驱逐优先级是非常离散的 - 不必支持例如任何可能的长/双值。让我们说比任何条目都具有自然数1-10范围内的优先级(只有10个可能的驱逐优先级值)

猜猜可以使用支持eviction-policy插件的缓存实现来完成。 EHCache似乎支持这一点。不幸的是,番石榴缓存没有。

但是我害怕性能和灵活性,如果实现实际上只使用一个内部缓存,它试图在必须驱逐时找到具有最低停留优先级的条目。如果它以某种方式实现,以便一个条目注册(带有缓存)它的新优先级,当它的优先级发生变化,并且缓存保持优先级队列时,我就不会那么害怕。有人知道这样做的缓存实现吗?有谁知道EHCache实际上在做什么?

我们也很难从上述两个因素中实际计算出一个优先级。很难计算出最近的使用和#34;之间的公平平衡。和#34;重新计算它是如何消耗资源"。

目前,我们已经使自己的缓存实现具有内部缓存(Guava缓存)列表。每个内部缓存只使用LRU驱逐策略。当一个条目改变时,它是如何重新计算它的资源消耗的。它移动到下一个"内部缓存。这样,我们不必计算组合的逐出优先级值,但可以在每个内部缓存上具有不同的最大大小等。实际上我们喜欢它给出的灵活性,但我们宁愿不自己做和维护缓存实现。我们宁愿使用某些开源项目的缓存实现。任何人都知道支持这种多级内部缓存功能的开源缓存实现?或者是一个想要采用我们的实现的开源项目?

1 个答案:

答案 0 :(得分:0)

您的问题非常专业,可能属于XYProblem类别。您要求的技术方法可能不是解决问题的正确方法,或者它增加了系统的复杂性,但与之相比效益较小。

解决方案的想法,构建分段缓存,并根据复制成本分配段,似乎可以合理地解决您的问题陈述。但是,它可能无法优于所有优化。

您要求的是,缓存应该考虑驱逐决策的新近度和优先级。这可能会产生不利影响,因为它没有考虑频率。例如。可以驱逐复制成本为99的条目,并且可以保留成本100的条目。但是如果成本99的条目被频繁访问三次呢?聚合的复制成本变得更糟。

固有的问题是:您希望保留一个条目,因为重现这一条目非常重要且成本高昂。 "重要"意味着应用程序经常使用它,这意味着它正被访问。为什么缓存会逐出它呢?

这里出现了一些随意的想法来解决这个问题:

只需增加缓存大小即可。使用Guava,你会受到限制。也许使用具有持久性的缓存来克服这个问题,如infinispan或hazelcast。

为什么缓存会驱逐重要的条目呢?检查应用程序是否真正访问缓存并且不保留引用或在顶部强制执行其他缓存。也许您的应用程序的访问模式不是LRU友好的。然后有更好的驱逐算法,例如LRU,例如ARC,LIRS或Clock-Pro。也许现代驱逐算法无论如何都会保留您昂贵的条目。

是否有可能从缓存密钥中获得合理的成本估算?也许这是可能的,并且足够好"根据密钥对缓存进行分段。这样,条目进入哪个段也更透明。

最后一句话:

我喜欢你对此的想法,因为我认为缓存是调整典型时间与空间设计决策的好地方。但是,如果你开始改善"并添加优先驱逐,然后全程:评估不同的方法,并确保使用的资源真的降低。