Beacher CheckIn

This commit is contained in:
marcodn 2024-10-22 19:32:23 +02:00
parent cd6ac0a1d8
commit df7042b4b7
2 changed files with 585 additions and 140 deletions

Binary file not shown.

View file

@ -6,17 +6,41 @@
\input{marco-galster-config} \input{marco-galster-config}
\addbibresource{expose-ref.bib} \addbibresource{expose-ref.bib}
%\usepackage{fourier}
\usepackage{array}
\usepackage{makecell}
\renewcommand\theadalign{bc}
\renewcommand\theadfont{\bfseries}
\renewcommand\theadgape{\Gape[4pt]}
\renewcommand\cellgape{\Gape[4pt]}
% ACHTUNG: Damit sich die Datei sauber im Visual Studio Code übersetzten lässt, muss in den Benutzer-Einstellungen % ACHTUNG: Damit sich die Datei sauber im Visual Studio Code übersetzten lässt, muss in den Benutzer-Einstellungen
% das Element "latex-workshop.latex.tools" aufgenommen werden und der erscheinende Eintrag für latexmk bei den % das Element "latex-workshop.latex.tools" aufgenommen werden und der erscheinende Eintrag für latexmk bei den
% args am Anfang um den folgenden Eintrage erweitert werden: % args am Anfang um den folgenden Eintrage erweitert werden:
% "-shell-escape" % "-shell-escape"
% TODO
\title{\myTitle} \title{\myTitle}
%\subtitle{} %\subtitle{}
\author[M. Galster]{\myName} \author[M. Galster]{\myName}
\footlinetext{\insertshortauthor \hspace{4em} Multi-Layer Optimization Strategies for Enhanced Performance in Digital Editions} \footlinetext{\insertshortauthor \hspace{4em} Multi"=Layer Optimization Strategies for Enhanced Performance in Digital Editions}
\institute{Universität~in~Hagen,~Deutschland} \institute{Universität~in~Hagen,~Deutschland}
\date{\myTime} \date{07. November 2024}
\tikzset{
every axis/.style={
%%width=\textwidth,height=\textheight,
xlabel={Aufruf},
ylabel={Laufzeit [ms]},
enlargelimits=0.05,
ymin=0, %ymax=2100,
xtick={0,1,2,3,4,5}, %Ticks explizit angeben, dass bei grpßerer Darstellung nicht Zwischenticks existieren
legend pos=north east,
ymajorgrids=true,
grid style=dashed,
},
}
\begin{document} \begin{document}
\selectlanguage{ngerman} \selectlanguage{ngerman}
@ -26,13 +50,15 @@
% und dort markieren, was genau verändert wurde % und dort markieren, was genau verändert wurde
% -- SLIDE -- Title % -- SLIDE -- Title
% 1. Titelfolie
\begin{frame}[plain] \begin{frame}[plain]
\titlepage \titlepage
\end{frame} \end{frame}
% -- SLIDE -- TOC % -- SLIDE -- TOC
% 2. Agenda
\begin{frame}[c] \begin{frame}[c]
\frametitle{Übersicht} \frametitle{Agenda}
%left space %left space
\begin{addmargin*}{2.5em} \begin{addmargin*}{2.5em}
@ -50,7 +76,8 @@
\def\showHorizontalNavBar{True} \def\showHorizontalNavBar{True}
% -- SLIDES -- % -- SLIDES --
\section{Übersicht} % 3. Einleitung (Warum ist das Thema relevant, Ziel der Arbeit, Ergebnis mit dem nicht gerechnet hat)
\section{Einleitung}
\begin{frame}[c] \begin{frame}[c]
\frametitle{Problemstellung} \frametitle{Problemstellung}
\begin{columns} \begin{columns}
@ -67,6 +94,7 @@
\end{columns} \end{columns}
\end{frame} \end{frame}
% 4. Forschungsgegenstand (Thema einführen durch Vorstellung Forschungsgegenstand)
\begin{frame}[c] \begin{frame}[c]
\frametitle{Ablauf einer Web-Anfrage} \frametitle{Ablauf einer Web-Anfrage}
\begin{figure}[centered] \begin{figure}[centered]
@ -84,7 +112,7 @@
\node (JPA) [block,below of=EJB] {Java Persistance API}; \node (JPA) [block,below of=EJB] {Java Persistance API};
\node (openJPA) [block, below of=JPA] {OpenJPA Cache}; \node (openJPA) [block, below of=JPA] {OpenJPA Cache};
\node (fitGlassfish) [rounded corners,fit=(JSF) (EJB) (JPA) (openJPA)] {}; \node (fitGlassfish) [rounded corners,fit=(JSF) (EJB) (JPA) (openJPA)] {};
\node [left] at (fitGlassfish.west) [text width=1.5cm] {Glassfish/ Payara}; \node [left] at (fitGlassfish.west) [text width=1.5cm] {GlassFish/ Payara};
\node (memoryBuffers) [block, below of=openJPA] {Memory Buffers}; \node (memoryBuffers) [block, below of=openJPA] {Memory Buffers};
\node (services) [block, right of=memoryBuffers, xshift=2cm] {Services}; \node (services) [block, right of=memoryBuffers, xshift=2cm] {Services};
@ -107,114 +135,352 @@
\end{figure} \end{figure}
\end{frame} \end{frame}
\section{Untersuchungen} \begin{frame}[c]
\frametitle{Anpassungen}
\begin{columns}
\column{0.5\textwidth}
\onslide<1>{
\begin{itemize}
\item Caching EJB
\end{itemize}
}
\onslide<2>{
\begin{itemize}
\item Abfragen in JPQL
\item Abfragen in Criteria API
\end{itemize}
}
\onslide<3>{
\begin{itemize}
\item Caching in OpenJPA
\item Cached Queries
\item Caching mit Ehcache
\end{itemize}
}
\onslide<4>{
\begin{itemize}
\item Materialized Views
\item Optimierung der Abfrage
\end{itemize}
}
\column{0.5\textwidth}
\begin{figure}[centered]
\begin{tikzpicture}[scale=.55,transform shape,node distance=4em,
block/.style={rectangle, rounded corners,minimum width=3cm,minimum height=.5cm,text centered, draw=black,fill=green!30},
selected/.style={rectangle, rounded corners,minimum width=3cm,minimum height=.5cm,text centered, draw=black,fill=blue!30},
halfselected/.style={rectangle, rounded corners,minimum width=3cm,minimum height=.5cm,text centered, draw=black,fill=blue!15},
lineArrow/.style={arrows={-Latex[length=5pt 3 0]}},
every fit/.style={inner sep=.4em,draw}
]
\node (browser) [block] {Webbrowser};
\node (fitClient) [rounded corners,fit=(browser)] {};
\node [left] at (fitClient.west) {Client};
\onslide<4>{\node (JSF) [halfselected,below of=browser,node distance=5em] {Java Server Faces};}
\onslide<1-3>{\node (JSF) [block,below of=browser,node distance=5em] {Java Server Faces};}
\onslide<1>{\node (EJB) [selected,below of=JSF] {Enterprise Java Beans};}
\onslide<2-4>{\node (EJB) [block,below of=JSF] {Enterprise Java Beans};}
\onslide<2>{\node (JPA) [selected,below of=EJB] {Java Persistance API};}
\onslide<1,3,4>{\node (JPA) [block,below of=EJB] {Java Persistance API};}
\onslide<3>{\node (openJPA) [selected, below of=JPA] {OpenJPA Cache};}
\onslide<1,2,4>{\node (openJPA) [block, below of=JPA] {OpenJPA Cache};}
\node (fitGlassfish) [rounded corners,fit=(JSF) (EJB) (JPA) (openJPA)] {};
\node [left] at (fitGlassfish.west) [text width=1.5cm] {GlassFish/ Payara};
\node (memoryBuffers) [block, below of=openJPA] {Memory Buffers};
\node (services) [block, right of=memoryBuffers, xshift=2cm] {Services};
\onslide<4>{\node (database) [selected, below of=memoryBuffers] {Database};}
\onslide<1-3>{\node (database) [block, below of=memoryBuffers] {Database};}
\node (fitPostgreSQL) [rounded corners,fit=(memoryBuffers) (services) (database)] {};
\node [left] at (fitPostgreSQL.west) {PostgreSQL};
\node (fitServer) [rounded corners,fit=(fitGlassfish) (fitPostgreSQL),inner xsep=3em] {};
\node [left] at (fitServer.west) {Server};
\draw[lineArrow] (browser)--(JSF);
\draw[lineArrow] (JSF)--(EJB);
\draw[lineArrow] (EJB)--(JPA);
\draw[lineArrow] (JPA)--(openJPA);
\draw[lineArrow] (openJPA)--(memoryBuffers);
\draw[lineArrow] (memoryBuffers)--(database);
\draw[lineArrow] (services)|-(database);
\end{tikzpicture}
%\label{fig:webrequest}
\end{figure}
\end{columns}
\end{frame}
% 5. Methodik
\section{Methodik}
\begin{frame}[c]
\frametitle{Voraussetzungen}
\begin{itemize}
\item Verwendung von Docker, zur Performance"=Limitierung
\item Eigene Container für die Datenbank und den Webserver
\item Für die Untersuchung wird nur die Dokumentenliste beobachtet
\item Verwendung von Scripts zur besseren Vergleichbarkeit und Wiederholgenauigkeit
\end{itemize}
\end{frame}
\begin{frame}[c] \begin{frame}[c]
\frametitle{Vorgehen} \frametitle{Vorgehen}
\begin{itemize} \begin{itemize}
\item Vor jeder Messung werden die Container neugestartet und die Startroutinen abgewartet \item Vor jeder Messung werden die Container neugestartet und die Startroutinen abgewartet
\item Aufruf eines Bash-Script auf dem gleichen Rechner wie die Docker-Container um die Latenz des Netzwerkes auszuschließen \item Aufruf eines Bash"=Script auf dem gleichen Rechner wie die Docker-Container um die Latenz des Netzwerkes auszuschließen
\item Ermittlung des Speicherbedarfs vor und nach dem Webseitenaufrufen \item Ermittlung des Speicherbedarfs vor und nach dem Webseitenaufrufen
\item Messung der Aufruf der Index-Seite (ohne Datenbankaufrufe) und der Dokumentenliste, jeweils 10 mal \item Messung der Aufruf der Index"=Seite (ohne Datenbankaufrufe) und der Dokumentenliste, jeweils 10 mal
\item Report über die SQL-Abfragen mit pgBadger erstellen \item Report über die SQL"=Abfragen mit pgBadger erstellen
\end{itemize} \end{itemize}
\end{frame} \end{frame}
\begin{frame}[c] \begin{frame}[c]
\frametitle{Voraussetzungen} \frametitle{Erste Auffäligkeiten}
\begin{itemize} \begin{itemize}
\item Verwendung von Docker, zur Performance-Limitierung \item OutOfMemory"=Ausnahme ausgelöst nach dem vierten Script Aufruf ($\sim$40 Webseitenaufrufe)
\item Eigene Container für die Datenbank und den Webserver \item Erhöhung des Java"=Heapspeichers von 512MB auf 4096MB hat nur die Anzahl der Aufrufe bis zum Absturz verzögert
\item Für die Untersuchung wird nur die Dokumentenliste beobachtet
\end{itemize}
\vspace{10pt}
Erste Auffälligkeiten
\begin{itemize}
\item OutOfMemory-Ausnahme ausgelöst nach dem vierten Script Aufruf ($\sim$40 Webseitenaufrufe)
\item Erhöhung des Java-Heapspeichers von 512MB auf 4096MB hat nur die Anzahl der Aufrufe bis zum Absturz verzögert
\end{itemize} \end{itemize}
\end{frame} \end{frame}
%\subsection{Ohne Cache} \section{Untersuchungen}
\begin{frame}[c] \begin{frame}[c]
\frametitle{Ohne Cache} \frametitle{Vergleichsmessung - Ohne Cache}
\begin{columns} \begin{columns}
\onslide<2->{ \column{0.5\textwidth}
\column{0.5\textwidth} \begin{overprint}
\begin{itemize} \begin{itemize}
\item Deaktivieren aller Caches
\item Auffälliger Speicheranstieg, trotz deaktiviertem Cache \item Auffälliger Speicheranstieg, trotz deaktiviertem Cache
\item Gleichmässige Anzahl an Datenbankabfragen \item Gleichmässige Anzahl an Datenbankabfragen
\item Gleichmässige Laufzeit der Datenbankabfragen \item Gleichmässige Laufzeit der Datenbankabfragen
\item Laufzeitanteil der Datenbankabfragen unter 10\% \item Laufzeitanteil der Datenbankabfragen unter 10\%
\end{itemize} \end{itemize}
} \end{overprint}
\onslide<1->{ \column{0.5\textwidth}
\column{0.5\textwidth} \centering
\begin{table}[h!] \resizebox{0.8\textwidth}{!}{ \begin{tabular}{r|r|r|r|r|r}
\centering \thead{\#} & \thead{Call \\ (ms)} & \thead{Query \\ (\# / ms)} & \thead{Memory \\ Diff (MB)} & \thead{Render \\ (ms)} & \thead{DB"=load \\ (ms)} \\
\resizebox{\textwidth}{!}{ \begin{tabular}{r|r|r|r|r|r|r|r|r} \hline
& \multicolumn{3}{c|}{Aufrufzeit (ms)} & \multicolumn{2}{c|}{Datenbankabfragen} & \multicolumn{3}{c}{Speicherverbrauch (MB)} \\ \hline
\# & min & avg & max & \#-avg & avg (ms) & davor & danach & diff \\ 0 & 1931 & - & - & 1849 & 710 \\
\hline 1 & 682 & 1223.0 / 30.3 & 54.8 & 666 & 399 \\
\hline 2 & 389 & 1208.0 / 31.2 & 172.5 & 378 & 282 \\
1 & 360 & 623 & 2079 & 1224.0 & 30.3 & 872.8 & 914.1 & 41.3 \\ % 12240 - 303 ms (135+ 79+ 39+ 22+17+11) (#2-6,8) 3 & 407 & 1208.0 / 33.5 & 110.0 & 398 & 307 \\
2 & 331 & 372 & 430 & 1208.0 & 31.2 & 914.5 & 1008.0 & 93.5 \\ % 24320 - 615 ms (270+156+ 78+ 56+34+21) (#2-7) 4 & 359 & 1208.0 / 33.7 & 193.0 & 351 & 269 \\
3 & 291 & 428 & 815 & 1208.0 & 33.5 & 1030.0 & 1297.0 & 267.0 \\ % 36400 - 950 ms (406+256+118+ 79+55+36) (#2-7) \textbf{5} & 317 & 1208.0 / 32.9 & 107.0 & 309 & 235 \\
\textbf{4} & 288 & 357 & 433 & 1208.0 & 33.7 & 1299.0 & 1461.0 & 162.0 \\ % 48480 - 1287 ms (564+334+167+105+72+45) (#2-7) \end{tabular} }
5 & 294 & 404 & 499 & 1208.0 & 32.9 & 1462.0 & 1638.0 & 176.0 \\ % 60560 - 1616 ms (699+428+210+128+92+59) (#2-7)
\end{tabular} } \vspace{10pt}
\caption{Messung ohne Caches} \begin{tikzpicture}[scale=0.2,every node/.style={scale=0.6}]
\end{table} % Zeichne die Balken von unten nach oben
} \draw[fill=red] (0,0) rectangle (31.7,1.5); % WebRequest
\draw[fill=orange] (0,1.5) rectangle (30.9,3); % Render
\draw[fill=yellow] (0,3) rectangle (23.5,4.5); % DB-Load
\draw[fill=green] (0,4.5) rectangle (3.3,6); % DB
% Beschriftungen hinzufügen
\node at (15.0, 0.7) {WebRequest};
\node at (15.0, 2.2) {Render};
\node at (15.0, 3.7) {DB"=Load};
\node at (15.0, 5.2) {Queries};
\end{tikzpicture}
\end{columns} \end{columns}
\end{frame} \end{frame}
% Hier 2-3 der aktuellen erarbeiten Ansätze Vorstellen und nach dem Warum fragen % Hier 2-3 der aktuellen erarbeiten Ansätze Vorstellen und nach dem Warum fragen
% Genau beschreiben was Signifikant besser/schlechter ist % Genau beschreiben was Signifikant besser/schlechter ist
\begin{frame}
\frametitle{Caching EJB}
\begin{itemize}
\item Konfiguration über die Webseite des Payara"=Servers
\item habt keine Auswirkungen auf die Performance
\item Der Cache wird nur von den Provider selbst und nicht den geladenen Datenbank"=Objekten verwendet
\end{itemize}
\vspace{8pt}
\begin{corollary}
Nicht nutzbar für dieses Szenario
\end{corollary}
\end{frame}
\begin{frame}
\frametitle{Abfragesprachen}
\begin{itemize}
\item Ähnliche gemessene Zeiten
\item Untersuchung im Debugger zeigt ähnlicher Abfrage"=Syntax innerhalb von OpenJPA
\item Prüfung der SQL"=Abfragen zeigt, dass die identischen Befehle an die Datenbank übertragen werden
\item Keine Unterschied im Speicherverbrauch feststellbar
\item Gleiche Optimierung durch Hint \texttt{openjpa.FetchPlan.EagerFetchMode} (halbierte Laufzeit, geviertelte Datenbankaufrufe)
\item Andere Hints hatte keine messbaren Auswirkungen
\end{itemize}
\vspace{8pt}
\begin{corollary}
Daher kann die Art der Programmierung verwendet werden die für den Anwendungsfall die einfachere ist
\end{corollary}
\end{frame}
%\subsection{OpenJPA-Cache} %\subsection{OpenJPA-Cache}
\begin{frame}[c] \begin{frame}[c]
\frametitle{Caching mit OpenJPA} \frametitle{Caching mit OpenJPA}
\begin{columns} \begin{columns}
\onslide<2->{ \begin{column}{0.5\textwidth}
\column{0.5\textwidth} \begin{overprint}
\onslide<1>
\begin{itemize}
\item Einfaches aktivieren
\item Direkte Unterstützung
\item Konfiguration über die Anzahl der Objekte
\item Messung mit 1000 und 10000 Objekten
\end{itemize}
\onslide<2>
\begin{itemize} \begin{itemize}
\item Erwartete Reduzierung der Datenbankabfragen \item Erwartete Reduzierung der Datenbankabfragen
\item Laufzeit in der Datenbank halbiert sich nicht, trotz halbierter Abfragen \item Laufzeit in der Datenbank halbiert sich nicht, trotz halbierter Abfragen
\item Speicheranstieg wurde reduziert \item Speicheranstieg wurde reduziert
\end{itemize} \end{itemize}
}
\onslide<1->{ \end{overprint}
\column{0.5\textwidth} \end{column}
\begin{table}[h!]
\small % Rechte Spalte
\centering \column{0.5\textwidth}
\resizebox{\textwidth}{!}{ \begin{tabular}{r|r|r|r|r|r|r|r|r} \center
& \multicolumn{3}{c|}{Aufrufzeit (ms)} & \multicolumn{2}{c|}{Datenbankabfragen} & \multicolumn{3}{c}{Speicherverbrauch (MB)} \\ \resizebox{0.8\textwidth}{!}{\begin{tabular}{r|r|r|r|r|r}
\# & min & avg & max & \#-avg & avg (ms) & davor & danach & diff \\ \thead{\#} & \thead{Call \\ (ms)} & \thead{Query \\ (\# / ms)} & \thead{Memory \\ Diff (MB)} & \thead{Render \\ (ms)} & \thead{DB"=load \\ (ms)} \\
\hline \hline
\hline \hline
ref-4 & 288 & 357 & 433 & 1208.0 & 33.7 & 1299.0 & 1461.0 & 162.0 \\ % 48480 - 1287 ms (564+334+167+105+72+45) (#2-7) ref-5 & 317 & 1208.0 / 32.9 & 107.0 & 309 & 235 \\
\hline \hline
\hline \hline
1 & 338 & 567 & 1853 & 741.8 & 28.8 & 874.8 & 923.5 & 48.7 \\ % 7418 - 288 ms (145+ 42+ 40+ 24+18+ 8+ 7+ 4) (#2-8,12) 0 & 2347 & - & - & 2286 & 770 \\
2 & 235 & 290 & 460 & 685.2 & 25.8 & 923.5 & 926.4 & 2.9 \\ % 14270 - 546 ms (282+ 81+ 70+ 47+33+14+11+ 8) (#2-9) 1 & 611 & 730.2 / 28.8 & 39.2 & 595 & 284 \\
3 & 225 & 254 & 313 & 683.6 & 27.6 & 927.4 & 1018.0 & 90.6 \\ % 21106 - 822 ms (430+120+ 99+ 77+49+20+16+11) (#2-9) %2 & 319 & 667.3 / 25.8 & 117.3 & 309 & 195 \\
4 & 235 & 289 & 403 & 683.9 & 27.6 & 1018.0 & 1018.0 & 0.0 \\ % 27945 - 1098 ms (569+160+137+ 99+68+26+22+17) (#2-9) 3 & 281 & 680.6 / 27.6 & 56.0 & 271 & 180 \\
5 & 193 & 265 & 359 & 687.9 & 27.6 & 1025.0 & 1140.0 & 115.0 \\ % 34824 - 1374 ms (704+202+171+128+86+34+27+22) (#2-9) %4 & 280 & 671.3 / 27.6 & 55.0 & 271 & 189 \\
\hline 5 & 272 & 683.6 / 27.6 & 97.0 & 264 & 175 \\
\hline \hline
1 & 151 & 368 & 1904 & 142.2 & 20.8 & 878.1 & 919.9 & 41.8 \\ % 1422 - 208 ms (133+ 40+ 23+9+2+1) (#2,4-6,10,12) \hline
2 & 133 & 143 & 159 & 6.0 & 20.5 & 919.8 & 921.0 & 1.2 \\ % 1482 - 413 ms (274+ 80+ 47+9+2+1) (#2-3,5,6,10,12) 0 & 1904 & - & - & 2232 & 847 \\
3 & 120 & 126 & 132 & 6.0 & 19.9 & 922.8 & 924.1 & 1.3 \\ % 1542 - 612 ms (412+119+ 69+9+2+1) (#2,3,5,6,10,12) 1 & 368 & 141.2 / 20.8 & 30.5 & 404 & 124 \\
4 & 120 & 124 & 128 & 6.0 & 21.4 & 924.1 & 925.4 & 1.3 \\ % 1602 - 826 ms (550+168+ 96+9+2+1) (#2-4,6,10,12) %2 & 143 & 6.0 / 20.5 & 3.6 & 136 & 36 \\
5 & 109 & 114 & 131 & 6.0 & 19.7 & 926.1 & 926.8 & 0.7 \\ % 1662 - 1023 ms (683+209+119+9+2+1) (#2-4,6,10,12) 3 & 126 & 6.0 / 19.9 & 3.3 & 136 & 47 \\
\end{tabular} } %4 & 124 & 6.0 / 21.4 & 1.1 & 113 & 39 \\
\caption{Messung mit OpenJPA-Cache und Größe auf 1000 bzw. 10000} \textbf{5} & 114 & 6.0 / 19.7 & 1.2 & 107 & 32 \\
\end{table} \end{tabular} }
}
\vspace{8pt}
\begin{tikzpicture}[scale=0.2,every node/.style={scale=0.6}]
% Zeichne die Balken von unten nach oben
\draw[fill=red] (0,7) rectangle (31.7,8.5); % WebRequest
\draw[fill=orange] (0,8.5) rectangle (30.9,10); % Render
\draw[fill=yellow] (0,10) rectangle (23.5,11.5); % DB-Load
\draw[fill=green] (0,11.5) rectangle (3.3,13); % DB
% Beschriftungen hinzufügen
\node at (15.0, 7.7) {ref"=Call};
\node at (15.0, 9.2) {ref"=Render};
\node at (15.0, 10.7) {ref"=DB"=Load};
\node at (15.0, 12.2) {ref"=Queries};
% Zeichne die Balken von unten nach oben
\draw[fill=red] (0,0) rectangle (11.4,1.5); % WebRequest
\draw[fill=orange] (0,1.5) rectangle (10.7,3); % Render
\draw[fill=yellow] (0,3) rectangle (3.2,4.5); % DB-Load
\draw[fill=green] (0,4.5) rectangle (2.0,6); % DB
% Beschriftungen hinzufügen
\node at (7.0, 0.7) {Call};
\node at (7.0, 2.2) {Render};
\node at (7.0, 3.7) {DB"=Load};
\node at (7.0, 5.2) {Queries};
\end{tikzpicture}
\end{columns}
\end{frame}
\begin{frame}[c]
\frametitle{Cached Queries}
\begin{itemize}
\item Einfaches aktivieren
\item Einzelne Abfragen können ausgeschlossen werden
\item Keine Auswirkung auf die Performance
\item Wird nur beachtet wenn keine Argumente vorhanden sind
\end{itemize}
\vspace{8pt}
\begin{corollary}
Nur gut verwendbar, wenn keine Bedingungen vorhanden sind
\end{corollary}
\end{frame}
\begin{frame}[c]
\frametitle{Caching mit Ehcache}
\begin{columns}
\column{0.5\textwidth}
\begin{overprint}
\onslide<1>
\begin{itemize}
\item Benötigt zusätzliche Pakete
\item Aufwendigere Konfiguration, ohne Fehlerausgabe
\item Zusätzliche Konfiguration bzw. Code zum aktivieren des Caches
\item Weitere Konfiguration an den Klassen möglich
\end{itemize}
\onslide<2>
\begin{itemize}
\item Erwartete Reduzierung der Datenbankabfragen
\item Laufzeit der Datenbankabfragen halbiert sich nur trotz signifikant weniger Abfragen
\item Starke Reduzierung der Laderoutine von Datenbank nach Java"=Objekten
\item Geringer Speicheranstieg trotz des Caches
\item Sehr effizienter Cache, auch bei größeren Datenmengen
\end{itemize}
\end{overprint}
\column{0.5\textwidth}
\centering
\resizebox{\textwidth}{!}{\begin{tabular}{r|r|r|r|r|r}
\thead{\#} & \thead{Call \\ (ms)} & \thead{Query \\ (\# / ms)} & \thead{Memory \\ Diff (MB)} & \thead{Render \\ (ms)} & \thead{DB"=load \\ (ms)} \\
\hline
\hline
ref-5 & 317 & 1208.0 / 32.9 & 107.0 & 309 & 235 \\
\hline
\hline
0 & 2820 & - & - & 2809 & 1186 \\
1 & 488 & 135.2 / 20.7 & 24.4 & 490 & 175 \\
2 & 144 & 6.0 / 20.1 & 1.0 & 136 & 38 \\
3 & 129 & 6.0 / 19.4 & 1.0 & 121 & 34 \\
4 & 123 & 6.0 / 19.7 & 8.0 & 116 & 33 \\
\textbf{5} & 118 & 6.0 / 12.7 & 4.0 & 111 & 34 \\
\end{tabular} }
\vspace{10pt}
\begin{tikzpicture}[scale=0.2,every node/.style={scale=0.6}]
% Zeichne die Balken von unten nach oben
\draw[fill=red] (0,7) rectangle (31.7,8.5); % WebRequest
\draw[fill=orange] (0,8.5) rectangle (30.9,10); % Render
\draw[fill=yellow] (0,10) rectangle (23.5,11.5); % DB-Load
\draw[fill=green] (0,11.5) rectangle (3.3,13); % DB
% Beschriftungen hinzufügen
\node at (15.0, 7.7) {ref"=Call};
\node at (15.0, 9.2) {ref"=Render};
\node at (15.0, 10.7) {ref"=DB"=Load};
\node at (15.0, 12.2) {ref"=Queries};
% Zeichne die Balken von unten nach oben
\draw[fill=red] (0,0) rectangle (11.8,1.5); % WebRequest
\draw[fill=orange] (0,1.5) rectangle (11.1,3); % Render
\draw[fill=yellow] (0,3) rectangle (3.4,4.5); % DB-Load
\draw[fill=green] (0,4.5) rectangle (1.3,6); % DB
% Beschriftungen hinzufügen
\node at (6.0, 0.7) {Call};
\node at (6.0, 2.2) {Render};
\node at (6.0, 3.7) {DB"=Load};
\node at (6.0, 5.2) {Queries};
\end{tikzpicture}
\end{columns} \end{columns}
\end{frame} \end{frame}
@ -222,111 +488,290 @@
\begin{frame}[c] \begin{frame}[c]
\frametitle{Abfragen über materialized views} \frametitle{Abfragen über materialized views}
\begin{columns} \begin{columns}
\onslide<2->{ \column{0.5\textwidth}
\column{0.5\textwidth} \begin{overprint}
\onslide<1>
\begin{itemize} \begin{itemize}
\item Deutliche Reduzierung der Datenbankabfragen und \=laufzeiten \item Materialized View und Webseite aus dem aktuellen Wedekind"=Projekt übernommen \citep{Dokument53:online}
\item Unter-Abfragen werden als Json-Objekte direkt hinterlegt \item Zusätzliche Anpassung an der View um die Parameter in der Abfrage zu entfernen für Test mit QueryCache
\item Verschiebung des JSON"=Parsen in den Webclient
\end{itemize}
\onslide<2>
\begin{itemize}
\item Deutliche Reduzierung der Datenbankabfragen und "=laufzeiten
\item Unter"=Abfragen werden als JSON"=Objekte direkt hinterlegt
\item Teuer beim erstellen, aber selten notwendig \item Teuer beim erstellen, aber selten notwendig
\item Geringe Schwankung der Aufrufzeiten \item Geringe Schwankung der Aufrufzeiten
\item Anteil der Datenbank nochmals reduziert \item Anteil der Datenbank nochmals reduziert
\item Deutliche Reduzierung der DB"=Load Laufzeit durch Verschiebung des JSON"=Parsing
\end{itemize} \end{itemize}
} \end{overprint}
\onslide<1->{ \column{0.5\textwidth}
\column{0.5\textwidth} \centering
\begin{table} \resizebox{\textwidth}{!}{\begin{tabular}{r|r|r|r|r|r}
\centering \thead{\#} & \thead{Call \\ (ms)} & \thead{Query \\ (\# / ms)} & \thead{Memory \\ Diff (MB)} & \thead{Render \\ (ms)} & \thead{DB"=load \\ (ms)} \\
\resizebox{\textwidth}{!}{ \begin{tabular}{r|r|r|r|r|r|r|r|r} \hline
& \multicolumn{3}{c|}{Aufrufzeit (ms)} & \multicolumn{2}{c|}{Datenbankabfragen} & \multicolumn{3}{c}{Speicherverbrauch (MB)} \\ \hline
\# & min & avg & max & \#-avg & avg (ms) & davor & danach & diff \\ ref-5 & 317 & 1208.0 / 32.9 & 107.0 & 309 & 235 \\
\hline \hline
\hline \hline
ref & 288 & 357 & 433 & 1208.0 & 33.7 & 1299.0 & 1461.0 & 162.0 \\ % 48480 - 1287 ms (564+334+167+105+72+45) (#2-7) 0 & 859 & - & - & 803 & 334 \\
\hline 1 & 348 & 16.8 / 2.5 & 36.4 & 331 & 174 \\
\hline 2 & 194 & 9.0 / 2.4 & 2.6 & 185 & 99 \\
1 & 203 & 315 & 808 & 17.8 & 3.0 & 851.4 & 883.9 & 32.5 \\ % 178 - 30 ms (19+11+0) (#2,4,8) 3 & 161 & 9.0 / 2.4 & 3.0 & 152 & 77 \\
2 & 154 & 172 & 187 & 9.0 & 2.2 & 883.2 & 887.0 & 3.8 \\ % 268 - 52 ms (33+18+1) (#2,3,8) 4 & 145 & 9.0 / 2.4 & -3.4 & 137 & 73 \\
3 & 145 & 151 & 163 & 9.0 & 2.8 & 887.7 & 895.3 & 7.6 \\ % 358 - 80 ms (52+27+1) (#2,3,8) 5 & 137 & 9.0 / 2.4 & 3.0 & 129 & 72 \\
4 & 132 & 143 & 152 & 9.0 & 2.8 & 896.0 & 900.0 & 4.0 \\ % 448 - 108 ms (70+37+1) (#2,3,8) \textbf{js} & 70+13 & 9.0 / 2.4 & - & $\sim$60 & 4 \\
5 & 121 & 125 & 132 & 9.0 & 2.4 & 900.6 & 901.0 & 0.4 \\ % 538 - 132 ms (85+46+1) (#2,3,8) \end{tabular} }
\end{tabular} }
\caption{Messung mit Materialized View} \vspace{8pt}
\end{table} \begin{tikzpicture}[scale=0.2,every node/.style={scale=0.6}]
} % Zeichne die Balken von unten nach oben
\draw[fill=red] (0,7) rectangle (31.7,8.5); % WebRequest
\draw[fill=orange] (0,8.5) rectangle (30.9,10); % Render
\draw[fill=yellow] (0,10) rectangle (23.5,11.5); % DB-Load
\draw[fill=green] (0,11.5) rectangle (3.3,13); % DB
% Beschriftungen hinzufügen
\node at (15.0, 7.7) {ref"=Call};
\node at (15.0, 9.2) {ref"=Render};
\node at (15.0, 10.7) {ref"=DB"=Load};
\node at (15.0, 12.2) {ref"=Queries};
% Zeichne die Balken von unten nach oben (9)
\draw[fill=red] (0,0) rectangle (8.3,1.5); % WebRequest
\draw[fill=orange] (0,1.5) rectangle (6,3); % Render
\draw[fill=yellow] (0,3) rectangle (0.4,4.5); % DB-Load
\draw[fill=green] (0,4.5) rectangle (0.3,6); % DB
% Zeichne die Balken von unten nach oben (5)
%\draw[fill=red] (0,0) rectangle (13.7,1.5); % WebRequest
%\draw[fill=orange] (0,1.5) rectangle (12.9,3); % Render
%\draw[fill=yellow] (0,3) rectangle (7.2,4.5); % DB-Load
%\draw[fill=green] (0,4.5) rectangle (0.3,6); % DB
% Beschriftungen hinzufügen
\node at (3.0, 0.7) {Complete};
\node at (3.0, 2.2) {Server"=Side};
\node at (3.0, 3.7) {DB"=Load};
\node at (3.0, 5.2) {Queries};
\end{tikzpicture}
\end{columns} \end{columns}
\end{frame} \end{frame}
\section{Vergleich} \begin{frame}[c]
\frametitle{Optimierung der Abfrage}
\begin{columns}
\column{0.5\textwidth}
\begin{overprint}
\onslide<1>
\begin{itemize}
\item Große Datenmenge vom ersten Befehlt bis fast zur Ausgabe
\item Höchste Kosten im Seq Scan der Dokumententabelle
\item Nur Seq Scan bei den verlinkten Tabellen
\item Am Ende ist ein teurer Sort notwendig
\end{itemize}
\onslide<2>
\begin{itemize}
\item Umstellung mit dem WITH"=Statement
\item Große Datenmenge verschwindet nach dem ersten Hash join
\item Verwendung von Index Scan
\item Kosten der Sortierung am Ende reduziert
\item Reduktion der Laufzeit um den Faktor drei
\item Nur möglich wenn die Bedingen ins WITH eingetragen werden können
\end{itemize}
\end{overprint}
\column{0.5\textwidth}
\begin{overprint}
\onslide<1>
\includegraphics[width=\textwidth]{gfx/chapter05_ExplainVisualize.png}
\onslide<2>
\includegraphics[width=\textwidth]{gfx/chapter05_ExplainVisualize_with.png}
\end{overprint}
\end{columns}
\end{frame}
\section{Fazit}
\begin{frame}[c] \begin{frame}[c]
\frametitle{Vergleich} \frametitle{Vergleich}
\begin{columns} \begin{columns}
\column{0.3\textwidth} \column{0.5\textwidth}
\centering \centering
\begin{tikzpicture}[scale=.4] \begin{tikzpicture}[scale=.4]
\centering
\begin{axis}[ \begin{axis}[
title={Laufzeitvergleich Webseitenaufrufe}, title={Laufzeitvergleich Webseitenaufrufe},
%width=\textwidth,height=\textheight, ymax=1200,
xlabel={Aufruf},
ylabel={Laufzeit [ms]},
enlargelimits=0.05,
ymin=0, ymax=2100,
xtick={0,1,2,3,4,5}, %Ticks explizit angeben, dass bei grpßerer Darstellung nicht Zwischenticks existieren
ytick={0,500,1000,1500,2000,2500},
legend pos=north east,
ymajorgrids=true,
grid style=dashed,
] ]
\addplot coordinates { (0,2079)(1,623)(2,372)(3,428)(4,357)(5,404) }; \addplot coordinates {(0,1931) (1,682)(2,389)(3,407)(4,359)(5,317)};
\addplot coordinates { (0,1853) (1,567)(2,290)(3,254)(4,289)(5,265)}; \addplot coordinates {(0,2347) (1,611)(2,319)(3,281)(4,280)(5,272)};
\addplot coordinates { (0,1904) (1,143)(2,126)(3,126)(4,124)(5,114)}; \addplot coordinates {(0,1904) (1,368)(2,143)(3,126)(4,124)(5,114)};
\addplot coordinates { (0,808) (1,315)(2,172)(3,151)(4,143)(5,125)}; \addplot coordinates {(0,2820) (1,488)(2,144)(3,129)(4,123)(5,118)};
\legend{Ohne Cache,OpenJPA Cache,OpenJPA Cache groß,Materialized View} \addplot coordinates {(0, 859) (1,348)(2,194)(3,161)(4,145)(5,137)};
\addplot coordinates {(5, 83)};
\legend{Ohne Cache,OpenJPA Cache,OpenJPA Cache groß,Ehcache,Materialized View,Materialized View JS}
\end{axis} \end{axis}
\end{tikzpicture} \end{tikzpicture}
\begin{tikzpicture}[scale=.4]
\centering \centering
\begin{tikzpicture}[scale=.4]
\begin{axis}[ \begin{axis}[
title={Laufzeitvergleich Datenbankabfragen}, title={Laufzeitvergleich Datenbankabfragen},
%width=\textwidth,height=\textheight, ymax=80,
xlabel={Aufruf},
ylabel={Laufzeit [ms]},
enlargelimits=0.05,
ymin=0, ymax=60,
xtick={1,2,3,4,5}, %Ticks explizit angeben, dass bei grpßerer Darstellung nicht Zwischenticks existieren xtick={1,2,3,4,5}, %Ticks explizit angeben, dass bei grpßerer Darstellung nicht Zwischenticks existieren
legend pos=north east,
ymajorgrids=true,
grid style=dashed,
] ]
\addplot coordinates { (1,30.3)(2,31.5)(3,33.5)(4,33.7)(5,32.9) }; \addplot coordinates {(1,30.3)(2,31.5)(3,33.5)(4,33.7)(5,32.9)};
\addplot coordinates { (1,28.8)(2,25.8)(3,27.6)(4,27.6)(5,27.6) }; \addplot coordinates {(1,28.8)(2,25.8)(3,27.6)(4,27.6)(5,27.6)};
\addplot coordinates { (1,20.8)(2,20.5)(3,19.9)(4,21.4)(5,19.7) }; \addplot coordinates {(1,20.8)(2,20.5)(3,19.9)(4,21.4)(5,19.7)};
\addplot coordinates { (1,3.0)(2,2.2)(3,2.8)(4,2.8)(5,2.4) }; \addplot coordinates {(1,20.7)(2,20.1)(3,19.4)(4,19.7)(5,12.7)};
\legend{Ohne Cache,OpenJPA Cache,OpenJPA Cache groß,Materialized View} \addplot coordinates {(1, 2.5)(2, 2.4)(3, 2.4)(4, 2.4)(5, 2.4)};
\addplot coordinates {(5, 2.4)};
\legend{Ohne Cache,OpenJPA Cache,OpenJPA Cache groß,Ehcache,Materialized View,Materialized View JS}
\end{axis} \end{axis}
\end{tikzpicture} \end{tikzpicture}
\pause \column{0.5\textwidth}
\centering
\begin{tikzpicture}[scale=.4]
\begin{axis}[
title={Laufzeitvergleich Render},
ymax=1200,
]
\addplot coordinates {(0,1849) (1,666)(2,378)(3,398)(4,351)(5,309)};
\addplot coordinates {(0,2286) (1,595)(2,309)(3,271)(4,271)(5,264)};
\addplot coordinates {(0,2232) (1,404)(2,136)(3,136)(4,113)(5,107)};
\addplot coordinates {(0,2809) (1,490)(2,136)(3,121)(4,116)(5,111)};
\addplot coordinates {(0, 803) (1,331)(2,185)(3,152)(4,137)(5,129)};
\addplot coordinates {(5, 60)};
\legend{Ohne Cache,OpenJPA Cache,OpenJPA Cache groß,Ehcache,Materialized View,Materialized View JS}
\end{axis}
\end{tikzpicture}
\column{0.7\textwidth} \centering
\begin{tikzpicture}[scale=.4]
\begin{axis}[
title={Laufzeitvergleich DB"=Load},
ymax=1200,
]
\addplot coordinates {(0, 710) (1,399)(2,282)(3,307)(4,269)(5,235)};
\addplot coordinates {(0, 770) (1,284)(2,195)(3,180)(4,189)(5,175)};
\addplot coordinates {(0, 847) (1,124)(2, 36)(3, 47)(4, 39)(5, 32)};
\addplot coordinates {(0,1186) (1,175)(2, 38)(3, 34)(4, 33)(5, 34)};
\addplot coordinates {(0, 334) (1,174)(2, 99)(3, 77)(4, 73)(5, 72)};
\addplot coordinates {(5, 4)};
\legend{Ohne Cache,OpenJPA Cache,OpenJPA Cache groß,Ehcache,Materialized View,Materialized View JS}
\end{axis}
\end{tikzpicture}
\end{columns}
\end{frame}
\begin{frame}
\frametitle{Vergleich der besten Laufzeiten}
\begin{columns}
\column{0.5\textwidth}
\begin{tikzpicture}[scale=0.2,every node/.style={scale=0.6}]
% Zeichne die Balken von unten nach oben
\draw[fill=red] (0,26) rectangle (31.7,27.5); % WebRequest
\draw[fill=orange] (0,27.5) rectangle (30.9,29); % Render
\draw[fill=yellow] (0,29) rectangle (23.5,30.5); % DB-Load
\draw[fill=green] (0,30.5) rectangle (3.3,32); % DB
% Beschriftungen hinzufügen
\node at (9.0, 26.7) {ref"=Call};
\node at (9.0, 28.2) {ref"=Render};
\node at (9.0, 29.7) {ref"=DB"=Load};
\node at (9.0, 31.2) {ref"=Queries};
%\node at (25.0, 28.8) {ohne Cache};
% OpenJPA
% Zeichne die Balken von unten nach oben
\draw[fill=red] (0,19.5) rectangle (11.4,21); % WebRequest
\draw[fill=orange] (0,21) rectangle (10.7,22.5); % Render
\draw[fill=yellow] (0,22.5) rectangle (3.2,24); % DB-Load
\draw[fill=green] (0,24) rectangle (2.0,25.5); % DB
% Beschriftungen hinzufügen
\node at (6.0, 20.2) {Call};
\node at (6.0, 21.7) {Render};
\node at (6.0, 23.2) {DB"=Load};
\node at (6.0, 24.7) {Queries};
\node at (25.0, 22.6) {OpenJPA 10000 Objekte};
% Ehcache
% Zeichne die Balken von unten nach oben
\draw[fill=red] (0,13) rectangle (11.8,14.5); % WebRequest
\draw[fill=orange] (0,14.5) rectangle (11.1,16); % Render
\draw[fill=yellow] (0,16) rectangle (3.4,17.5); % DB-Load
\draw[fill=green] (0,17.5) rectangle (1.3,19); % DB
% Beschriftungen hinzufügen
\node at (6.0, 13.7) {Call};
\node at (6.0, 15.2) {Render};
\node at (6.0, 16.7) {DB"=Load};
\node at (6.0, 18.2) {Queries};
\node at (25.0, 15.8) {Ehcache};
% matview normal
% Zeichne die Balken von unten nach oben (5)
\draw[fill=red] (0,6.5) rectangle (13.7,8); % WebRequest
\draw[fill=orange] (0,8) rectangle (12.9,9.5); % Render
\draw[fill=yellow] (0,9.5) rectangle (7.2,11); % DB-Load
\draw[fill=green] (0,11) rectangle (0.3,12.5); % DB
\node at (3.0, 7.2) {Call};
\node at (3.0, 8.7) {Render};
\node at (3.0, 10.2) {DB"=Load};
\node at (3.0, 11.7) {Queries};
\node at (25.0, 9.3) {Materialized View};
% matview parseJson Client
% Zeichne die Balken von unten nach oben (9)
\draw[fill=red] (0,0) rectangle (8.3,1.5); % WebRequest
\draw[fill=orange] (0,1.5) rectangle (6,3); % Render
\draw[fill=yellow] (0,3) rectangle (0.4,4.5); % DB-Load
\draw[fill=green] (0,4.5) rectangle (0.3,6); % DB
% Beschriftungen hinzufügen
\node at (3.0, 0.7) {Complete};
\node at (3.0, 2.2) {Server"=Side};
%\node at (3.0, 0.7) {Call};
%\node at (3.0, 2.2) {Render};
\node at (3.0, 3.7) {DB"=Load};
\node at (3.0, 5.2) {Queries};
\node at (25.0, 2.8) {Materialized View Client"=Parsing};
\end{tikzpicture}
\column{0.5\textwidth}
\begin{itemize} \begin{itemize}
\item Keine Start-Phase auf der Datenbank zu erkennen, im Gegensatz zur Anwendung
\item Die Datenbankabfragen nehmen den kleinsten Teil der Laufzeit ein \item Die Datenbankabfragen nehmen den kleinsten Teil der Laufzeit ein
\item Beim Großteil der Optimierung wird die Zeit bei DB"=Load verringert
\item Die Differenz zwischen DB"=Load und Render verändert sich gering
\item Hoher Offset im DB"=Load, außer bei Materialized View mit Client Parsing
\item Materialized View geringste Datenbankabfragezeiten, aber nicht schneller als OpenJPA-Cache mit größerem Cache \item Materialized View geringste Datenbankabfragezeiten, aber nicht schneller als OpenJPA-Cache mit größerem Cache
%\item Die erhöhte Differenz bei zwischen Render und Call bei Materialized View mit Client Parsing ist der Client"=Anteil
\end{itemize} \end{itemize}
\end{columns} \end{columns}
\end{frame}
\begin{frame}
\frametitle{Zusammenfassung}
\begin{itemize}
\item Query"=Cache und EJB"=Cache nicht verwendbar
\item Bei Verwendung von Cache auf Ehcache umstellen, OpenJPA"=Cache ist ineffizienter
\item Die Wahl der Abfragesprache hat keine Performance"=Beeinflussung
\item Verwendung der Materialized"=View mit JSON"=Parsing am Client hat die beste Performance
\item Abfragen können optimiert werden, aber besitzen nur geringe Auswirkung auf den gesamten Aufruf
\item Größtes Optimierungspotential im ORM vorhanden, bei der Bereitstellung der Entitäten (gut an der Umsetzung mit Materialized"=View zu sehen)
\end{itemize}
\end{frame} \end{frame}
\begin{frame} \begin{frame}
\frametitle{Ausblick} \frametitle{Ausblick}
\begin{itemize} \begin{itemize}
\item Größte Optimierungspotenziale sind in der Anwendung vorhanden \item Weitestgehende optimale Umsetzung der Schichten im GlassFish"=Server, bzw. wenige Optimierungsmöglichkeiten
\item Ermittlung welcher Teil der Anwendung die meiste Zeit benötigt \item Verlagerung des Aufbaus der Darstellung an den Client um weniger Ressourcen am Server zu nutzen
\item Weitere Prüfung der anderen Caches \item Speicherleck im OpenJPA durch neue Version behebbar
\item Suche des Speicherlecks \item Wechseln auf anderen ORM oder eigene Entwicklung
\item Verwendung von Caches benötigen zusätzliche Ressourcen, daher nicht sinnvoll bei schwächeren Serversystemen
\end{itemize} \end{itemize}
\end{frame} \end{frame}