6

I am using hibernate second-level caching with in-memory ehcache, and it is slow. I mean, not slower than SQL, but not really faster either given a fast database on an SSD. The actual speed increase is less than a factor of 2, and sometimes unnoticeable.

It seems that others had the same problem, but got no answer: http://forum.spring.io/forum/spring-projects/data/44353-hibernate-second-level-caching-slow-no-really-slow https://forum.hibernate.org/viewtopic.php?t=985913

After some profiling, it seems that hibernate always de/re-hydrates the cache elements, instead of directly storing them, which leads to this abysmal performance (over a factor of 100 compared to direct use of ehcache).

So, my questions are:

  • Can hibernate store and restore the cached objects directly?
  • Is there some other way to speed up the second level cache?
  • Is there a relatively simple alternative mechanism for faster hibernate caching?
P.Péter
  • 1,527
  • 16
  • 39
  • Because you ask three questions where you should be asking only one you instantly put this question into "too broad" territory. Stackoverflow is about asking one question at a time, consider splitting it up or narrowing it down to what you really want to know. Which would probably be to zoom in on the Hibernate cache performance problem. Start by being more specific about which version of Hibernate you're using. – Gimby Feb 02 '16 at 09:35
  • Well, the gist of the question is "I want faster caching". If any of the three options is feasible, I would be satisfied. – P.Péter Feb 02 '16 at 10:09
  • I think that is the hopping point: "less than a factor of 2". How can anybody tackle this, without knowing what your application is doing? Can you put together an example or benchmark that resembles the same access pattern then your application? – cruftex Feb 02 '16 at 11:27
  • 1
    I noticed this too. The speed L2C vs simply querying database on SSD is more or less the same (28 ms vs 33 ms in my sample). First query with L2C is much much slower! I expected at least 2-3 times faster with L2C, but we have what we have. – Andreas Gelever Jan 01 '19 at 13:46

4 Answers4

2

Can hibernate store and restore the cached objects directly?

No, it can't, because that would mean that concurrent sessions would use the same object instances, thus stepping on each other toes.

Is there some other way to speed up the second level cache?

There are probably thousands of ways to speed it up. Most of them depend on the specific requirements of your application.

Is there a relatively simple alternative mechanism for faster hibernate caching?

No, at least not for the time being.

Dragan Bozanovic
  • 23,102
  • 5
  • 43
  • 110
1

This is an old question but other people seem to have performance issues with Hibernate + Ehcache. I took me a while to figure out the problem so I'm adding what I found here, hopefully this might help someone.

The JCache/JSR-107 specification says that by default caches must store by value while Ehcache defaults to store by reference. When using Ehcache 3, Hibernate uses the jcache interface so Ehcache enforces the specification by using a serializing copier: before storing any key or value, they are serialized in a byte buffer. This operation takes quite a few CPU cycles for each cache get() and each put().

Ehcache switches to store-by-reference (i.e. essentially put the objects straight into the cache) when the default copier is the IdentityCopier, see the source of CompleteConfiguration.

So in order to avoid the serialization/deserialisation, I added a default-copiers element to my ehcache.xml:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.ehcache.org/v3" xmlns:jsr107="http://www.ehcache.org/v3/jsr107">

    <service>
        <jsr107:defaults enable-management="false" enable-statistics="false" default-template="default" />
    </service>

    <default-copiers>
        <copier type="java.lang.Object">org.ehcache.impl.copy.IdentityCopier</copier>
    </default-copiers>
    
    <cache>...</cache>
    <cache-template name="default">...</cache-template>
</config>
Guillaume
  • 14,306
  • 3
  • 43
  • 40
0

Have you figured out the Hibernate second level cache performance issues?, in some application diskPersistence and overFlowToDisk were on and noticed clone/serialization/deserialization in TRACE logs. Don't see why Hibernate/Ehcache had to clone/deserialize local JVM objects again.

kisna
  • 2,869
  • 1
  • 25
  • 30
  • No I have not figured out how to have a fast second level cache. Where it is critical, I employ an in-memory ehcache with detached objects. It does have drawbacks, as you have to be careful not to try to merge the objects you get from that cache. – P.Péter Apr 16 '19 at 12:02
  • Just wanted to say I have exactly the same issue. A test replacing ehcache 3.8 with a simple HashMap gave a speed up of about 200 times. Is Unserialization really that slow? – MTilsted Oct 11 '19 at 10:01
  • @kisna see my answer, I was able to improve my caching performance by setting a and using IdentityCopier. But maybe this does not work if you're doing disk operations (then you obviously need serialization). – Guillaume Aug 30 '21 at 14:16
0

We have this problem, too. If you store and retrieve many objects from the 2nd Level cache you must take into account the time for hydration and dehydration.

It is not cheap. But it is needed as you can't put the real entity into the 2ndLC. First the object is bound to the session and might have some proxies and other hibernate magic stuff. Second the object would be shared across multiple sessions/transactions. So you could "see" the changes another session is doing concurrently. Therefore hibernate hydrates and dehydrates.

What we have done to have a faster solution in some circumstances: We build a "Third Level Cache" with Spring @Cacheable, where we place DTOObjects (DataTransferObject as we call it) which are read-only. So if we have a Member entity we have a MemberDTO which is the object for the third level cache. It is mostly a copy of the real entity just for caching reasons.

Janning Vygen
  • 8,877
  • 9
  • 71
  • 102