首先,如果我在这里使用错误的术语,我很抱歉,我并不是特别熟悉缓存或Linux文件系统的内部工作原理。就此而言,我可能会误解问题并咆哮错误的树。
目前正在运行grails 3.2.10 with
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非常狡猾。
有谁知道为什么这些基于磁盘的缓存被打开了这么多次(并没有关闭)?有没有办法配置这个,以便缓存#34;温暖&#34;不同?
修改,提供更多信息:
所以我终于弄明白了发生了什么,但还没有解决它的问题。 ehcache正在使用一个用于磁盘缓存的terracotta实现(我不确定这是默认实现,还是唯一包含的实现),它专注于性能。对于基于磁盘的高速缓存,默认并发性被硬编码为16
,这意味着它会向每个磁盘高速缓存打开16个读取和16个写入FileChannel
(然后由于某种原因打开另外两个打开的文件句柄) ,但在这一点上并不那么重要)。既没有从代码中梳理,也没有从文档中找到一种方法来配置它。