diff --git a/.vscode/settings.json b/.vscode/settings.json index 22e74fe..8ed7972 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,7 @@ "Denormalisierung", "editionswissenschaftlich", "EFFW", + "Ehcache", "Entitätsklassen", "Fouine", "freigeschalten", @@ -72,6 +73,7 @@ "documentfacsimile", "documentid", "downto", + "ehcache", "enddatestatus", "endday", "endmonth", diff --git a/chapters/thesis/appendix05_Provider.java b/chapters/thesis/appendix05_Provider.java index 13ad855..158d2b8 100644 --- a/chapters/thesis/appendix05_Provider.java +++ b/chapters/thesis/appendix05_Provider.java @@ -1,6 +1,7 @@ public interface PerfStatistics { String getOpenJPAStatistics(); String getEntityClasses(); + String getEhCacheManager(); } @Stateless @@ -38,4 +39,26 @@ public class PerfStatisticsImpl implements PerfStatistics { res.append("\" }"); return res.toString(); } + + @Override + public String getEhCacheManager() { + List tmpMgr = CacheManager.ALL_CACHE_MANAGERS; + StringBuilder res = new StringBuilder("{ \"count:\": "); + res.append(tmpMgr.size()); + res.append(", \"CacheManagers\": ["); + for(CacheManager cm : tmpMgr) { + res.append(String.format("{ \"name\": \"%s\", \"caches\": [", cm.getName())); + String[] cacheNames = cm.getCacheNames(); + for (String cacheName : cacheNames) { + net.sf.ehcache.Cache ec = cm.getCache(cacheName); + Statistics stat = ec.getStatistics(); + res.append(String.format("{ \"name\": \"%s\", \"status\": \"%s\", \"CacheHits\": %d, \"CacheMisses\": %d, \"ObjectCount\": %d, \"AvgGetTime\": %f, \"AvgSearchTime\": %d }, " + , cacheName, ec.getStatus(), stat.getCacheHits(), stat.getCacheMisses(), stat.getObjectCount() + , stat.getAverageGetTime(), stat.getAverageSearchTime())); + } + res.append("\"\"] }, "); + } + res.append("{}] }"); + return res.toString(); + } } diff --git a/chapters/thesis/appendix05_servlet.java b/chapters/thesis/appendix05_servlet.java index 25baf85..e8f26f0 100644 --- a/chapters/thesis/appendix05_servlet.java +++ b/chapters/thesis/appendix05_servlet.java @@ -12,6 +12,7 @@ public class PerfStatServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String openJPAStatistics = perfStatistics.getOpenJPAStatistics(); String entityClasses = perfStatistics.getEntityClasses(); + String ehCache = perfStatistics.getEhCacheManager(); resp.setStatus(HttpServletResponse.SC_OK); resp.setContentType(MediaType.APPLICATION_JSON); @@ -20,6 +21,8 @@ public class PerfStatServlet extends HttpServlet { out.print(openJPAStatistics); out.print(", \"entityClasses\": "); out.print(entityClasses); + out.print(", \"ehCache\": "); + out.print(ehCache); out.print(" }"); } } diff --git a/chapters/thesis/chapter01.tex b/chapters/thesis/chapter01.tex index e482482..f99d788 100644 --- a/chapters/thesis/chapter01.tex +++ b/chapters/thesis/chapter01.tex @@ -69,31 +69,30 @@ Hierbei ist auch ein Vergleich mit anderen Techniken angedacht. \section{Gliederung} \label{sec:intro:structure} -Zu Beginn der Arbeit werden im Kapitel \ref{ch:basics} die Struktur und der grundsätzliche Aufbau der Anwendung +Zu Beginn der Arbeit werden im \autoref{ch:basics} die Struktur und der grundsätzliche Aufbau der Anwendung erklärt. Hierbei wird aufgezeigt an welchen Stellen es immer wieder zu Unstimmigkeiten kommen kann und wie diese zu überprüfen sind. -Nachfolgend werden im Kapitel \ref{ch:concept} die Konzepte vorgestellt, die die Stellen ermitteln, die eine schlechte +Nachfolgend werden im \autoref{ch:concept} die Konzepte vorgestellt, die die Stellen ermitteln, die eine schlechte Performance aufweisen und optimiert werden sollen. Hierzu gehören zum einen die Einstellungen der verwendeten Software, und zum anderen der Aufbau und die verwendeten Techniken in der Anwendung. Diese Techniken werden im weiteren Verlauf nochmal überprüft, ob eine alternative Lösung einen performantere Umsetzung bringen kann. -Bei den Performance"=Untersuchung in Kapitel \ref{ch:performance-checking} werden nun die Konzepte angewandt, um +Bei den Performance"=Untersuchung in \autoref{ch:performance-checking} werden nun die Konzepte angewandt, um die Umgebung selbst zu untersuchen und die dort bekannten Probleme zu ermitteln. Diese werden direkt bewertet, unter den -Gesichtspunkten, ob eine Optimierung an dieser Stelle sinnvoll ist, oder ob der Arbeitsaufwand dafür zu enorm ist. -\mytodos{das enorm sollte man umschreiben} +Gesichtspunkten, ob eine Optimierung an dieser Stelle sinnvoll ist, oder ob der Arbeitsaufwand dafür zu aufwendig ist. Zusätzlich werden noch die Vorbereitungen und die angepassten Konfigurationen für die nachfolgenden Performance"=Untersuchung der Anwendung aufzeigt. -Zuerst wird im Kapitel \ref{ch:performance-investigation-application} die Ausgangsmessung durchgeführt, hierbei werden +Zuerst wird im \autoref{ch:performance-investigation-application} die Ausgangsmessung durchgeführt, hierbei werden alle bekannten Caches deaktiviert und eine Messung durchgeführt. Dann werden Schicht für Schicht die Optimierungsmöglichkeiten aufgezeigt, umgesetzt und erneut gemessen. Diese Messung wird dann in Abhängigkeit zur Ausgangsmessung die Optimierung bewertet. -\mytodos{Kapitel 6 ist noch zu überlegen, ob das mit 7 nicht zusammengefasst werden könnte} -Nach der Optimierung kommt nun die Evaluierung im Kapitel \ref{ch:evaluation}, um zu überprüfen ob die Anpassungen -die gewünschten Verbesserung in der Performance gebracht haben. +Nach der Optimierung kommt nun die Evaluierung im \autoref{ch:evaluation}. Hier werden die verschiedenen Optimierungen +begutachtet, in welchem Anwendungsfall die gewünschte Verbesserung in der Performance umgesetzt werden kann und welche +für den vorliegenden Fall in der Praxis umsetzbar ist. Zum Abschluss im Kapitel \ref{ch:summary_and_outlook} wird explizit die Anpassungen dargestellt, die zu einer merklichen Verbesserung geführt haben und wie diese entsprechend umgesetzt werden müssen. Zusätzliche wird diff --git a/chapters/thesis/chapter03.tex b/chapters/thesis/chapter03.tex index 12c1034..7ad30d1 100644 --- a/chapters/thesis/chapter03.tex +++ b/chapters/thesis/chapter03.tex @@ -87,7 +87,6 @@ Wie im Kapitel \ref{ch:basics} dargestellt, besteht die eigentliche Anwendung au PostgreSQL"=Schicht wurde schon im vorherigen Kapitel betrachtet. Daher gehen wir nun weiter nach oben in den Schichten vom Glassfish"=Server. -\mytodos{Statistik-Webseite hier entfernen, wird aktuell nicht angewendet} Die OpenJPA Cache Schicht wird nun einzeln untersucht. Hierfür werden die zuerst die Cache"=Statistik für Object"=Cache und Query"=Cache aktiviert \citep[315]{MüllerWehr2012}. Die somit erfassten Werte, werden über eine Webseite bereitgestellt, um die Daten Live vom Server verfolgen zu können. Zusätzlich werden die Webseite über ein Script @@ -110,8 +109,6 @@ for(EntityType entityType : em.getMetaModel().getEntities()) emf.getCache().print(); \end{lstlisting} -% \mytodos{\url{https://eclipse.dev/eclipselink/api/2.1/org/eclipse/persistence/jpa/JpaCache.html#getObject(java.lang.Class,%20java.lang.Object)}} - Die Schicht \ac{EJB} besitzt keine Möglichkeit um eine sinnvolle Messung durchzuführen, daher wird hierfür keine direkte Messungen eingefügt. Hier werden nur die externen Statistiken durch das Skript verwendet, um zu prüfen in welchen Umfang die Umstellungen eine Veränderung im Verhalten der Webseite bewirken. diff --git a/chapters/thesis/chapter05.tex b/chapters/thesis/chapter05.tex index 94d9f6b..abf3813 100644 --- a/chapters/thesis/chapter05.tex +++ b/chapters/thesis/chapter05.tex @@ -255,49 +255,45 @@ mit \ac{JPQL} oder mit der Criteria API abfragt. \mytodos{Queryzeiten fehlen nocht} -\section{Caching im JPA} -\label{sec:performance-investigation-application:caching-jpa} +\section{Caching mit Ehcache} +\label{sec:performance-investigation-application:caching-ehcache} -%hier ein test vom acf: \acf{JPA}. aber ich seh ihn nicht +Der Ehcache ist ein L2"=Cache den man direkt in OpenJPA mit integrieren kann. Hierfür sind einige Punkte zu beachten. +Zum einen muss die Reference auf das \textit{ehcache} und das \textit{ehcache"=openjpa} Packet hinzugefügt werden. +Zusätzlich dazu sind die Konfiguration \textit{openjpa.""QueryCache} und \textit{openjpa.""DataCache} auf +\textit{ehcache} anzupassen. Die Objekte oder mindestens das Hauptobjekt benötigt noch die Annotation +\textbf{@DataCache(name = "userCache")}, damit der Cache für die Klassen aktiviert wird. Als letztes muss noch der +Cache"=Manager aktiviert werden, dieser kann entweder durch Code programmiert werden oder über eine Konfiguration +in der \textit{ehcache.xml}. -\mytodos{muss noch umgebaut werden, falsche Konfiguration erwischt} +Anhand der Auswertung von \ref{tbl:measure-ehcache-active} fällt auf, dass der Cache keine Geschwindigkeitsvorteile +bringt. Zusätzlich werden trotz aktiven Cache die Anzahl der Anfragen an die Datenbank nicht reduziert. Gleichzeitig +sieht man aber anhand der Statistik"=Ausgaben, dass der Ehcache verwendet wird und entsprechende Hits hat und der +OpenJPA"=Cache nicht mehr verwendet wird. Zusätzlich steigt der Speicherverbrauch stärker als in anderen Fällen. -%Die Cache-Einstellungen von \ac{JPA} werden über mehrere Einstellungen konfiguriert. Anhand von -%\texttt{eclipselink.query-results-cache} wird definiert, dass die Ergebnisse von benannten Abfragen im Cache -%gespeichert werden. Für den Zugriff in den Cache, wird neben den Namen noch die übergebenen Parameter -%berücksichtigt. -%% https://eclipse.dev/eclipselink/documentation/2.5/concepts/cache008.htm +% document, documentaddresseeperson, first/last, documentcoauthorperson, count und documentfacsimile +\begin{table}[h!] + \centering + \resizebox{\textwidth}{!}{ + \begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|} + \hline + & \multicolumn{3}{c|}{Aufrufzeit (ms)} & \multicolumn{2}{c|}{Queries (ms)} & \multicolumn{3}{c|}{Memory (MB)} & \multicolumn{3}{c|}{Render (ms)} & \multicolumn{3}{c|}{DB-load (ms)} \\ + \hline + \# & min & avg & max & \#"=avg & avg & start & stop & diff & min & avg & max & min & avg & max \\ + \hline + %- & 151 & 368 & 1904 & 141.2 & 20.8 & 906.3 & 936.8 & 30.5 & 164 & 404 & 2232 & 39 & 124 & 847 \\ % 1412 - 208 ms (133+ 40+ 23+9+2+1) (#2,4-6,10,12) + 1 & 450 & 934 & 3026 & 1095.2 & xxxx & 977.1 & 1027.0 & 49.9 & 592 & 978 & 3015 & 464 & 656 & 1348 \\ % 10952 - ... ms ( .+ .+ .+.+.+.) (#.) + 2 & 503 & 563 & 666 & 1206.0 & xxxx & 1028.0 & 1126.0 & 98.0 & 494 & 554 & 555 & 395 & 448 & 453 \\ % 23012 - + 3 & 431 & 522 & 586 & 1206.0 & xxxx & 1137.0 & 1370.0 & 233.0 & 422 & 513 & 575 & 341 & 430 & 494 \\ % 35072 - + 4 & 421 & 497 & 635 & 1206.0 & xxxx & 1371.0 & 1469.0 & 98.0 & 414 & 490 & 627 & 337 & 414 & 551 \\ % 47132 - + 5 & 444 & 511 & 600 & 1206.0 & xxxx & 1469.0 & 1662.0 & 193.0 & 436 & 503 & 589 & 362 & 420 & 505 \\ % 59192 - + \hline + \end{tabular} + } + \caption{Messung mit aktiviertem Ehcache} + \label{tbl:measure-ehcache-active} +\end{table} -%Der geteilte Cache, der für die Dauer der persistenten Einheit (EntityManagerFactory oder der Server) vorhanden ist, -%kann über \texttt{eclipselink.cache.shared.default} gesteuert werden. Dieser kann nur aktiviert oder deaktiviert werden. -%% https://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching - -%Mit \texttt{eclipselink.cache.size.default} wird die initiale Größe des Caches definiert, hierbei ist der Standardwert -%100. Die Objekt werden nicht direkt aus dem Cache entfernt, sondern erst nachdem der \ac{GC} diese freigeben hat. -%Zusätzlich wird über \texttt{eclipselink.cache.type.default} die Art des Caching gesteuert. Die Einstellung mit dem -%höchsten Speicherbedarf ist \textit{FULL}, bei dem alle Objekte im Cache bleiben, außer sie werden explizit gelöscht. -%Die Einstellung \textit{SOFT} und \textit{WEAK} sind sehr ähnlich, der unterschied ist die Referenzierung auf die -%Entität. Bei \textit{WEAK} bleiben die Objekte nur solange erhalten, wie die Anwendung selbst eine Referenz auf die -%Objekte fest hält. Im Gegensatz dazu bleibt bei \textit{SOFT} die Referenz so lange bestehen, bis der \ac{GC} wegen -%zu wenig Speicher Objekte aus dem Cache entfernt. -%% https://eclipse.dev/eclipselink/documentation/2.5/concepts/cache002.htm - -%Um den Cache zu deaktivieren wurden beiden Einstellungen auf \textit{false} gestellt, die Größe auf 0 und der Cache-Typ -%auf \textit{NONE}. Hierbei lag die maximale gemessene Laufzeit des ersten Aufrufs bei circa 1300 ms und es wurden 12219 -%Abfragen an die Datenbank gestellt. Bei den nachfolgenden Aufrufe lag die Aufrufzeit im Durchschnitt bei 350 ms und -%12080 Abfragen. - -%Um den Cache wieder zu aktivieren wurden die Einstellungen auf \textit{true} gestellt, die Größe auf den Standardwert -%von 100 und der Cache-Type auf \textit{SOFT} gestellt. Hierbei wurde eine maximale Laufzeit beim ersten Aufruf ebenfalls -%von 1300 ms gemessen und es wurden 12218 Abfragen abgesetzt. Bei den nachfolgenden Aufrufen lag die Aufrufzeit im -%Durchschnitt bei 340 ms. - -%Bei WEAK hat sich die Speichernutzung nur um 5MB gesteigert - -%\mytodos{in einer Tabelle oder Graphen darstellen?} - -%Wie man an den Daten erkennen kann, wird der Cache vom \ac{JPA} für diese Abfrage nicht verwendet, sonst müssten die -%Anzahl der Abfragen an die Datenbank drastisch reduziert werden. Selbst die Laufzeit ändert sich nur marginal. \section{Caching in EJB} \label{sec:performance-investigation-application:caching-ejb} diff --git a/chapters/thesis/chapter06.tex b/chapters/thesis/chapter06.tex index dc78698..2349f63 100644 --- a/chapters/thesis/chapter06.tex +++ b/chapters/thesis/chapter06.tex @@ -91,9 +91,10 @@ werden. Dies ist der Grund warum diese Anfragen in diesem Cache nicht gespeicher Dadurch ist dieser Cache für eine Performance"=Verbesserung in unseren Fall nicht verwendbar. -\subsection{Caching in JPA} - \subsection{Caching in EJB} +\label{sec:evaluation:result-optimization:ejb} + +\mytodos{fehlt noch} \subsection{Abfragen mit JPQL und Criteria API} \label{sec:evaluation:result-optimization:jpal-capi} diff --git a/thesis.pdf b/thesis.pdf index 6b51e1e..5a5b274 100644 Binary files a/thesis.pdf and b/thesis.pdf differ