2 Stimmen

Keine Verbesserung der Geschwindigkeit bei Verwendung von Ehcache mit Hibernate

Ich erhalte keine Geschwindigkeitsverbesserung bei der Verwendung von Ehcache mit Hibernate

Hier sind die Ergebnisse, die ich erhalte, wenn ich den Test unten ausführe. Der Test liest 80 Stop-Objekte und dann die gleichen 80 Stop-Objekte wieder mit dem Cache.

Beim zweiten Lesen wird der Cache getroffen, aber es gibt keine Verbesserung der Geschwindigkeit. Irgendwelche Ideen, was ich falsch mache?

Speed Test:

First Read: Reading stops 1-80 : 288ms
Second Read: Reading stops 1-80 : 275ms

Cache Info:

elementsInMemory: 79
elementsInMemoryStore: 79
elementsInDiskStore: 0

JunitCacheTest

public class JunitCacheTest extends TestCase  {

    static Cache stopCache;

    public void testCache()
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans-hibernate.xml");
        StopDao stopDao = (StopDao) context.getBean("stopDao");

        CacheManager manager = new CacheManager();
        stopCache = (Cache) manager.getCache("ie.dataStructure.Stop.Stop");
        //First Read
        for (int i=1; i<80;i++)
        {
            Stop toStop = stopDao.findById(i);
        }
        //Second Read
        for (int i=1; i<80;i++)
        {
            Stop toStop = stopDao.findById(i);
        }

        System.out.println("elementsInMemory " + stopCache.getSize());
        System.out.println("elementsInMemoryStore " + stopCache.getMemoryStoreSize());
        System.out.println("elementsInDiskStore " + stopCache.getDiskStoreSize());

    }

        public static Cache getStopCache() {
        return stopCache;
    }
}

HibernateStopDao

    @Repository("stopDao")
    public class HibernateStopDao implements StopDao {

        private SessionFactory sessionFactory;

        @Transactional(readOnly = true)
        public Stop findById(int stopId) {

            Cache stopCache = JunitCacheTest.getStopCache();
            Element cacheResult = stopCache.get(stopId);

            if (cacheResult != null){

                return (Stop) cacheResult.getValue();
            }
            else{

                Stop result =(Stop) sessionFactory.getCurrentSession().get(Stop.class, stopId);
                Element element = new Element(result.getStopID(),result);
                stopCache.put(element);
                return result;
            }
        }
    }

ehcache.xml

   <cache name="ie.dataStructure.Stop.Stop"
    maxElementsInMemory="1000"
    eternal="false"
    timeToIdleSeconds="5200"
    timeToLiveSeconds="5200"
    overflowToDisk="true">
    </cache>

stop.hbm.xml

    <class name="ie.dataStructure.Stop.Stop" table="stops" catalog="hibernate3" mutable="false" >
     <cache usage="read-only"/>
            <comment></comment>
            <id name="stopID" type="int">

                <column name="STOPID" />
                <generator class="assigned" />
            </id>
            <property name="coordinateID" type="int">
                <column name="COORDINATEID" not-null="true">
                    <comment></comment>
                </column>
            </property>
            <property name="routeID" type="int">
                <column name="ROUTEID" not-null="true">
                    <comment></comment>
                </column>
            </property>
        </class>

Stopp

public class Stop implements Comparable<Stop>, Serializable  {

    private static final long serialVersionUID = 7823769092342311103L;
    private Integer stopID;
    private int routeID;
    private int coordinateID;
    }

2voto

Pascal Thivent Punkte 548176

Der erste Fehler, den ich sehe, ist, dass Sie einen Cache auf der zweiten Ebene Cache von Hibernate, die bereits Zwischenspeichern werden behandelt werden Stop Einheiten. Das ist einfach nutzlos, der Cache der zweiten Ebene ist transparent, Sie müssen keine zusätzlichen Klassen hinzufügen (wie Element hier) oder zusätzlicher Code. Die DAO-Methode sollte also sein:

@Transactional(readOnly = true)
public Stop findById(int stopId) {
    return (Stop) sessionFactory.getCurrentSession().get(Stop.class, stopId);
}

Und das ist alles, nichts weiter. Ich wiederhole: Die Aktivierung der zweiten Ebene ist deklarativ, Sie brauchen Ihren Code nicht zu ändern.

Zweiter Fehler: Ihr aktueller Test wird nicht wirklich auf den Cache der zweiten Ebene zugreifen, die zweite Schleife verwendet dieselbe Sitzung und holt Objekte aus der Sitzung (dem Cache der ersten Ebene), nicht aus dem Cache der zweiten Ebene. Wenn Sie den Cache der zweiten Ebene testen wollen, verwenden Sie eine andere Sitzung (d.h. schließen Sie die erste und holen Sie eine andere aus der Sitzungsfabrik).

Ich würde empfehlen, die Protokollierung in der Kategorie org.hibernate.cache um alle Cache-Aktivitäten der zweiten Ebene zu protokollieren und sicherzustellen, dass die Dinge wie erwartet funktionieren.

Wenn Sie sicher sind, entfernen Sie die Protokollierung und wiederholen Sie den (festen) Test mit einer größeren Stichprobe (x10 oder x100).

0voto

mdma Punkte 55529

Hibernate wird den Cache der zweiten Ebene automatisch verwenden, wenn Sie die <cache> Element in Ihre Mapping-Datei aufnehmen. Sie müssen den Cache vor und nach dem Abrufen von Objekten aus Ihrer Sitzung nicht explizit verwalten.

Haben Sie es mit einer größeren Anzahl von Objekten versucht? Benchmarks unter einer Sekunde sind nicht sonderlich zuverlässig.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X