EhCache条目驱逐期间CPU飙升原因咨询(v2.10.9.2)
问题场景
我们的应用使用Ehcache 2.10.9.2版本,近期将部分缓存的本地堆最大条目总数从500万提升至550万。相关缓存的条目始终达到上限,Ehcache需要从缓存中驱逐LRU(最近最少使用)条目。驱逐过程中观察到CPU使用率上升,此前也出现过该情况,但在拆分缓存并提升最大条目数后,CPU飙升现象更为明显,导致应用无响应。
此前缓存配置
<cache name="cache1" maxEntriesLocalHeap="3000000" eternal="false" memoryStoreEvictionPolicy="off"> <persistence strategy="none"/> </cache> <cache name="cache2" maxEntriesLocalHeap="2000000" eternal="false" memoryStoreEvictionPolicy="off"> <persistence strategy="none"/> </cache>
最新缓存配置
<cache name="cache1" maxEntriesLocalHeap="3000000" eternal="false" memoryStoreEvictionPolicy="off"> <persistence strategy="none"/> </cache> <cache name="cache2" maxEntriesLocalHeap="1500000" eternal="false" memoryStoreEvictionPolicy="off"> <persistence strategy="none"/> </cache> <cache name="cache3" maxEntriesLocalHeap="1000000" eternal="false" memoryStoreEvictionPolicy="off"> <persistence strategy="none"/> </cache>
原因分析
Ehcache 2.x的LRU实现固有开销
Ehcache 2.x的内存存储默认用LinkedHashMap维护LRU顺序,每次缓存访问、插入都会修改链表节点的位置,以保证访问顺序的正确性。当缓存条目达到百万级规模时,这种链表操作的CPU消耗会被显著放大;触发驱逐时,还需要遍历找到最旧条目并移除,进一步增加CPU负载。多缓存驱逐的叠加效应
拆分缓存后,总条目数从500万增加到550万,且新增了独立的cache3。每个缓存都有自己的LRU维护逻辑和独占锁:- 当多个缓存同时达到条目上限时,各自的驱逐操作会并行执行,CPU开销是多个缓存驱逐操作的叠加;
- 更多的缓存意味着更多的锁竞争点,并发场景下线程上下文切换频率升高,进一步推高CPU使用率。
memoryStoreEvictionPolicy="off"的配置误解
该配置仅表示不基于内存占用比例触发驱逐,但当maxEntriesLocalHeap达到上限时,Ehcache会强制执行LRU驱逐作为兜底策略。由于你的缓存始终处于条目饱和状态,系统会持续陷入“新增条目→触发LRU驱逐→新增条目”的循环,CPU资源被持续消耗。锁竞争加剧
Ehcache 2.x中每个缓存的内存存储都使用独占锁保证线程安全。拆分后的多缓存意味着更多的锁,当业务并发访问多个缓存时,锁竞争会导致线程阻塞、上下文切换频繁,这也是CPU飙升的重要诱因。
内容的提问来源于stack exchange,提问作者divya siddu

