242 lines
17 KiB
TeX
242 lines
17 KiB
TeX
% !TeX root = ../../thesis.tex
|
|
|
|
\chapter{Evaluierung}
|
|
\label{ch:evaluation}
|
|
|
|
Nun werden die durchgeführten Anpassungen anhand ihre Effektivität betrachtet und unter welchen äußeren Einflüssen
|
|
diese eine Optimierung darstellen. Weiterhin werden die Nachteile der Anpassungen überprüft und und bei der Betrachtung
|
|
der Effektivität mit beachtet.
|
|
|
|
Es wurden die Konfigurationen der Caches von OpenJPA, \ac{JPA}, \ac{EJB} und Ehcache aktiviert und deren Auswirkung betrachtet. Bei den
|
|
Caches, bei denen eine Größe angebbar ist, wurde zusätzlich mit der Anzahl variiert, um zu ermitteln, in welchem Umfang
|
|
sich diese auswirken. Des Weiteren wird die Art der Programmierung für die Abfragen betrachtet, ob signifikante
|
|
Unterschiede in der Performance und der Abarbeitung erkennbar sind. Als weiteren Punkt werden die
|
|
\textit{Materialized View} verwendet, um zu ermitteln, ob durch einen vorverdichteten und aufbereiteten Datenbestand
|
|
die Abfragen beschleunigt werden können. Abschließend werden die Abfragen in der Datenbank betrachtet und auf ihre
|
|
Optimierungspotentiale hin untersucht.
|
|
|
|
\section{Nutzerumfrage}
|
|
\label{sec:evaluation:user-survey}
|
|
|
|
Zusätzlich war noch eine Befragung unter den Benutzern und den Entwicklern geplant. Auf Grund dessen, dass nur fünf
|
|
Personen zur Verfügung stehen, ist dies nicht zielführend. Daher ist die einzig sinnvolle Alternative, welche gewählt
|
|
wurde, ein rein technischer Ansatz.
|
|
|
|
\section{Umgestalten der Datenbanktabellen}
|
|
\label{sec:evaluation:new-table}
|
|
|
|
Hierfür wurde die aktuelle Datenstruktur untersucht, um zu überprüfen, ob eine Umgestaltung der Tabelle eine Verbesserung
|
|
bringt. Die typische Optimierung ist die Normalisierung der Tabellenstruktur. Die Tabellenstruktur ist aktuell
|
|
schon normalisiert, daher kann hier nichts weiter optimiert werden.
|
|
|
|
Eine weitere Optimierungsstrategie besteht in der Denormalisierung, um sich die Verknüpfungen der Tabellen zu sparen.
|
|
Dies ist in diesem Fall nicht anwendbar, da nicht nur 1:n Beziehungen vorhanden sind, sondern auch auch n:m Beziehungen.
|
|
Dadurch erhöht sich fälschlicherweise die Anzahl der Dokumentenliste.
|
|
|
|
\section{Statische Webseiten}
|
|
\label{sec:evaluation:static-website}
|
|
|
|
Eine Umstellung der Dokumentenliste in eine statische Webseite würde die Zugriffszeiten sehr verkürzen. Darüber hinaus
|
|
funktionieren in statischen Webseiten aber keine Suchen oder Sortierungen. Die Sortierung könnte durch das Erstellen
|
|
von statischen Seiten aller Möglichkeiten der Sortierung emuliert werden, diese würde den notwendigen Speicherbedarf der
|
|
Webseite vervielfachen. Für die Suchanfragen ist dies nicht mehr möglich, da nicht alle Suchanfragen vorher definiert
|
|
werden können.
|
|
|
|
Die Umstellung der Suche auf Client"=Basis wäre noch eine Möglichkeit, dafür benötigen die Clients entsprechende
|
|
Leistung und es muss eine Referenzdatei erstellt werden, welche alle Informationen über die Dokumente beinhaltet, nach
|
|
welcher gesucht werden kann.
|
|
|
|
Daher ist eine Umstellung auf statische Webseiten nicht sinnvoll.
|
|
|
|
\section{Client basierte Webseiten}
|
|
\label{sec:evaluation:client-side-rendering}
|
|
|
|
Als weitere Möglichkeit könnte man die Webseite so umbauen, dass die Daten erst im Nachgang über eine AJAX-Anfrage
|
|
ermittelt und die Sortierung und Aufteilung im Client durchgeführt wird. Hierbei wird allerdings je nach Datenmenge ein
|
|
großer Speicher am Client benötigt und der Großteil der benötigten Rechenleistung zu dem Client verschoben.
|
|
|
|
Dies wiederrum ist ein Vorteil für den Serverbetreiber, da durch die Verschiebung weniger Rechenleistung am Server
|
|
benötigt wird. Gleichzeitig würde man wiederrum schwächere Clients, wie Smartphones, aussperren, da bei diesem
|
|
die notwendige Rechenleistung fehlt, um die Webseite in annehmbarer Zeit darzustellen.
|
|
|
|
\section{Serverseitige Paginierung}
|
|
\label{sec:evaluation:server-side-paging}
|
|
|
|
Die Aufteilung eines großen Datenbestandes in mehrere einzelne Seiten ist eine der wenigen Optimierungsmöglichkeiten in
|
|
der \ac{JSF}"=Ebene. Dieser Einbau optimiert direkt an mehreren Stellen, dazu gehört die kleinere Datenmenge, die vom
|
|
Datenbankserver geladen wird. Ebenso wird entsprechend weniger Zeit benötigt, um die View zu erstellen,
|
|
gleichzeitig wird die übertragene Datenmenge an den Client reduziert. Dadurch benötigt die Seite auf dem Client weniger
|
|
Zeit zum rendern.
|
|
|
|
Da das Paging für den Fall der Dokumentenliste implementiert ist, gibt es hier keine weiteren offensichtliche
|
|
Optimierungsmöglichkeiten.
|
|
|
|
\section{Caching im OpenJPA}
|
|
\label{sec:evaluation:caching-jpa}
|
|
|
|
Bei der Verwendung des OpenJPA"=Caches gibt es einige Verbesserungen bei der Geschwindigkeit zu sehen. Die Höhe der
|
|
Optimierungen hängt stark von der gewählten Cache"=Größe und der aufgerufenen Webseiten ab. Solange die Anfragen sich
|
|
auf die gleichen Objekte beziehen und diese alle im Cache hinterlegt werden können, fällt die Optimierung entsprechend
|
|
hoch aus. Sobald bei den Anfragen aber häufig die zu ermittelnden Objekte sich unterscheiden und alte Objekte wieder
|
|
aus dem Cache entfernt werden, fällt die Performance"=Verbesserung immer geringer aus.
|
|
|
|
Das Entfernen der Objekte kann zwar umgangen werden, indem die häufig abgefragten Objekte gepinnt werden, was aber
|
|
den Speicherbedarf noch weiter erhöht, da diese Objekte nicht in die Zählung der Cache"=Objekte miteinfliesen.
|
|
Als größten Nachteil des Caches ist zu nennen, dass die notwendige Speichermenge ständig zur Verfügung gestellt
|
|
werden muss. Damit ist immer ein gewisser Grundbedarf notwendig, da sich der Speicher bis zum eingestellten
|
|
Grenzwert aufbaut und dann nicht mehr entleert wird. Gerade bei kleiner dimensionierten Servern stellt dies ein
|
|
größeres Problem dar, da nun weniger Speicher für die anderen laufenden Programme, wie dem Datenbankmanagementsystem,
|
|
zur Verfügung steht.
|
|
|
|
Hierbei ist aber noch zu beachten, dass die Optimierung durch den Cache nicht die Laufzeit der Abfragen in der Datenbank
|
|
enorm verringert hat, sondern die Laufzeit beim Erstellen der Objekte im \textit{OpenJPA}"=Framework. Dies sieht man
|
|
sehr gut schon bei der ersten Messung, wie in \autoref{tbl:measure-ojpa-active}. Hierbei wird die Laufzeit in der
|
|
Datenbank im Schnitt um circa 5 ms reduziert, allerdings wird die komplette Webseite fast 100 ms schneller an den Client
|
|
ausgeliefert. Dies ist nur dadurch erklärbar, dass das Erstellen und mit den Datenwerte zu befüllen mehr Zeit kostet,
|
|
als das Objekt aus dem Cache zu ermitteln und zurückzugeben.
|
|
|
|
Daher ist die Verwendung des OpenJPA"=Cache nur in Verbindung mit einem größer dimensionierten Server gut verwendbar,
|
|
wenn der Großteil der Objekte im Cache gehalten werden kann. Bei Bedarf sollten die häufig frequentierten Objekte
|
|
explizit im Cache aufgenommen und angepinnt werden.
|
|
|
|
\section{Cached Queries}
|
|
\label{sec:evaluation:cached-queries}
|
|
|
|
Die Optimierung über die gespeicherten Anfragen brachte keine Verbesserung hervor. Dieser Cache bearbeitet nur Anfragen,
|
|
die keine Bedingungen besitzen und daher ist es erklärbar, warum er für diese Abfrage nicht funktioniert. In diesem Fall sind in der Tabelle
|
|
noch nicht freigegebene und ungültige Datensätze gespeichert, daher müssen diese vor dem Übertragen herausgefiltert
|
|
werden. Aus diesem Grund werden die Anfragen in diesem Cache nicht gespeichert.
|
|
|
|
Dadurch ist dieser Cache für eine Performance"=Verbesserung in dem Fall der Dokumentenliste nicht anwendbar.
|
|
|
|
\section{Caching mit Ehcache}
|
|
\label{sec:evaluation:ehcache}
|
|
|
|
Mit dem Ehcache konnte eine Verbesserung in der Performance erzielt werden. Im Vergleich zum Cache von OpenJPA ist
|
|
die Verbesserung sehr ähnlich. Die Standardwerte dieses Caches sind gut vordefiniert, es wird für den aktuellen Fall
|
|
keine Anpassung benötigt, um eine gute Performance zu erreichen. Hierbei ist natürlich das gleiche Problem wie in anderen
|
|
Caches, dass beim Erreichen der Grenzen alte Objekte entfernt werden müssen.
|
|
|
|
Nach aktueller Beobachtung scheint die Verwaltung im Ehcache effizienter gestaltet zu sein als die des OpenJPA"=Caches.
|
|
Im Falle des Ehcache ist die interne Verwaltung auf mehrere Caches aufgebaut, dies ist daran zu sehen, dass in der
|
|
Standardkonfiguration jede Klasse ihren eigenen Cache besitzt. Diese können einzeln konfiguriert und diagnostiziert
|
|
werden, um diese genau auf die jeweiligen Bedürfnisse der Objekte anzupassen.
|
|
|
|
Im Falle der Verwendung des Caches ist auch hier gut zu sehen, dass der Speicheranstieg bei der Verwendung des Caches
|
|
sehr gering ist, dies deutet ebenfalls darauf hin, dass die Speicherproblematik beim Erstellen von Objekten innerhalb
|
|
des OpenJPA Framework liegen muss.
|
|
|
|
Durch die effizientere Verwendung des Speichers, ist der Ehcache die bessere Alternative zum OpenJPA"=Cache. Dieser ist
|
|
auch schon für kleinere Serverkonfigurationen gut verwendbar. Hierbei ist nur abzuwägen, mit welcher Größe der Cache
|
|
bereitgestellt werden kann, dies hängt direkt vom verfügbaren Arbeitsspeicher ab.
|
|
|
|
\section{Caching in EJB}
|
|
\label{sec:evaluation:ejb}
|
|
|
|
Bei der Erweiterung des \ac{EJB} konnte keine Verbesserung in der Performance festgestellt werden. Der Grund hierfür ist, dass
|
|
der \ac{EJB}"=Cache die Provider beinhaltet, aber keine Daten"=Objekte. Dadurch kann der Cache das Ermitteln der Objekte
|
|
nicht optimieren.
|
|
|
|
Auf Grund dessen ist der \ac{EJB}"=Cache nicht für eine Performance"=Verbesserung nutzbar.
|
|
|
|
\section{Abfragen mit JPQL und Criteria API}
|
|
\label{sec:evaluation:jpal-capi}
|
|
|
|
Bei dem Vergleich zwischen den zwei Abfragemöglichkeiten der \ac{JPQL} und der Criteria API konnte in der Art der
|
|
Abfragen kein Unterschied festgestellt werden. Die Abfragen der beiden Systeme sind auf Datenbankseite komplett
|
|
identisch. Auch in der Übertragung der Daten aus der Datenbank in die Java"=Objekte konnte kein Unterschied in der
|
|
Art und Geschwindigkeit festgestellt werden.
|
|
|
|
Ebenfalls sind die Möglichkeiten der Optimierung durch die Hints identisch. In beiden Fällen haben die meisten Hints
|
|
keinen nennenswerten Einfluss auf die Laufzeit der Abfragen und Übertragung in die Java"=Objekte. Das sinnvolle Setzen
|
|
von OptimizeResultCount, der FetchSize sowie der FetchBatchSize hilft dem Framework die Bearbeitung der Anfrage
|
|
effizient abzuarbeiten, konnte aber in den gemessenen Laufzeiten nicht verifiziert werden.
|
|
|
|
Anders verhält sich dies mit der Einstellung für \texttt{EagerFetchMode}, welche definiert, wie die Daten für abhängige Klassen
|
|
ermittelt werden. Bei der Umstellung auf \textit{parallel} konnte für die Ermittlung der Dokumente einiges an Performance gewonnen
|
|
werden. Das liegt daran, dass nun für die abhängigen Objekte, wie den Koautoren, nicht pro Dokument eine Anfrage an die
|
|
Datenbank gestellt wird, sondern es werden alle Koautoren für die ermittelten Dokumente auf einmal ermittelt. Die
|
|
Zuordnung der Koautoren zu dem Dokument wird dann nun im Framework und nicht mehr durch die Datenbank durchgeführt.
|
|
Diese Abarbeitung reduziert viele einzelne Abfragen und somit auch den entsprechend Overhead im Framework.
|
|
|
|
Folglich ist die Entscheidung der Technik für die Performance irrelevant und es kann das genutzt werden, was für den
|
|
jeweiligen Einsatzzweck besser beziehungsweise einfacher zu programmieren ist. Das Setzen der richtigen Hints wiederrum
|
|
ist in beiden Fällen äußerst wichtig. Explizit bei der EagerFetchMode muss vorher darüber nachgedacht werden, wie viele
|
|
abhängige Objekttypen es zu dieser Klasse gibt, welche dazu geladen werden sollen und von welcher Anzahl an Objekte
|
|
ausgegangen werden kann. Gerade bei einer größeren Anzahl lohnt es sich den Hint auf \textit{parallel} zu setzen.
|
|
Gleiches gilt bei dem Hint \texttt{SubclassFetchMode}, dieser steuert dimensionierte Abfragen im Falle von
|
|
abgeleiteten Klassen.
|
|
|
|
\section{Materialized View}
|
|
\label{sec:evaluation:materialized-view}
|
|
|
|
Die Idee der \textit{Materialized View} ist simple, aber sehr effizient, gerade für einen Datenbestand, welcher häufig gelesen
|
|
und selten verändert wird. Hierbei werden komplexe Abfragen einmalig ausgeführt und das Ergebnis intern
|
|
zwischengespeichert. Für alle weiteren Aufrufe werden die Daten nun aus dem Zwischenspeicher gelesen und dem Aufrufer
|
|
zurückgegeben. Der größte Nachteil der \textit{Materialized View} ist, dass bei einer Änderung an den Quelldaten die
|
|
Sicht aktualisiert werden muss. Dieser Nachteil kommt in einer Briefedition nicht zum tragen, da in dieser nach dem die
|
|
Briefe einmalig eingepflegt wurden, nur noch selten Änderungen erfahren. Der Recherche zu dem Datenbestand wird die
|
|
meiste Zeit gewidmet.
|
|
|
|
Ein weiterer Nachteil der \textit{Materialized View} ist die doppelte Speicherung der Daten, da die Daten für die Sicht
|
|
wie bei einer Tabelle auf der Festplatte gespeichert sind. Dieser Nachteil ist in der Dokumentliste vernachlässigbar,
|
|
da sich die Daten auf die Meta"=Daten der Dokumente, wie Namen, Datum und Autoren beschränkt. Der größte Datenbestand,
|
|
die Faksimile, sind nicht in dieser Sicht enthalten und werden erst beim Anzeigen einer Kommunikation ermittelt.
|
|
Zusätzlich ist zu beachten, dass bei der Verwendung eines Caches die Daten ebenfalls doppelt gehalten werden und in
|
|
den meisten Fällen im Arbeitsspeicher gehalten werden.
|
|
|
|
Eine weitere Optimierung, welche durch die \textit{Materialized View} entstanden ist, ist die direkte Integration der
|
|
Autoren, der Koautoren und der Adressen im \textit{Json}"=Format. Durch diese aus dem Wedekind-Projekt übernommene Idee
|
|
konnten schon viele zusätzliche Abfragen eingespart werden, da diese nicht mehr durch OpenJPA nach der Hauptabfragen
|
|
für jede Datenzeile einzeln durchgeführt wird.
|
|
|
|
Zusätzlich konnte dies nochmal beschleunigt werden, in dem das Parsen der \textit{Json}"=Daten vom Server auf den Client
|
|
verlagert wurde. Hiermit konnte ein Teil der Last vom Server genommen und die gesamte Ausführungszeit nochmals
|
|
optimiert werden. Die Wandlung der Daten in \textit{\ac{HTML}}"=Objekte ist eine Kernkompetenz von JavaScript und damit auch bei
|
|
schwächeren Clients in kurzer Zeit durchführbar.
|
|
|
|
Als weiteren Punkt ist anzumerken, dass der Speicherbedarf des Webserver relativ konstant bleibt, ohne dass ein Cache
|
|
verwendet wird. Der größte Unterschied zur Standardimplementierung ist die Verwendung von eigenen Codes, um die Objekte
|
|
zu erstellen und zu befüllen und es nicht durch das OpenJPA"=Framework durchführen zu lassen.
|
|
Dies legt den Schluss nahe, dass Probleme in der Speicherverwaltung der Objekte im OpenJPA"=Framework existieren.
|
|
|
|
Zusammenfassend ist zu sagen, dass die \textit{Materialized View} eine gute Wahl ist, um die Listendarstellungen
|
|
zu optimieren. Mit dieser Technik können zum einen die Abfragezeiten optimiert werden, wodurch gleichzeit die
|
|
Ressourcennutzung verringert wird. Zum anderen wird die Ressourcennutzung des Servers noch weiter reduziert, wenn die
|
|
\textit{Json}"=Verarbeitung an den Client ausgelagert wird.
|
|
Durch die doppelte Datenhaltung muss bei jeder Abfrage geprüft werden, ob die Nutzung der \textit{Materialized View} sinnvoll
|
|
ist oder direkt auf denormalisierte Daten umgestellt werden sollte, weil der zusätzliche benötigte Speicher größer als
|
|
die Quelle ist.
|
|
Im Gegensatz zu einer reinen Cache"=Lösung, die die gleiche Optimierung besitzt, ist diese vorzuziehen, da in den
|
|
meisten Fällen der Festplattenspeicher kostengünstiger als der Arbeitsspeicher ist. Zusätzlich ist der Cache begrenzt
|
|
und wirft alte Objekte heraus. Wenn dieser voll ist wird ein Zugriff auf diese entfernten Objekte
|
|
langsamer. Somit ist die Optimierung über die \textit{Materialized View} auf lange Zeit gesehen kostengünstiger und
|
|
stabiler.
|
|
|
|
\section{Optimierung der Abfrage}
|
|
\label{sec:evaluation:optimize-query}
|
|
|
|
Die Abfragen, die durch die OpenJPA an die Datenbank abgesetzt werden, sind meist durch ihre Einfachheit gut optimiert.
|
|
Nur durch Sortierung oder Bedingungen können die Abfragen langsamer werden. Diese können durch entsprechende Indexe
|
|
gelöst werden. Bei größeren Abfragen mit mehreren Joins kann durch geschicktes umstellen die Performance verbessert
|
|
werden. Die Hauptabfrage der Dokumentenliste besteht aus mehreren Joins und diese wurde explizit untersucht.
|
|
|
|
Der Abfrageplan der Hauptabfrage wurde visuell untersucht und zeigt, dass das Hauptproblem die nicht eingeschränkte
|
|
Datenmenge der Haupttabelle \textit{document} ist. Dadurch werden die anderen Tabellen komplett geladen
|
|
anstatt die Zugriffe über die vorhandenen Indexe durchzuführen, obwohl die Bedingungen über die Primary Key definiert
|
|
sind. Für den PostgreSQL
|
|
ist es laut Berechnung kostengünstiger mit einem \textit{Seq Scan}, was einem kompletten Durchlaufen der Tabelle
|
|
entspricht, zu arbeiten.
|
|
|
|
Um dies zu optimieren, werden über eine \textit{Common Table Expression} zuerst die eingeschränkten Datenzeilen
|
|
ermittelt, diese mit der Haupttabelle verknüpft und anschließend die anderen Tabellen hinzugenommen. Hierdurch kann die
|
|
Zeilenanzahl während der Verarbeitung enorm verringert werden, wodurch einige der Verknüpfungen auf Indexzugriffe
|
|
umgestellt werden. Durch die Umstellung kann die Abfragezeit um mehr als das dreifache reduziert werden.
|
|
|
|
Mit dieser Art der Umstellung können Abfragen optimiert werden, die für das Paging verwendet werden und die Abfrage aus
|
|
mehrere Tabellen besteht. Das Wichtigste hierbei ist, dass die Bedingungen und die Sortierkriterien auf der
|
|
Haupttabelle arbeiten. Wenn dem nicht so ist, müssen Joins in die \textit{Common Table Expression} mit aufgenommen
|
|
werden und damit funktioniert die Reduzierung der Datensätze weniger effizient. Bei der Selektion einer Tabelle hat diese Art
|
|
der Optimierung keine Auswirkung, hier hilft nur das geschickte Setzen von Indexen auf die Tabelle, welche die
|
|
Bedingungen und die Sortierkriterien beinhalten. Dies wird mit der Untersuchung der Abfrage auf die
|
|
\textit{Materialized View} bestätigt.
|