SlideShare une entreprise Scribd logo
1  sur  50
Ihre
Persistenzschicht?
Kunde, Chef, DBA?
Tuning von
Hibernate und JPA
Anwendungen
Michael Plöd
Michael Plöd
• Architekt bei Senacor Technologies AG in
  Nürnberg
• http://www.senacor.com
• michael.ploed@senacor.com
• http://rockingcode.blogspot.com
• Twitter: @bitboss
IST ORM
LANGSAM
Zu                        Zu
 viele                   langsame
Abfragen                 Abfragen



            Gründe für
             schlechte
           Performance


 Falsch                   Falsch
getunte                  getunte
Daten-                     Infra-
  bank                   struktur
Klassifizierung von
Anzahl der   1.500
                  Abfragen
 Abfragen


             1.125



              750



              375



                0
                     0   225   450   675     900
                                           Durchschnittliche
                                            Laufzeit in [ms]
Ursachen
 Hohe Häufigkeit            Hohe Laufzeit
! Applikations-Logik     ! Zu hohe Selektivität
! Mappings               ! Variablen-Übergabe
! Kein Caching           ! Fehlende Indizes
! N+1 Selects Problem    ! Karthesisches Produkt
                         ! Locks
                         ! Datenbankstruktur
N+1 Selects Problem


List list = s.createCriteria(Konto.class).list();
for (Iterator it = list.iterator(); it.hasNext();) {
  Konto kto = (Konto) it.next();
  kto.getKunde().getName();
}

SELECT   *   FROM   KONTEN
SELECT   *   FROM   PERSONEN WHERE PERSON_ID = ?
SELECT   *   FROM   PERSONEN WHERE PERSON_ID = ?
SELECT   *   FROM   PERSONEN WHERE PERSON_ID = ?
...
Karthesisches Produkt
@Entity
public class Konto {
 ...
 @OneToMany(fetch=FetchType.EAGER)
 public Set<Buchung> getBuchungen() {...}

  @OneToMany(fetch=FetchType.EAGER)
 public Set<Vollmacht> getVollmachten() {...}
 ...
}

select konto.*, buchung.*, vollmacht.*
  from KONTEN konto
  left outer join BUCHUNGEN buchung
     on konto.ID = buchung.KTO_ID
  left outer join VOLLMACHTEN vollmacht
     on konto.ID = vollmacht.KTO_ID
Karthesisches Produkt
select konto.*, buchung.*, vollmacht.*
  from KONTEN konto
  left outer join BUCHUNGEN buchung
     on konto.KTO_ID = buchung.KTO_ID
  left outer join VOLLMACHTEN vollmacht
     on konto.KTO_ID = vollmacht.KTO_ID


KTO_ID   KTO_NR   ...   BUCH_ID   BUCH_BETRAG    ...   VM_ID    VM_NAME         ...
  1       12344   ...     10        1000,00 !    ...    200     Michael Plöd    ...
  1       12344   ...     10        1000,00 !    ...    300     Martin Plöd     ...
  1       12344   ...     20        -324,23 !    ...    200     Michael Plöd    ...
  1       12344   ...     20        -324,23 !    ...    300     Martin Plöd     ...
  1       12344   ...     30        543,11 !     ...    200     Michael Plöd    ...
  1       12344   ...     30        543,11 !     ...    300     Martin Plöd     ...
  2       21300   ...     40        -4323,23 !   ...    400    Sandra Ulrich    ...
  2       21300   ...     40        -4323,23 !   ...    400    Melanie Ulrich   ...
  2       21300   ...     40        -4323,23 !   ...    400    Herbert Ulrich   ...
  ...      ...    ...     ...           ...      ...    ...          ...        ...
Gutes

TUNING
Anzahl oder Laufzeit?
ist

IMMER
eine Frage der

BALANCE
FETCHING       CACHING ABFRAGEN
! Batch        ! 1st Level Cache     ! Selektivität
! Subselect    ! 2nd Level Cache     ! Query Cache
! Eager        ! Stateless Session   ! Bind Variablen


   LOGIK          LOCKS                Runtime
! Schleifen    ! Optimistic          ! DB Entwurf
                  Locking
! Datenmenge                         ! Konfiguration
                                     ! Connection Pool
Fetching
Batch Fetching


@Entity
public class Konto {        SELECT k.* FROM KONTEN k
 @ManyToOne(...)
 public Person getKunde()   SELECT * FROM PERSONEN
  {...}                     WHERE PERSON_ID IN (?, ?, ?, ?, ?)
 ...
}                           SELECT * FROM PERSONEN
                            WHERE PERSON_ID IN (?, ?, ?, ?, ?)
@Entity
@BatchSize(size=5)          SELECT * FROM PERSONEN
public class Person {       WHERE PERSON_ID IN (?, ?, ?)
 ...
}
Batch Fetching
1.500
                                    ! Schätzung
1.125
                                    ! Einfach
 750

 375                                ! Lazy
   0
        0   225   450   675   900
                                    ! (N / Batch Size) + 1
Subselect Fetching


@Entity
public class Konto {            SELECT k.* FROM KONTEN k
 @OneToMany
  @Fetch(FetchMode.SUBSELECT)   SELECT b.* FROM BUCHUNGEN b
                                WHERE b.KTO_ID IN (
 public Set getBuchungen()        SELECT k.KTO_ID FROM KONTEN k
  {...}                         )
 ...
}
Subselect Fetching
1.500
                                    ! Nur für Collections
1.125                               ! Keine Schätzung
 750
                                    ! Einfach
 375
                                    ! Lazy
   0
        0   225   450   675   900
                                    ! 2 Abfragen
Eager Fetching

@Entity
public class Konto {
 @OneToMany(
   fetch = FetchType.EAGER
 )                                SELECT   ko.*, b.*,   ku.*
 public Set getBuchungen()          FROM   KONTEN ko
 {...}                              LEFT   OUTER JOIN   BUCHUNGEN b
                                      on   b.KTO_ID =   ko.KTO_ID
                                    LEFT   OUTER JOIN   KUNDEN ku
 @ManyToOne(                          on   ko.KU_ID =   ku.KU_ID
    fetch = FetchType.EAGER
  )
  public Kunde getEigentuemer()
  {...}
}
Eager Fetching
1.500                               ! Nie bei 2+ Collections!
1.125
                                    ! Nicht Lazy
 750
                                    ! 1 Abfrage
 375

   0                                ! Nie in globalen Fetch
        0   225   450   675   900      Plan aufnehmen
Caching
Caching Architektur
First Level Cache

  Persistenz Kontext A        Persistenz Kontext B   Persistenz Kontext C



Second Level Cache

 Cache Concurrency Strategy                          Query Cache



Cache Implementierung
     Klassen Cache             Collection Cache         Query Cache
         Region                     Region                Region
                                                     Update Timestamps
                                                       Cache Region
Infrastruktur
 1st Level Cache only
     Virtual Machine 1

        SessionFactory

    Session        Session

    Session        Session

    Session        Session
Infrastruktur
Lokale 2nd Level Caches
     Virtual Machine 1

        SessionFactory

    Session        Session

    Session        Session

    Session        Session

      Second Level Cache
Infrastruktur
             Lokale 2nd Level Caches
 Virtual Machine 1             Virtual Machine 2

    SessionFactory                SessionFactory

Session        Session        Session        Session

Session        Session        Session        Session

Session        Session        Session        Session

  Second Level Cache            Second Level Cache
Infrastruktur
                 Verteilter Second Level Cache
           Virtual Machine 1           Virtual Machine 2

             SessionFactory               SessionFactory

       Session          Session       Session        Session

       Session          Session       Session        Session

       Session          Session       Session        Session

           Second Level Cache           Second Level Cache




Netzwerk
Welche
EXCEPTION
bekomme ich, wenn
ich
10.000.000 Objekte
lade?


OutOfMemory
!
             Hibernate
         verwaltet den
    1st Level Cache
      nicht von selbst!
Grundregeln
! ORM ist kein Batch Tool!
! Bei Massen-Verarbeitung regelmässig
  flushen und clearen!
! JDBC Batch-Size anpassen

for ( int i=0; i<100000; i++ ) {
    Konto konto = new Konto(...);
    session.save(konto);
    if ( i % 50 == 0 ) {
        session.flush();
        session.clear();
    }
}
Concurrency Strategies
                       Isolation bis zu
Transactional          repeatable read

                       Isolation bis zu
Read-Write             read commited

                     Keine Konsistenz Garantie, aber
Nonstrict-read-write Timeouts

Read-only              Nur für Daten, die sich nie ändern
Cache Provider
                                           Nonstrict
              Transactional   Read-write                Read-only
                                           Read-write

 EHCache                          x            x           x

 OSCache                          x            x           x

SwarmCache                                     x           x

JBoss Cache        x                                       x
Konfiguration
       org.hibernate.cache.provider_class

EHCache      org.hibernate.cache.EhCacheProvider

OSCache      org.hibernate.cache.OsCacheProvider

SwarmCache org.hibernate.cache.SwarmCacheProvider

JBoss Cache org.hibernate.cache.TreeCacheProvider
Mappings
! Annotation:
  @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)

! XML:
  <cache usage=“read-write“>

! Sowohl auf Klassen als auch auf Collection
  Level
! Volles Caching: Klasse + Collection!
Beispiel
@Entity
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Author implements Serializable {
...
    @Override
	 public int hashCode() { ... }
    @Override
	 public boolean equals(Object obj) { ... }
}	

@Entity
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class RecordReview implements Article {
...
    @OneToMany(fetch=FetchType.LAZY)
    @Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    private Set<Author> authors = new HashSet<Author>();
...
}
Cache Regions
  ! Einteilung in Cache Regions mit Naming
    Convention
  ! Cache Regions werden in Cache Provider
    Konfiguration referenziert

Klasse                            Voll qualifizierter Name
de.allschools.domain.Band         de.allschools.domain.Band


Collection                        Klasse + „.“ + Attribut
de.allschools.domain.Record#bands de.allschools.domain.Record.bands
EhCache Beispiel
                ehchache.xml
<ehcache>
	   <diskStore path="java.io.tmp"/>

	   <defaultCache maxElementsInMemory="10000" eternal="true"
	   	   overflowToDisk="true" />
	
	   <cache name="de.allschools.domain.Author"
       maxElementsInMemory="30"
       eternal="false"
       timeToIdleSeconds="900"
       timeToLiveSeconds="1800"
       overflowToDisk="true" />
	   <cache name="de.allschools.domain.RecordReview.authors"
       maxElementsInMemory="500"
       eternal="false"
       timeToIdleSeconds="600"
       timeToLiveSeconds="1200"
       overflowToDisk="true" />
     ...
</ehcache>
Auswahl von Caching Kandidaten?

KONSERVATIV
! Wenige Inserts und Updates

! Viele Lesezugriffe

! Unkritische Daten

! Von vielen Sessions benötigt

! Von vielen Usern benötigt
Stateless Session
! sessionFactory.openStatelessSession()
! Command orientierte API
! Kein Persistenz Kontext
! Kein Caching
! Kein Transaktionales write-behind
! Kein Cascading
! Keine Interceptors und Events
Abfragen
Selektivität
! Nur benötige Daten laden
! Möglichst früh einschränken
! Projection verwenden

Query query = getSession().createQuery(
   "select
    new TourCityInfo(t.name, d.timestamp, l)
    from Tour t
      inner join t.tourDates d
        with d.timestamp > :datum
      inner join d.location l
    where l.stadt=:stadt
    order by t.name asc"
);
"from User u
  where u.name=" + name

   " SQL Injection

   " Performance Killer

   " Heimtückisch
IMMER
        !
Query query =
                        BIND
                        VARIABLEN
                                      verwenden

session.createQuery("from User u where u.name= :name");
q.setString("name", "michael");
Query Cache
! Wird selten benötigt
! Nur für bestimmte Queries geeignet
! Wird extra konfiguriert:
  hibernate.cache.use_query_cache=true

! Muss pro Query / Criteria aktiviert werden:
  query.setCacheable(true);
Analyse
Logging
! Sehr detailliert, viele Informationen
! Interessant sind für Tuning:
   #   org.hibernate.jdbc - TRACE
   #   org.hibernate.SQL - TRACE
! Logging auch in User Types integrieren
! Sicht auf plain SQL
Statistics




! Müssen extra aktiviert werden
! Zugriff programmatisch oder JMX
Datenbank + Infrastruktur
 ! Auch in der Datenbank analysieren
    #   Sind alle Indizes korrekt gesetzt?
    #   Wie ist das Laufzeitverhalten?
 ! Gleiches gilt für Infrastruktur
    #   Connection Pool
    #   Transaktions Monitor
    #   Applikations Server
Laufen                    Messdaten
 lassen                     erheben



              Analyse
               pro
            Anwendungs-
                fall


 Nur eine                  Vergleich
  Tuning                  mit Referenz
Massnahme                  und Doku
Lasttest
! Arten
   #   Normale Last
   #   Stresstest
   #   Lange Lauzeiten
! Setup:
   #   Realistisches Hardware Sizing
   #   Realistische Datenmenge
VIELEN
DANK!
FRAGEN?
Michael Plöd
Senacor Technologies AG
michael.ploed@senacor.com

Contenu connexe

Similaire à Hibernate Tuning

Auszug Seminarmaterial "EJB 3.x"
Auszug Seminarmaterial "EJB 3.x"Auszug Seminarmaterial "EJB 3.x"
Auszug Seminarmaterial "EJB 3.x"schellsoft
 
Solr & Cassandra: Searching Cassandra with DataStax Enterprise
Solr & Cassandra: Searching Cassandra with DataStax EnterpriseSolr & Cassandra: Searching Cassandra with DataStax Enterprise
Solr & Cassandra: Searching Cassandra with DataStax EnterpriseDataStax Academy
 
Python Mike Müller
Python Mike MüllerPython Mike Müller
Python Mike MüllerAberla
 
Hands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und StolperfallenHands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und Stolperfalleninovex GmbH
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsQAware GmbH
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsJosef Adersberger
 
Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!OPEN KNOWLEDGE GmbH
 
Präsentation - GWAVA & Kroll Ontrack: Microsoft Exchange Recovery
Präsentation - GWAVA & Kroll Ontrack: Microsoft Exchange RecoveryPräsentation - GWAVA & Kroll Ontrack: Microsoft Exchange Recovery
Präsentation - GWAVA & Kroll Ontrack: Microsoft Exchange RecoveryGWAVA
 
Das Repository-Pattern und der O/R-Mapper: Geniale Kombination oder vergebene...
Das Repository-Pattern und der O/R-Mapper: Geniale Kombination oder vergebene...Das Repository-Pattern und der O/R-Mapper: Geniale Kombination oder vergebene...
Das Repository-Pattern und der O/R-Mapper: Geniale Kombination oder vergebene...André Krämer
 
Fanstatic pycon.de 2012
Fanstatic pycon.de 2012Fanstatic pycon.de 2012
Fanstatic pycon.de 2012Daniel Havlik
 
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Stephan Hochdörfer
 
Shibboleth Single-Sign-On mit TYPO3
Shibboleth Single-Sign-On mit TYPO3Shibboleth Single-Sign-On mit TYPO3
Shibboleth Single-Sign-On mit TYPO3tschikarski
 
Cloud Deployment und (Auto)Scaling am Beispiel von Angrybird
Cloud Deployment und (Auto)Scaling am Beispiel von AngrybirdCloud Deployment und (Auto)Scaling am Beispiel von Angrybird
Cloud Deployment und (Auto)Scaling am Beispiel von AngrybirdAOE
 
Big-Data-Analyse und NoSQL-Datenbanken
Big-Data-Analyse und NoSQL-DatenbankenBig-Data-Analyse und NoSQL-Datenbanken
Big-Data-Analyse und NoSQL-DatenbankenJohannes Schildgen
 
Cloud Native und Java EE: Freund oder Feind?
Cloud Native und Java EE: Freund oder Feind?Cloud Native und Java EE: Freund oder Feind?
Cloud Native und Java EE: Freund oder Feind?Josef Adersberger
 
Cloud Native & Java EE: Freund oder Feind?
Cloud Native & Java EE: Freund oder Feind?Cloud Native & Java EE: Freund oder Feind?
Cloud Native & Java EE: Freund oder Feind?QAware GmbH
 
Doctrine 2 - An Introduction (German)
Doctrine 2 - An Introduction (German)Doctrine 2 - An Introduction (German)
Doctrine 2 - An Introduction (German)Michael Romer
 
Startimpuls at Microsoft w/ IFJ
Startimpuls at Microsoft w/ IFJStartimpuls at Microsoft w/ IFJ
Startimpuls at Microsoft w/ IFJReto Laemmler
 

Similaire à Hibernate Tuning (20)

Auszug Seminarmaterial "EJB 3.x"
Auszug Seminarmaterial "EJB 3.x"Auszug Seminarmaterial "EJB 3.x"
Auszug Seminarmaterial "EJB 3.x"
 
Solr & Cassandra: Searching Cassandra with DataStax Enterprise
Solr & Cassandra: Searching Cassandra with DataStax EnterpriseSolr & Cassandra: Searching Cassandra with DataStax Enterprise
Solr & Cassandra: Searching Cassandra with DataStax Enterprise
 
Python Mike Müller
Python Mike MüllerPython Mike Müller
Python Mike Müller
 
Hands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und StolperfallenHands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und Stolperfallen
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
 
Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!
 
JavaScript Performance
JavaScript PerformanceJavaScript Performance
JavaScript Performance
 
JavaScript Performance
JavaScript PerformanceJavaScript Performance
JavaScript Performance
 
Präsentation - GWAVA & Kroll Ontrack: Microsoft Exchange Recovery
Präsentation - GWAVA & Kroll Ontrack: Microsoft Exchange RecoveryPräsentation - GWAVA & Kroll Ontrack: Microsoft Exchange Recovery
Präsentation - GWAVA & Kroll Ontrack: Microsoft Exchange Recovery
 
Das Repository-Pattern und der O/R-Mapper: Geniale Kombination oder vergebene...
Das Repository-Pattern und der O/R-Mapper: Geniale Kombination oder vergebene...Das Repository-Pattern und der O/R-Mapper: Geniale Kombination oder vergebene...
Das Repository-Pattern und der O/R-Mapper: Geniale Kombination oder vergebene...
 
Fanstatic pycon.de 2012
Fanstatic pycon.de 2012Fanstatic pycon.de 2012
Fanstatic pycon.de 2012
 
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
 
Shibboleth Single-Sign-On mit TYPO3
Shibboleth Single-Sign-On mit TYPO3Shibboleth Single-Sign-On mit TYPO3
Shibboleth Single-Sign-On mit TYPO3
 
Cloud Deployment und (Auto)Scaling am Beispiel von Angrybird
Cloud Deployment und (Auto)Scaling am Beispiel von AngrybirdCloud Deployment und (Auto)Scaling am Beispiel von Angrybird
Cloud Deployment und (Auto)Scaling am Beispiel von Angrybird
 
Big-Data-Analyse und NoSQL-Datenbanken
Big-Data-Analyse und NoSQL-DatenbankenBig-Data-Analyse und NoSQL-Datenbanken
Big-Data-Analyse und NoSQL-Datenbanken
 
Cloud Native und Java EE: Freund oder Feind?
Cloud Native und Java EE: Freund oder Feind?Cloud Native und Java EE: Freund oder Feind?
Cloud Native und Java EE: Freund oder Feind?
 
Cloud Native & Java EE: Freund oder Feind?
Cloud Native & Java EE: Freund oder Feind?Cloud Native & Java EE: Freund oder Feind?
Cloud Native & Java EE: Freund oder Feind?
 
Doctrine 2 - An Introduction (German)
Doctrine 2 - An Introduction (German)Doctrine 2 - An Introduction (German)
Doctrine 2 - An Introduction (German)
 
Startimpuls at Microsoft w/ IFJ
Startimpuls at Microsoft w/ IFJStartimpuls at Microsoft w/ IFJ
Startimpuls at Microsoft w/ IFJ
 

Plus de Michael Plöd

Event Sourcing: Introduction & Challenges
Event Sourcing: Introduction & ChallengesEvent Sourcing: Introduction & Challenges
Event Sourcing: Introduction & ChallengesMichael Plöd
 
Event Sourcing für reaktive Anwendungen
Event Sourcing für reaktive AnwendungenEvent Sourcing für reaktive Anwendungen
Event Sourcing für reaktive AnwendungenMichael Plöd
 
CQRS basierte Architekturen mit Microservices
CQRS basierte Architekturen mit MicroservicesCQRS basierte Architekturen mit Microservices
CQRS basierte Architekturen mit MicroservicesMichael Plöd
 
Spring One 2 GX 2014 - CACHING WITH SPRING: ADVANCED TOPICS AND BEST PRACTICES
Spring One 2 GX 2014 - CACHING WITH SPRING: ADVANCED TOPICS AND BEST PRACTICESSpring One 2 GX 2014 - CACHING WITH SPRING: ADVANCED TOPICS AND BEST PRACTICES
Spring One 2 GX 2014 - CACHING WITH SPRING: ADVANCED TOPICS AND BEST PRACTICESMichael Plöd
 
Caching - Hintergründe, Patterns und Best Practices
Caching - Hintergründe, Patterns und Best PracticesCaching - Hintergründe, Patterns und Best Practices
Caching - Hintergründe, Patterns und Best PracticesMichael Plöd
 
Warum empfehle ich meinen Kunden das Spring Framework?
Warum empfehle ich meinen Kunden das Spring Framework? Warum empfehle ich meinen Kunden das Spring Framework?
Warum empfehle ich meinen Kunden das Spring Framework? Michael Plöd
 
Bessere Präsentationen
Bessere PräsentationenBessere Präsentationen
Bessere PräsentationenMichael Plöd
 
Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Michael Plöd
 

Plus de Michael Plöd (8)

Event Sourcing: Introduction & Challenges
Event Sourcing: Introduction & ChallengesEvent Sourcing: Introduction & Challenges
Event Sourcing: Introduction & Challenges
 
Event Sourcing für reaktive Anwendungen
Event Sourcing für reaktive AnwendungenEvent Sourcing für reaktive Anwendungen
Event Sourcing für reaktive Anwendungen
 
CQRS basierte Architekturen mit Microservices
CQRS basierte Architekturen mit MicroservicesCQRS basierte Architekturen mit Microservices
CQRS basierte Architekturen mit Microservices
 
Spring One 2 GX 2014 - CACHING WITH SPRING: ADVANCED TOPICS AND BEST PRACTICES
Spring One 2 GX 2014 - CACHING WITH SPRING: ADVANCED TOPICS AND BEST PRACTICESSpring One 2 GX 2014 - CACHING WITH SPRING: ADVANCED TOPICS AND BEST PRACTICES
Spring One 2 GX 2014 - CACHING WITH SPRING: ADVANCED TOPICS AND BEST PRACTICES
 
Caching - Hintergründe, Patterns und Best Practices
Caching - Hintergründe, Patterns und Best PracticesCaching - Hintergründe, Patterns und Best Practices
Caching - Hintergründe, Patterns und Best Practices
 
Warum empfehle ich meinen Kunden das Spring Framework?
Warum empfehle ich meinen Kunden das Spring Framework? Warum empfehle ich meinen Kunden das Spring Framework?
Warum empfehle ich meinen Kunden das Spring Framework?
 
Bessere Präsentationen
Bessere PräsentationenBessere Präsentationen
Bessere Präsentationen
 
Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6
 

Hibernate Tuning

  • 3. Tuning von Hibernate und JPA Anwendungen Michael Plöd
  • 4. Michael Plöd • Architekt bei Senacor Technologies AG in Nürnberg • http://www.senacor.com • michael.ploed@senacor.com • http://rockingcode.blogspot.com • Twitter: @bitboss
  • 6. Zu Zu viele langsame Abfragen Abfragen Gründe für schlechte Performance Falsch Falsch getunte getunte Daten- Infra- bank struktur
  • 7. Klassifizierung von Anzahl der 1.500 Abfragen Abfragen 1.125 750 375 0 0 225 450 675 900 Durchschnittliche Laufzeit in [ms]
  • 8. Ursachen Hohe Häufigkeit Hohe Laufzeit ! Applikations-Logik ! Zu hohe Selektivität ! Mappings ! Variablen-Übergabe ! Kein Caching ! Fehlende Indizes ! N+1 Selects Problem ! Karthesisches Produkt ! Locks ! Datenbankstruktur
  • 9. N+1 Selects Problem List list = s.createCriteria(Konto.class).list(); for (Iterator it = list.iterator(); it.hasNext();) { Konto kto = (Konto) it.next(); kto.getKunde().getName(); } SELECT * FROM KONTEN SELECT * FROM PERSONEN WHERE PERSON_ID = ? SELECT * FROM PERSONEN WHERE PERSON_ID = ? SELECT * FROM PERSONEN WHERE PERSON_ID = ? ...
  • 10. Karthesisches Produkt @Entity public class Konto { ... @OneToMany(fetch=FetchType.EAGER) public Set<Buchung> getBuchungen() {...} @OneToMany(fetch=FetchType.EAGER) public Set<Vollmacht> getVollmachten() {...} ... } select konto.*, buchung.*, vollmacht.* from KONTEN konto left outer join BUCHUNGEN buchung on konto.ID = buchung.KTO_ID left outer join VOLLMACHTEN vollmacht on konto.ID = vollmacht.KTO_ID
  • 11. Karthesisches Produkt select konto.*, buchung.*, vollmacht.* from KONTEN konto left outer join BUCHUNGEN buchung on konto.KTO_ID = buchung.KTO_ID left outer join VOLLMACHTEN vollmacht on konto.KTO_ID = vollmacht.KTO_ID KTO_ID KTO_NR ... BUCH_ID BUCH_BETRAG ... VM_ID VM_NAME ... 1 12344 ... 10 1000,00 ! ... 200 Michael Plöd ... 1 12344 ... 10 1000,00 ! ... 300 Martin Plöd ... 1 12344 ... 20 -324,23 ! ... 200 Michael Plöd ... 1 12344 ... 20 -324,23 ! ... 300 Martin Plöd ... 1 12344 ... 30 543,11 ! ... 200 Michael Plöd ... 1 12344 ... 30 543,11 ! ... 300 Martin Plöd ... 2 21300 ... 40 -4323,23 ! ... 400 Sandra Ulrich ... 2 21300 ... 40 -4323,23 ! ... 400 Melanie Ulrich ... 2 21300 ... 40 -4323,23 ! ... 400 Herbert Ulrich ... ... ... ... ... ... ... ... ... ...
  • 13. FETCHING CACHING ABFRAGEN ! Batch ! 1st Level Cache ! Selektivität ! Subselect ! 2nd Level Cache ! Query Cache ! Eager ! Stateless Session ! Bind Variablen LOGIK LOCKS Runtime ! Schleifen ! Optimistic ! DB Entwurf Locking ! Datenmenge ! Konfiguration ! Connection Pool
  • 15. Batch Fetching @Entity public class Konto { SELECT k.* FROM KONTEN k @ManyToOne(...) public Person getKunde() SELECT * FROM PERSONEN {...} WHERE PERSON_ID IN (?, ?, ?, ?, ?) ... } SELECT * FROM PERSONEN WHERE PERSON_ID IN (?, ?, ?, ?, ?) @Entity @BatchSize(size=5) SELECT * FROM PERSONEN public class Person { WHERE PERSON_ID IN (?, ?, ?) ... }
  • 16. Batch Fetching 1.500 ! Schätzung 1.125 ! Einfach 750 375 ! Lazy 0 0 225 450 675 900 ! (N / Batch Size) + 1
  • 17. Subselect Fetching @Entity public class Konto { SELECT k.* FROM KONTEN k @OneToMany @Fetch(FetchMode.SUBSELECT) SELECT b.* FROM BUCHUNGEN b WHERE b.KTO_ID IN ( public Set getBuchungen() SELECT k.KTO_ID FROM KONTEN k {...} ) ... }
  • 18. Subselect Fetching 1.500 ! Nur für Collections 1.125 ! Keine Schätzung 750 ! Einfach 375 ! Lazy 0 0 225 450 675 900 ! 2 Abfragen
  • 19. Eager Fetching @Entity public class Konto { @OneToMany( fetch = FetchType.EAGER ) SELECT ko.*, b.*, ku.* public Set getBuchungen() FROM KONTEN ko {...} LEFT OUTER JOIN BUCHUNGEN b on b.KTO_ID = ko.KTO_ID LEFT OUTER JOIN KUNDEN ku @ManyToOne( on ko.KU_ID = ku.KU_ID fetch = FetchType.EAGER ) public Kunde getEigentuemer() {...} }
  • 20. Eager Fetching 1.500 ! Nie bei 2+ Collections! 1.125 ! Nicht Lazy 750 ! 1 Abfrage 375 0 ! Nie in globalen Fetch 0 225 450 675 900 Plan aufnehmen
  • 22. Caching Architektur First Level Cache Persistenz Kontext A Persistenz Kontext B Persistenz Kontext C Second Level Cache Cache Concurrency Strategy Query Cache Cache Implementierung Klassen Cache Collection Cache Query Cache Region Region Region Update Timestamps Cache Region
  • 23. Infrastruktur 1st Level Cache only Virtual Machine 1 SessionFactory Session Session Session Session Session Session
  • 24. Infrastruktur Lokale 2nd Level Caches Virtual Machine 1 SessionFactory Session Session Session Session Session Session Second Level Cache
  • 25. Infrastruktur Lokale 2nd Level Caches Virtual Machine 1 Virtual Machine 2 SessionFactory SessionFactory Session Session Session Session Session Session Session Session Session Session Session Session Second Level Cache Second Level Cache
  • 26. Infrastruktur Verteilter Second Level Cache Virtual Machine 1 Virtual Machine 2 SessionFactory SessionFactory Session Session Session Session Session Session Session Session Session Session Session Session Second Level Cache Second Level Cache Netzwerk
  • 28. ! Hibernate verwaltet den 1st Level Cache nicht von selbst!
  • 29. Grundregeln ! ORM ist kein Batch Tool! ! Bei Massen-Verarbeitung regelmässig flushen und clearen! ! JDBC Batch-Size anpassen for ( int i=0; i<100000; i++ ) { Konto konto = new Konto(...); session.save(konto); if ( i % 50 == 0 ) { session.flush(); session.clear(); } }
  • 30. Concurrency Strategies Isolation bis zu Transactional repeatable read Isolation bis zu Read-Write read commited Keine Konsistenz Garantie, aber Nonstrict-read-write Timeouts Read-only Nur für Daten, die sich nie ändern
  • 31. Cache Provider Nonstrict Transactional Read-write Read-only Read-write EHCache x x x OSCache x x x SwarmCache x x JBoss Cache x x
  • 32. Konfiguration org.hibernate.cache.provider_class EHCache org.hibernate.cache.EhCacheProvider OSCache org.hibernate.cache.OsCacheProvider SwarmCache org.hibernate.cache.SwarmCacheProvider JBoss Cache org.hibernate.cache.TreeCacheProvider
  • 33. Mappings ! Annotation: @Cache(usage=CacheConcurrencyStrategy.READ_WRITE) ! XML: <cache usage=“read-write“> ! Sowohl auf Klassen als auch auf Collection Level ! Volles Caching: Klasse + Collection!
  • 34. Beispiel @Entity @Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) public class Author implements Serializable { ... @Override public int hashCode() { ... } @Override public boolean equals(Object obj) { ... } } @Entity @Cache(usage=CacheConcurrencyStrategy.READ_WRITE) public class RecordReview implements Article { ... @OneToMany(fetch=FetchType.LAZY) @Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) private Set<Author> authors = new HashSet<Author>(); ... }
  • 35. Cache Regions ! Einteilung in Cache Regions mit Naming Convention ! Cache Regions werden in Cache Provider Konfiguration referenziert Klasse Voll qualifizierter Name de.allschools.domain.Band de.allschools.domain.Band Collection Klasse + „.“ + Attribut de.allschools.domain.Record#bands de.allschools.domain.Record.bands
  • 36. EhCache Beispiel ehchache.xml <ehcache> <diskStore path="java.io.tmp"/> <defaultCache maxElementsInMemory="10000" eternal="true" overflowToDisk="true" /> <cache name="de.allschools.domain.Author" maxElementsInMemory="30" eternal="false" timeToIdleSeconds="900" timeToLiveSeconds="1800" overflowToDisk="true" /> <cache name="de.allschools.domain.RecordReview.authors" maxElementsInMemory="500" eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="1200" overflowToDisk="true" /> ... </ehcache>
  • 37. Auswahl von Caching Kandidaten? KONSERVATIV ! Wenige Inserts und Updates ! Viele Lesezugriffe ! Unkritische Daten ! Von vielen Sessions benötigt ! Von vielen Usern benötigt
  • 38. Stateless Session ! sessionFactory.openStatelessSession() ! Command orientierte API ! Kein Persistenz Kontext ! Kein Caching ! Kein Transaktionales write-behind ! Kein Cascading ! Keine Interceptors und Events
  • 40. Selektivität ! Nur benötige Daten laden ! Möglichst früh einschränken ! Projection verwenden Query query = getSession().createQuery( "select new TourCityInfo(t.name, d.timestamp, l) from Tour t inner join t.tourDates d with d.timestamp > :datum inner join d.location l where l.stadt=:stadt order by t.name asc" );
  • 41. "from User u where u.name=" + name " SQL Injection " Performance Killer " Heimtückisch
  • 42. IMMER ! Query query = BIND VARIABLEN verwenden session.createQuery("from User u where u.name= :name"); q.setString("name", "michael");
  • 43. Query Cache ! Wird selten benötigt ! Nur für bestimmte Queries geeignet ! Wird extra konfiguriert: hibernate.cache.use_query_cache=true ! Muss pro Query / Criteria aktiviert werden: query.setCacheable(true);
  • 45. Logging ! Sehr detailliert, viele Informationen ! Interessant sind für Tuning: # org.hibernate.jdbc - TRACE # org.hibernate.SQL - TRACE ! Logging auch in User Types integrieren ! Sicht auf plain SQL
  • 46. Statistics ! Müssen extra aktiviert werden ! Zugriff programmatisch oder JMX
  • 47. Datenbank + Infrastruktur ! Auch in der Datenbank analysieren # Sind alle Indizes korrekt gesetzt? # Wie ist das Laufzeitverhalten? ! Gleiches gilt für Infrastruktur # Connection Pool # Transaktions Monitor # Applikations Server
  • 48. Laufen Messdaten lassen erheben Analyse pro Anwendungs- fall Nur eine Vergleich Tuning mit Referenz Massnahme und Doku
  • 49. Lasttest ! Arten # Normale Last # Stresstest # Lange Lauzeiten ! Setup: # Realistisches Hardware Sizing # Realistische Datenmenge