淘气回OffIfDiskSpoolSpoolFull
Naughty backOffIfDiskSpoolFull
当我的 Spring Boot + Data JPA 1.5 应用程序承受重负载时,一段时间后(在本例中为几分钟),存储库保存暂停 20-30 秒,因为 EhCache "backs-off" by putting the thread to sleep 因为它的磁盘假脱机已满:
"pool-2-thread-1" sleeping[0x00007fc1a95ae000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep
at ehcache.Cache.backOffIfDiskSpoolFull
at ehcache.Cache.putInternal
at ehcache.Cache.put
at ehcache.Cache.put
... many Hibernate, Spring, Sun frames
at com.sun.proxy.$Proxy155.save
(为清楚起见,从 ehcache 中删除了 net.sf.
)
结果,性能直线下降,这让我很难过。
我没有定义了一个ehcache.xml
;我只添加了 hibernate-ehcache
依赖项并通过 @EnableCaching
注释启用了缓存。尽管没有提供 ehcache.xml
Hibernate 仍然清楚地使用 Ehcache,如上面的堆栈跟踪所示。
我想将 EhCache 重新配置为不使用 DiskStore
,而是执行它现在正在执行的所有其他操作(通过 Spring 引导、Spring 数据、休眠等。 ).为了避免尝试重新创建现在显然存在的 effective/magical ehcache.xml
,是否有一个 EhCache bean 我可以在其中禁用持久性,或者类似的外科手术?或者,有什么办法可以打印有效的 Ehcache 配置吗?
磁盘存储在 Ehcache 配置中定义。这是在 ehcache.xml
.
因此从 ehcache.xml
中删除磁盘存储是一种可行的方法。
根据您添加的解释:Hibernate 试图对您友善并使用默认参数创建缓存。但是使用这些参数是一个非常糟糕的主意。
您需要对缓存配置进行一些思考。
- 它应该包含多少个元素?
- 它们应该过期吗?
- 我需要磁盘吗? (大多数时候这里的答案确实是"no")
如果不这样做,您将得到陈旧的数据或 OutOfMemoryError
s。
所以我强烈建议您使用自己深思熟虑的 ehcache.xml
而不是 Hibernate 魔法。
Spring Boot 1.5 with Spring Data JPA 使用 Hibernate 5.0.12.Final;并且,Hibernate 5.0.12.Final 在内部使用 Ehcache 2.4.3。要禁用磁盘写入,您需要在 Hibernate 使用的默认缓存配置中禁用磁盘,并在任何应用程序定义的缓存中禁用磁盘使用,例如:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
maxElementsOnDisk="0"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="my-cache-1" />
...
<cache name="my-cache-n" />
</ehcache>
当我的 Spring Boot + Data JPA 1.5 应用程序承受重负载时,一段时间后(在本例中为几分钟),存储库保存暂停 20-30 秒,因为 EhCache "backs-off" by putting the thread to sleep 因为它的磁盘假脱机已满:
"pool-2-thread-1" sleeping[0x00007fc1a95ae000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep
at ehcache.Cache.backOffIfDiskSpoolFull
at ehcache.Cache.putInternal
at ehcache.Cache.put
at ehcache.Cache.put
... many Hibernate, Spring, Sun frames
at com.sun.proxy.$Proxy155.save
(为清楚起见,从 ehcache 中删除了 net.sf.
)
结果,性能直线下降,这让我很难过。
我没有定义了一个ehcache.xml
;我只添加了 hibernate-ehcache
依赖项并通过 @EnableCaching
注释启用了缓存。尽管没有提供 ehcache.xml
Hibernate 仍然清楚地使用 Ehcache,如上面的堆栈跟踪所示。
我想将 EhCache 重新配置为不使用 DiskStore
,而是执行它现在正在执行的所有其他操作(通过 Spring 引导、Spring 数据、休眠等。 ).为了避免尝试重新创建现在显然存在的 effective/magical ehcache.xml
,是否有一个 EhCache bean 我可以在其中禁用持久性,或者类似的外科手术?或者,有什么办法可以打印有效的 Ehcache 配置吗?
磁盘存储在 Ehcache 配置中定义。这是在 ehcache.xml
.
因此从 ehcache.xml
中删除磁盘存储是一种可行的方法。
根据您添加的解释:Hibernate 试图对您友善并使用默认参数创建缓存。但是使用这些参数是一个非常糟糕的主意。
您需要对缓存配置进行一些思考。
- 它应该包含多少个元素?
- 它们应该过期吗?
- 我需要磁盘吗? (大多数时候这里的答案确实是"no")
如果不这样做,您将得到陈旧的数据或 OutOfMemoryError
s。
所以我强烈建议您使用自己深思熟虑的 ehcache.xml
而不是 Hibernate 魔法。
Spring Boot 1.5 with Spring Data JPA 使用 Hibernate 5.0.12.Final;并且,Hibernate 5.0.12.Final 在内部使用 Ehcache 2.4.3。要禁用磁盘写入,您需要在 Hibernate 使用的默认缓存配置中禁用磁盘,并在任何应用程序定义的缓存中禁用磁盘使用,例如:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
maxElementsOnDisk="0"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="my-cache-1" />
...
<cache name="my-cache-n" />
</ehcache>