我想使用 Infinispan 作为图像二进制数据(Java 类型byte[]
)的缓存。我假设 Infinispan 默认策略是 LIFO 或类似的策略,它更喜欢保留最近使用/添加的缓存实体。
在我的负载测试场景中,我总共进行了四次调用来检索给定的实体。假设第一个调用永远不会命中缓存(因为每一轮都请求一个唯一的实体),但接下来的三个总是命中缓存。所以预期的配置文件如下所示:
#1: MISS-HIT-HIT-HIT
#2: MISS-HIT-HIT-HIT
...
当我将 Infinispan 配置COUNT
为具有一定数量实体的驱逐类型时,它可以完美运行:
<local-cache name="imagesCache" statistics="true">
<!-- lifespan="30 min" max-idle="30 min" interval="1 min" -->
<expiration lifespan="1800000" max-idle="1800000" interval="60000" />
<memory>
<binary eviction="COUNT" size="500" />
</memory>
</local-cache>
统计数据显示运行结束时(以及中间)准确的 3/4 缓存命中:
基于我在负载测试中捕获的数字的缓存命中率:(2952-738)/2952 = 0.75
当我更改要保留在内存中的实体数量(<binary eviction="COUNT" size="100" />
)时,命中率不会改变(如预期的那样)。
在运行期间,我测量了负载测试前后的堆大小(在几次 GC 调用后进行的测量),结果表明 500 个实体大约需要114.895.000 - 62.445.000 = 52.450.000
字节 = 每个实体大约 100KB:
之后,我重新启动了应用程序,只对缓存配置进行了这个小改动:
<memory>
<binary eviction="MEMORY" size="1000000" />
</memory>
我希望 Infinispan 的性能具有相同的配置文件,但是事实证明,一旦给定的内存量被完全分配,新添加的实体不会驱逐旧实体,而是立即被驱逐。这意味着大约在添加 100 个实体之后,所有四个请求缓存结果缓存未命中。可以看到该比率现在是 0.58 而不是 0.75:
缓存命中率:(2952-738-504)/2952 = 0.579
如果我增加内存,命中率确实接近 0.75,但是我希望命中率相同,而与内存大小无关(假设内存至少可以容纳几个实体)。
一旦我将钝化配置为文件,基于内存的驱逐策略开始按预期工作:
<local-cache name="imagesCache" statistics="true">
<expiration lifespan="1800000" max-idle="1800000" interval="60000" />
<persistence passivation="true">
<file-store path="/var/cache/infinispan" purge="true">
<write-behind thread-pool-size="5" />
</file-store>
</persistence>
<memory>
<binary eviction="MEMORY" size="1000000" />
</memory>
</local-cache>
Passivation → Attributes显示钝化次数为 1121(等于驱逐次数),Activation → Attributes显示激活次数为 1242。这意味着某些实体已被激活多次(并立即驱逐,这不好)。一般来说,我希望激活次数为零。
知道如何配置基于内存的驱逐策略,以使缓存命中率与基于计数的策略相同吗?
我读过的与上述相关的主题(他们没有直接回答上述问题):