35
Orientation in Objects GmbH Weinheimer Str. 68 68309 Mannheim www.oio.de [email protected] Version: 1.1 Performance Tuning bei komplexen Domainmodellen Christian Dedek Falk Sippach © 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 2 ) Akademie ) ) Beratung ) Java, XML und Open Source seit 1998 Schulungen, Coaching, Weiterbildungsberatung, Train & Solve-Programme Methoden, Standards und Tools für die Entwicklung von offenen, unternehmens- weiten Systemen Schlüsselfertige Realisierung von Software Unterstützung laufender Projekte Pilot- und Migrationsprojekte ) Projekte )

Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

1

Orientation in Objects GmbH

Weinheimer Str. 6868309 Mannheim

[email protected]: 1.1

Performance Tuningbei komplexen

DomainmodellenChristian Dedek

Falk Sippach

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 2

) Akademie )) Beratung )

Java, XML und Open Source seit 1998

• Schulungen, Coaching, Weiterbildungsberatung, Train & Solve-Programme

• Methoden, Standards und Tools für die Entwicklung von offenen, unternehmens- weiten Systemen

• Schlüsselfertige Realisierung von Software• Unterstützung laufender Projekte• Pilot- und Migrationsprojekte

) Projekte )

Page 2: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

2

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 3

Performance?

Autor unbekannt

"You need the computing power of a Pentium, 16 MB RAM and 1 GB Harddisk to run Win95.

It took the computing power of

3 Commodore 64 (C64) to fly to the Moon.

Something is wrong here, and it wasn't the Apollo."

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 4

Agenda

• Problemstellung• Navigation in Objektnetzen• Caching• Veränderung von Objektnetzen• Diverses• Lessons learned

Page 3: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

3

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 5

Hibernate ist ein "einfaches"Persistenzframework

<<Tabelle>>Person

PERSON_ID<<PK>>FIRSTNAME....

<<Tabelle>>Adresse

ADRESSE_ID<<PK>>PERSON_ID<<FK>>STRASSE...

Collection

PersonAdresseAdresseAdresseAdresse

1 n

session.save(person);...person = session.load(Person.class, 1L);for (Adresse a : person.getAdressen) {

...}

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 6

Was ist bei komplexen Domänenmodellen?

Beleg

Gruppen

G1 G2

P11 P12 P21 P101 P102

Positionen

Positionen Positionen

Entität

Collection

Page 4: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

4

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 7

Performance-Probleme mit Hibernate ?

• Hibernate verursacht natürlich Overhead– durch OR-Mapping, Dirty-Checking, DB-Unabhängigkeit, ...

• Hibernate bringt auch Vorteile: z. B. Caches– aber ggf. nutzlos durch falsche Verwendung

• Was tun?– Optimierungsmöglichkeiten von Hibernate ausnutzen– Stored Procedures oder direkt SQL aus Hibernate aufrufen (DB

spezifische Abfrage-Optimierung)– Alternativen zu Hibernate: JDBC, iBatis, ...

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 8

Vorgehensweise Performance-Tuning

• Durchführung von Last- und Performanztests• Testszenarien (aus Use Cases) und deren Qualitätsziele festlegen

– sinnvolle Testdaten (wenn möglich auch Massendaten für Lasttests)• Problem Testdatenbeschaffung und -reproduktion

– Testszenarien sollten mit vertretbarem Aufwand wiederholbar sein– ev. Definition von Key Performance Indikator

• Testläufe müssen reproduzierbar sein– vor Performance-Tuning muß das mehrfache Ausführen eines

Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern• Scheduling, Netzwerk...

• kleine Performance-Iterationen– ein spezielles Tuning und danach Testlauf um Effekt zu erkennen

• Einsatz spezialisierter Werkzeuge

Page 5: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

5

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 9

Aktivitäten bei der Testdurchführung

Zielbestimmungen und Mengengerüst festlegen

Testumgebung und Rahmenbedingungen erfassen

Testplan festlegen

Testszenarien festlegen

Test durchführen

Analyse durchführen

Maßnahmen durchführen

Misserfolg analysieren

[gewichtiger Fehler]

[nicht aussagekräftig]

[erfolgreich][nicht erfolgreich]

[nicht behebbar][behebbar]

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 10

Lasttesttreiber - The Grinder 3

helloWorldService.pyfrom net.grinder.script.Grinder import grinderfrom net.grinder.script import Testfrom examples.webservices.basic.javaclass import HelloWorld_Implfrom java.lang import System

System.setProperty( "javax.xml.rpc.ServiceFactory", "weblogic.webservice.core.rpc.ServiceFactoryImpl")

webService = HelloWorld_Impl("http://localhost:7001/basic_javaclass/HelloWorld?WSDL")

port = webService.getHelloWorldPort()portTest = Test(1, "JAXP Port test").wrap(port)

class TestRunner: def __call__(self): result = portTest.sayHello(grinder.threadID, grinder.grinderID) grinder.logger.output("Got '%s'" % result)

Page 6: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

6

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 11

Lasttestanalysen durchführen

Skript

Anz

ahl I

nsta

nzen

Anzahl Testläufe

Analyseunterstützung

Speichern als PNG

Grinder-Import

logs

data_xxx.log

error_xxx.log

skript1

skript2

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 12

Werkzeuge - Monitoring Tools

• Profiler: z. B. JProfiler, JProbe, PerformaSure• JMX-Tooling: z. B. JConsole, AdventNet, MC4J, ...

Page 7: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

7

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 13

Hibernate Statistics:JConsole, Statsviewer

<bean id="jmxExporter" class="org.springframework.jmx.export.MBeanExporter"> <property name="beans"> <map> <entry key="Hibernate:name=statistics"> <ref local="statisticsBean" /> </entry> </map> </property></bean>

<bean id="statisticsBean" class="org.hibernate.jmx.StatisticsService"> <property name="statisticsEnabled"> <value>true</value> </property> <property name="sessionFactory"><ref bean="sessionFactory"/></property></bean>

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 14

Werkzeuge - DB-Analyzer

• Tracer: z. B. P6Spy, IronTrack SQL, Elvyx• SQL-Clients: z. B. Toad, SQL-Developer (für Oracle DB)

Page 8: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

8

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 15

Live-Demo

• Anwendung steht für mehrere Minuten• Ermittlung der Ursache per P6Spy und IronTrack SQL

– eine bestimmte DB-Abfrage dauert sehr lange• per SQL-Tool (Explain-Plan, Autotrace)

• 1000 Einträge aus Tabelle1 löschen– "delete from Tabelle1 where ..."– Full Table Scan in Tabelle2 (Constraint-Überprüfung)

• Ursache: Index auf TABELLE1_FK-Spalte fehlt

<<Tabelle>>Tabelle1

ID <<PK>>....

<<Tabelle>>Tabelle2

ID <<PK>>TABELLE1_FK <<FK>>...

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 16

Autotrace-Auswertung in SQL-Tool:Optimierung durch Einführung von DB-Indizes

• ohne Index

• mit Index

Page 9: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

9

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 17

Agenda

• Problemstellung• Navigation in Objektnetzen• Caching• Veränderung von Objektnetzen• Diverses• Lessons learned

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 18

Java Virtual Machine

„Hibernate in 30 Sekunden“

*.classJava Compiler

Hibernate

DB hibernate.cfg.xml

*.hbm.xml

Page 10: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

10

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 19

Schichtentrennung

Business Layer

Persistence Layer

Session Transaction Query

SessionFactory

Configuration

Interceptor

UserType

JNDI JDBC JTA

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 20

Optimierte Navigation in komplexenObjektnetzen/Relationen ?

Mannheim

GreenSupply

Hauptstrasse 174G7/2

Heidelberg<<Tabelle>>

Person

PERSON_ID<<PK>>FIRSTNAME....

<<Tabelle>>Adresse

ID<<PK>><<FK>>STRASSE...

id plzpositionstrasse

Page 11: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

11

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 21

Relationen navigieren

• Navigationsgeschwindigkeit optimieren– vollständiges Objektnetz in Speicher laden– komplexe Netze brauchen viel Speicher

• Speicherverbrauch optimieren– Relationen werden bei Bedarf nachgeladen– sog. N+1 Problem

• mögliche Lösungen– Batch Fetching– Subselect Fetching– Join Fetching (Achtung: Karthesisches Produkt)– HQL– Filter

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 22

N+1 Problem

List<Person> allPersons = session.createQuery("from Person").list();// List<Person> allPersons = session.createCriteria(Person.class).list();

Map<Person, Address> highestAddresss = new HashMap<Person, Address>();for (Person person : allPersons) { Address highestAddress = null; for (Address address : person.getAddresss() ) { // Initialize the coll. if (highestAddress == null) highestAddress = address; if (address.getPLZ() > highestAddress.getPLZ()) highestAddress = address; } highestAddresses.put(person, highestAddress);}

1 select für Liste der Entitäten+ n select für jede navigierte Relation

Page 12: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

12

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 23

Batch-Fetching

<set name="Addresss" inverse="true" batch-size="10">

<key column="Person_ID"/> <one-to-many class="Address"/>

</set>

1 select für Liste der Entitätenselect Persons...

+ n/batchsize selects für jede Gruppe navigierter Relationenselect a.* from Address a where a.Person_ID in (?<,?>)

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 24

Laden mit Subselects

<set name="Addresss" inverse="true" fetch="subselect">

<key column="Person_ID"/> <one-to-many class="Address"/>

</set>

1 select für Liste der Entitätenselect Persons...

+ 1 select für alle navigierte Relationenselect a.* from Address awhere a.Person_ID in (select p.Person_ID from Person p)

Page 13: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

13

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 25

Laden mit joins

•Fetchplan<set name="addresses" inverse="true" fetch="join">

<key column="Person_ID"/> <one-to-many class="Address"/>

</set>

1 select für Liste der Entitäten mit allen navigierbaren Relationenselect p.*, a.*from Person pleft outer join Address a on p.Person_ID = a.Person_ID

•besonders interessant für n-1-Relation

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 26

Laden mit expliziten Queries

Alternative Abfrage für eine Liste der Entitäten mit allen navigierbarenRelationen in spezifischem Anwendungsszenario

List<Person> allPersons =session.createQuery("from Person p left join fetch p.Addresss").list();

List<Person> allPersons = session.createCriteria(Person.class) .setFetchMode("addresses", FetchMode.JOIN) .list();// Iterate through the collections...

Es resultiert eine Datenbankanfrage

select p.*, a.*from Person pleft outer join Address a on p.Person_ID = a.Person_ID

Page 14: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

14

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 27

Kartesische Produkte

id Fla..Bewoh..name id satzleistungname id aktivornamename

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 28

• mit jeder Relation potenziert sich die Größe des resultierendenAnfrageergebnisses– DB-Server

• Abfragezeit• IO-Aufwand

– Applikation• Speicherverbrauch• Mappingaufwand in Hibernate

Kartesische Produkte

Page 15: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

15

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 29

Filter

• Mapping<class name=“City" table=“KA_STADT" lazy="false">.. <set name=“dezernenten“ table=“KA_DEZERNENT“ cascade="all,delete-orphan" lazy="false"> <key foreign-key="FK_KA_DEZERNENTEN“ column=“KA_STADT_ID" not-null="true" /> <one-to-many class="de.ex.Dezernent" /> <filter name="limitbyParty “ condition=“PARTY_NAME = :partId"/> </set>..</class>

• AnwendunggetHibernateTemplate().enableFilter("limitByParty").setParameter(“partId",“DIE GRAUEN“);..

getHibernateTemplate().getSessionFactory().getCurrentSession().disableFilter("limitbyParty");

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 30

Feintechniken

• Value types– Komponente im Kompositum (fehlender Lebenszyklus)

• extra Lazy Proxy Collection– ev. nützlich bei sehr großen Assoziationsmengen

• Lazy Attribute Fetching– bei LOB-Feldern bereits implizit

• Interception statt Proxies– Aufwand eigenimplementierter Lösungen?

Page 16: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

16

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 31

Feintuning

• zu komplexe DB-Anfragen– DB-spezifische Optimierung der execution plans– Minimierung von join-fetches

• zu viele DB-Anfragen– fetch-Typen definieren

• eher an der Abfrage als global• Batchsizes an Verarbeitungsgruppen(Screens) orientieren

– Alternative - Caching erwägen ?

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 32

Optimierungsstrategie

• Ausgangspunkt: Lazy Default-Fetch-Plan– n-1/1-1-Relationen mit lazy=false

• dann: Szenarien bezogenes Aufzeichnen• der auslösenden Hibernateanfragen• der resultierenden DB-anfragen

• daraus: Optimierung der Zahl und Komplexität der resultierendenDB-Anfragen durch Anpassung der Fetchstrategie der initiiertenHibernateanfragen– spezifische Optimierung einer Anfrage– seltener Optimierung des globalen Fetchplans

• Vorsicht Kostenfalle: manuelle Testausführung– globale Fetchplanänderungen erfordern Regressionstest– Lernkurve beachten

Page 17: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

17

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 33

bekannte Architektur Muster

• Open Session in View Pattern– Navigation nutzt Sessioncache

• aber nutzt globale Fetchoptimierung(side Effects ?)– Query wirkt nicht auf Session Cache

• Vorteil optimierter spezifischer Fetchplan

• spezifische Service Fassade– Ausgangspunkt Navigation über Session– Optimierung über spez. Finder in DAO– DAO-Schnittstelle wird breiter/Wartungsaufwand

• generisches DAO (Preload Pattern JavaMagazin 4/08)– schmale Finder-Schnittstelle– keine spezifischer Fetch-Plan

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 34

Agenda

• Problemstellung• Navigation in Objektnetzen• Caching• Veränderung von Objektnetzen• Diverses• Lessons learned

Page 18: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

18

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 35

Live Demo: Hibernate Statistics

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 36

Caches in Hibernate

• First-Level:– immer aktiviert– nur solange die eine Session offen ist– funktioniert nur bei Aufruf von load/get und bei Assoziationen-Fetch– funktioniert nicht bei Queries

• Second-Level:– muß erst aktiviert werden– Konfiguration nicht trivial– Query-Cache muß separat aktiviert werden

Page 19: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

19

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 37

Cache-Konfiguration

• in Hibernate-Settings aktivieren– CacheProvider (EHCache, OSCache, SwarmCache, TreeCache)– use_second_level_cache=true

• Cache Regions (angeben für Klassen, Collections oder Queries)– Usecase spezifisch optimieren– usage: Caching Strategie

• read-only:beste Performance• nonstrict-read-write: nur für nicht konkurrierende Zugriffe• read-write: gewährleistet read-commited• transactional: nur bei JTA-Umgebungen

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 38

Gefahren bei Second Level Caches

• andere Applikationen, welche die DB ändern– Cache muß regelmäßig validiert werden

• zu viele schreibende Zugriffe– Cache-Miss größer als Cache-Hit: schlechtes Cache-Ratio

• zu kleine Dimensionierung des Cache– sollte aber auch nicht zu groß dimensioniert werden (GC dauert

länger, längere Validierungsphase mit DB)

Performance kann sogar sinken (durch hohen Verwaltungsaufwand).

Page 20: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

20

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 39

Problem: fehlender Cache-Hit

• Beobachtung: Session Cache arbeitet nicht richtig– immer wieder die gleichen SQL-Selects im Log-Output

• Ursache: statt mit load/get wird mit HQL-Findern gearbeitet– von AndroMDA generierter Code arbeitet mit findById– Bug mittlerweile gefixed: AndroMDA generiert jetzt session.get()

• Alternative für finder: Query-Cache einschalten

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 40

Query-Cache

• Query-Cache überhaupt erstmal einschalten

• Query-Cache speichert nur IDs– muß mit Entity-Cache zusammen arbeiten

• nur sinnvoll für häufige Abfragen mit immer gleichen Parametern• darum werden Queries defaultmäßig nicht gecached

– setCacheable(true) aufrufen!

public Object getObjectByName(String name) { Query q = session.createQuery("from Object where name = ?"); q.setParameter(0, name); q.setCacheable(true); return q.uniqueResult();}

<prop key="hibernate.cache.use_query_cache">true</prop>

Page 21: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

21

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 41

Unwirksamer Cache

• z. B. bei Abfragen mit ständig wechselnden Parametern

• ggf. eigene Caches implementieren– insbesondere wenn immer der gleiche Datensatz geholt wird– dazu alle abzufragenden Datensätze laden und in Java vergleichen

• funktioniert nur bei überschaubarer Anzahl von Datensätzen!

hql = "from de.oio.Firma ... where validFrom <= :date and validTo >= :date";

Query q = session.createQuery(hql);for(..) {

q.setDate(..);q.list();

}

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 42

Agenda

• Problemstellung• Navigation in Objektnetzen• Caching• Veränderung von Objektnetzen• Diverses• Lessons learned

Page 22: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

22

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 43

Collections

• Arten– Indizierte collections

• maps/lists/arrays über eine index Spalte– Sets

• Uniqueness– Bags

• keine Garantien zu Reihenfolge oder Uniqueness• Id-bag

• TODO Visuell

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 44

Flushing-Probleme: Vorher

Page 23: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

23

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 45

Hintergrund

• Hibernate Session:– 1st Level Cache, muß mit DB synchronisiert werden -> Flushing

• Flushing:– Session.flush()– Transaction.commit()– bei DB-Abfragen (Dirty Check)

• Dirty Check:– Objektänderungen so lange wie möglich in der Session vorgehalten– bei Abfragen ggf. zuerst aufgelaufene Änderungen wegschreiben– Änderungen werden ermittelt und DML-Anweisungen generiert

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 46

Probleme

• je mehr Daten in der Session, desto länger dauert Dirty Check• Flush aber oftmals gar nicht notwendig

• Lösungen:– Operationen neu ordnen– Objekte aus Session abhängen (read-only)– mit dem Flush warten bis zum Commit (write behind)– Anwendung kontrolliert explizit Flushing

• Default Flushing Verhalten ändern:– MANUAL, COMMIT, AUTO, ALWAYS

Page 24: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

24

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 47

Nachher: Flushmode.COMMIT

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 48

Massendaten-Verarbeitung:1000 Datensätze löschen

2000 SQL-AnweisungenSession-Cache wird unnütz befüllt

eine SQL-Anweisungminimale DB-Kommunikation

for (...) {Entity e = session.load(Entity.class, id);session.delete(e);

}

String hql = "delete from Entity where idbetween ...";

session.createQuery(hql).execute();

Page 25: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

25

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 49

Single SQL statement

• Objekte können verarbeitet werden, ohne sie vorher in Speicherzu laden (Hibernate unterstützt INSERT/UPDATE/DELETE)– update Person set gehalt = :newGehalt where status = 'Chef'

• separates Löschen von vielen Elementen ist ineffizient– session.delete()– Vorsicht: Springs HibernateTemplate.deleteAll(Collection col) iteriert

über Collection und löscht jedes Element einzeln

• Collection-Mapping Delete-Optimierung– Hibernate erzeugt einzelnes DELETE bei Collection.clear()– funktioniert nicht mit inverse="true" (bidirektionalen Beziehungen)

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 50

Stateless Session

• ideal für Ausführung von Bulk/Batch Operationen (funktioniertauch mit detached Objects)

• ähnlich einer normalen Session, aber– kein Persistenz-Kontext, kein Cache (weder 1st noch 2nd)– kein automatisches Dirty Checking oder transaktionales Write Behind– kein kaskadierendes Verhalten, ignoriert Collections– umgeht Event-Modell und Interceptoren

sessionFactory.openStatelessSession()

Page 26: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

26

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 51

DB Performance Tuning

• DB Administratoren fragen• SQL-Dialect nach herstellerspezifische Features untersuchen

– ggf. eigenen Dialekt schreiben

• DB-Indizes– fehlen meist bei Grüne-Wiesen-Projekten– DB generiert typischerweise nur Unique-Constraints (PK, ...)– FK-Felder sollten Index erhalten, wenn Sie oft abgefragt werden– aber:

• nicht zu viele Indizes sonst leidet Insert/Update Performance• Indizes immer überprüfen, ob sie überhaupt verwendet werden

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 52

Hibernate Indizes

• Hibernate unterstützt Index-Definition in Mapping-Files

• für Properties und Assoziationsenden

<property name=".." index="idx" />

<many-to-one name=".." index="fk_idx" />

Page 27: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

27

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 53

Agenda

• Problemstellung• Navigation in Objektnetzen• Caching• Veränderung von Objektnetzen• Diverses• Lessons learned

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 54

Probleme bei Rich-Client Architekturen

• leider oft: feingranulare Services– CRUD-Schnittstelle für jede Domain-Klasse (auch für jedes Kind)– viele Aufrufe an Backend (Netzwerkverkehr)

• bei Objektnetzen hängt teilweise der ganze Objektbaum dran– Speicherprobleme bei falschem oder fehlendem Umhängen der

Abhängigkeiten (besonders bei bidirektionalen Verbindungen)

• besser: grobgranulare Fassaden– Usecase-spezifisch– Minimierung der Aufrufe ans Backend– Verringerung der Memory-Spitzen durch weniger RMI-Kopien

Page 28: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

28

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 55

C2 wird ans Backend geschickt und dann inCollection Children ausgetauscht

Parent

Children

C1 C2

service.method(C

2)

IN

OUT

vorher:

nachher:Parent

Children

C1 C2

Parent_1

Children_1

C1_1

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 56

Herausgelöste Objekt-Teilgraphen

• Speicher läuft voll bei Remote-Kommunikation– durch RMI erhalten wir mehrere Objekte im Speicher mit gleicher

Datenbank-Identität– diese "Kopien" enthalten ggf. wieder den kompletten (kopierten)

Objektgraphen, je nach globaler Fetching-Strategie

• GC kann Speicher nicht freiräumen, wenn noch Referenzen aufKopien des Objektgraphen bestehen– z. B. durch falsches Setzen der bidirektionale Beziehungen– Workaround für bidirektionale Beziehungen:

addChild(Child child) {this.getChildren().add(child);child.setParent(this);

}

Page 29: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

29

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 57

Probleme Hibernate Interceptor

public interface Interceptor {

public boolean onLoad(..) throws CallbackException;public boolean onFlushDirty(..) throws CallbackException;boolean onSave(..) throws CallbackException;public void onDelete(..) throws CallbackException;[..]public void postFlush(Iterator entities) throws Callba..;

public void afterTransactionCompletion(Transaction tx);

Aufräumen des Interceptor: afterTransactionCompletion()Aber: Aufruf nur bei Hibernate-Transaktionen, nicht bei JTA

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 58

ThreadLocal bei Hibernate Interceptor

• ThreadLocal-Variable muß immer aufgeräumt werden– ThreadLocal.remove();

– ThreadLocal kann sonst Memory-Leaks verursachen

• Verwendung eines ThreadLocals im Hibernate Interceptor– bei Nicht-Hibernate-Transaktionen wird nicht aufgeräumt– ThreadLocal-Objekt bleibt also bei einer Exception im Speicher– gefixed ab Hibernate 3.2.6:

• es wird nun immer implizit eine Hibernate-Transaktion gestartet• dadurch wird Interceptor korrekt deinitialisiert

• Spring-Workaround für ältere Hibernate-Versionen:– AOP-Throw-Advice für Service-Aufrufe, der Interceptor aufräumt

Page 30: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

30

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 59

Garbage Collector Aufwand optimieren

• Genutzten Speicher minimieren– Speicher ist zwar immer billiger aber weiterhin begrenzt

• z.B. ineffizientes caching führt zu erhöhtem Bedarf an GarbageCollections

– Caching ist kein High-level-Fix für Probleme tieferer Schichte– explizite Eviction an der SessionFactory als manueller Eingriffspunkt

im API

• Bessere GC-algorithmen– hilft bei „typischen Verfügbarkeitsproblemen“

• Phänomen seit Jahrzehnten bei GC-Sprachen bekannt– paralleler GC-algorithmus auf multi-prozessor systemen– schwierig (aber notwendig) zu testen

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 60

Spring Bugs

• http://jira.springframework.org/browse/SPR-1690– falsche Errorcodes für Deadlocks in DB

• http://jira.springframework.org/browse/SPR-2888– Deadlock bei spezieller init– Deadlock beim Exceptionhandling von Connections

• http://jira.springframework.org/browse/SPR-3961– Running benchmarks under high loads with 8 or more concurrents

threads I see significant lock contention from the synchronized blockinorg.springframework.aop.framework.AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice. This is a significant bottleneck in ourbenchmarks.

• http://jira.springframework.org/browse/SPR-1968– wzeite readonly Session in Spring um JSF zu unterstützen

Page 31: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

31

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 61

Hibernate Bugs

• http://opensource.atlassian.com/projects/hibernate/browse/HHH-2841 Deadlock im Jboss offen

• http://opensource.atlassian.com/projects/hibernate/browse/HHH-1669 mögliches Memoryleak

• http://opensource.atlassian.com/projects/hibernate/browse/HB-1246 seltener Deadlock wont fix

• Deadlocks in Treibern– http://opensource.atlassian.com/projects/hibernate/browse/HHH-1167

• Deadlocks in Pools– http://opensource.atlassian.com/projects/hibernate/browse/HHH-3189

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 62

Agenda

• Problemstellung• Navigation in Objektnetzen• Caching• Veränderung von Objektnetzen• Diverses• Lessons learned

Page 32: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

32

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 63

Best Practices I

• Anwendung einer optimistic concurrency zur Implementierungeiner hohen Skalierbarkeit sinnvoll

• Definition einer klaren Sessionmanagement Strategy– vorteilhaft ist Einbindung in gut dokumentierte Patterns

• Default Fetch Plan für Assoziationen ist lazy– Optimierung erfolgt gemäß Kapitel 2– sehr breiter Featureset(Filter,Projektionen,Interceptoren..) zur

Optimierung

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 64

Best Practices II

• Definition der Caching Strategie– Festlegen welche Bereiche über Navigation (Session Cache) und

welche über Finder (Query Cache optimieren)– Entity-Cache fein anpassen und tunen

• Verständnis für Implementierungsdetails hilft beim Optimieren

• Definition einer einheitlichen flush-Strategie– Feintuning: Hibernate auto-flush vs. use case spezifische

Synchronisation

• Untersuchung der GC-Aktivitäten– Minimierung des GC-Aufwands– Erkennung (minimaler) Memoryleaks

Page 33: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

33

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 65

Nichtfunktionale QM-Strategie

• Performance Meta Antipattern „Performance Afterthoughts“ istRealität in der agilen Entwicklung

• nichtfunktionales Qualitätsmanagement benötigt– fachlich richtige und realitätsnahe Testfälle– Automatisierung– Entwicklungsbegleitung– Technologische Kompetenz

• Hibernate/Spring• eingesetztes RDBMS

– Integration ins Entwicklungsteam• Empfehlung: Definition von Key Performance Indikatoren

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 66

Architekturelle Reife

• Die vorkonfektionierte Grobarchitektur Spring/Hibernate– hat viele gute Standardeinstellungen in Bezug auf Performanzaspekte

• in beiden Frameworks– Communities sorgen für Praxisnähe und -einsatz der Ideen– bietet bei Bedarf sehr viele Möglichkeiten für

Performanzoptimierungen• oft einfach durch reine Konfiguration

• Leistungsgrenzen der Kombination Spring/Hibernate sind amtechnologischen Gesamtstack aus JVM/OS/RDBMS/Netzwerk/IOangelehnt

Page 34: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

34

© 2008 Orientation in Objects GmbH Performance Tuning bei komplexen Domainmodellen 67

Der Kaufmann rechnet - oder Reife vs.Produktivität

• POJO-Development erhöht Entwicklungsgeschwindigkeit undsenkt den technischen QM-Aufwand– fast direkte Implementierung fachlicher Modelle möglich

• rasante Entwicklung von Spring/Hibernate/Tooling seit 2003senkte bisher die Entwicklungsgeschwindigkeit– sehr hoher Entwicklungsdruck fordert Qualitätsopfer

• Vorteil: Open Source schafft hier Transparenz– erfordert ständigen KnowHow-Transfer in die Entwicklung

• gerechtfertigt durch Produktivitäts- und Qualitätssteigerungen – zwingt zu Migrationen der Infrastruktur

• Bsp. MDD-Generatoren, Konfigurations-, Buildmanagement,Codeanalysewerkzeuge

Orientation in Objects GmbH

Weinheimer Str. 6868309 Mannheim

[email protected]: 1.1

? ?

???

Fragen ?

Page 35: Performance Tuning bei komplexen Domainmodellen...– vor Performance-Tuning muß das mehrfache Ausführen eines Testlaufs gleiche oder zumindest ähnliche Ergebnisse liefern • Scheduling,

35

Orientation in Objects GmbH

Weinheimer Str. 6868309 Mannheim

[email protected]: 1.1

Vielen Dank für IhreAufmerksamkeit !