我们对缓存(java)有以下要求。
我猜它可以使用支持驱逐策略插件的缓存实现来完成。EHCache似乎支持这一点。不幸的是,番石榴缓存没有。
但我担心性能和灵活性,如果实现实际上只使用一个内部缓存,试图在必须退出时找到具有最低保留优先级的条目。如果它是以某种方式实现的,以便一个条目在优先级发生变化时(与缓存一起)注册它的新优先级,并且缓存维护一个优先级队列,那么我就不会那么害怕了。有人知道缓存实现是这样做的吗?有人知道EHCache到底在做什么吗?
我们也很难从上述两个因素中实际计算出一个合并的优先次序。很难在“使用最近的情况”和“重新计算资源消耗情况”之间取得公平的平衡。
目前,我们已经建立了自己的缓存实现,有一个内部缓存列表(番石榴缓存)。每个内部缓存只使用LRU驱逐策略。当一个条目更改“如何使用资源以重新计算它”时,它会移动到“下一个”内部缓存。这样,我们就不必计算合并的驱逐优先级值,而是可以在每个内部缓存上有不同的最大大小等。实际上,我们喜欢它提供的灵活性,但我们不愿意自己做和维护缓存实现。我们宁愿使用来自某个开源项目的缓存实现。有人知道支持这种多级内部缓存功能的开源缓存实现吗?或者是一个希望采用我们的实现的开源项目?
发布于 2015-03-03 14:28:10
您的问题非常专门,可能属于XYProblem类别。您所要求的技术方法可能不是问题的正确解决方案,或者,它增加了系统的复杂性,但与其相比没有什么好处。
解决方案,建立分段缓存,并根据复制成本分配段,似乎是合理的解决您的问题陈述。然而,它可能不会产生一个良好的所有优化。
您要求的是,缓存应该考虑最近的情况和驱逐决定的优先级。这可能会产生不良影响,因为它没有考虑到频率。例如,复制成本为99的条目可以被逐出,成本为100的条目可以保留。但是,如果成本为99的条目被访问的次数增加了三倍,该怎么办?累计再生产成本越来越低。
内在的问题是:你想保留一个条目,因为它是重要的和昂贵的复制。“重要”意味着应用程序经常使用它,这意味着它正在被访问。那么,缓存为什么要驱逐它呢?
在这里,我想到了一些随机的想法来解决这个问题:
只需增加缓存大小即可。有了番石榴,你就被限制在堆里了。也许可以使用带有持久性的缓存来克服这种情况,比如无穷大或哈泽尔卡斯特。
为什么缓存会删除重要的条目?检查应用程序是否真的访问了缓存,并且没有保存引用,或者在顶部强制执行额外的缓存。也许您的应用程序的访问模式不是LRU友好的。有更好的驱逐算法比LRU,例如ARC,LIRS或Clock-Pro。也许一种现代的驱逐算法会保留你昂贵的记录。
难道不可能从缓存密钥中得到合理的成本估算吗?也许它是有可能的,而且“足够好”,可以根据键来分割缓存。这样,就可以更透明地看到哪些条目进入了哪个部分。
最后一句是:
我喜欢你对此的想法,因为我认为缓存是一个很好的地方来调整典型的时间和空间设计决策。但是,如果你开始“改进”并增加优先驱逐,那么就一直走下去:评估不同的方法,并确保使用的资源真的降低了。
https://stackoverflow.com/questions/28828383
复制相似问题