2

首先,如果我在这里使用了错误的术语,我深表歉意,我不是特别熟悉缓存或 Linux 文件系统的内部工作原理。就此而言,我可能误解了这个问题并找错了树。

目前正在运行 grails 3.2.10

compile 'org.grails.plugins:cache-ehcache:3.0.0.M1'

这似乎在幕后使用了 ehcache 3.1.4。我们遇到了一个问题,即我们的基于磁盘的缓存在启动时被加载,留下太多“打开的文件”。由于我们的应用程序为 .jars 保留了 4000 多个打开文件,用于读取缓存的 900 多个打开文件导致我们的服务器报告“打开的文件过多”并且服务器变得不可用。我们增加了可用的打开文件,但看起来我们不应该为缓存打开这么多文件。

示例缓存配置:

<config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://www.ehcache.org/v3' xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.1.xsd">
<persistence directory='/var/folders/x3/gs0rdtkn79s_5gc98d_0d4w0002yjd/T/myApp/ehcache'/>

<cache-template name="default">
    <key-type>java.lang.Object</key-type>
    <value-type>java.lang.Object</value-type>
    <heap unit="entries">1000</heap>
</cache-template>


<cache alias='myCacheName' uses-template='default'>
<key-type>java.lang.String</key-type>
<value-type>java.util.ArrayList</value-type>
<expiry><ttl unit='hours'>2</ttl></expiry>
<resources>
  <heap unit='entries'>1</heap>
  <disk unit='MB' persistent='true'>50</disk></resources>
</cache>
</config>

运行我的应用程序时,如果我使用 来检查打开的文件lsof -p <pid>,我会看到以下文件分别打开了 34 次,并且在应用程序加载后保持打开状态:

/private/var/folders/x3/gs0rdtkn79s_5gc98d_0d4w0002yjd/T/myApp/ehcache/myCacheName_863f4553eb5da54a98fff5c3f33a6a863225f6b8/offheap-disk-store/ehcache-disk-store.data

这种模式对每个基于磁盘的缓存重复。这在本地运行和将 .wars 部署到 Tomcat 服务器时是相同的。我已经尝试跟踪 ehcache 代码以找到打开这些代码的位置,但到目前为止没有成功,ehcache 非常狡猾。

有谁知道为什么这些基于磁盘的缓存被打开这么多次(而不是关闭)?有没有办法配置它,以便缓存以不同的方式“加热”?

编辑,更多信息:

所以我终于弄清楚发生了什么,虽然还没有解决它。ehcache 正在为磁盘缓存使用 terracotta 实现(我不确定这是默认实现,还是唯一包含的实现),它专注于性能。对于基于磁盘的缓存,默认并发被硬编码为16,这意味着它对每个磁盘缓存打开 16 个读取和 16 个写入FileChannel(然后由于某种原因还有另外两个打开的文件句柄,但此时并不那么重要)。无论是梳理代码还是从文档中,我都没有找到配置它的方法。

4

0 回答 0