bachelor-thesis/chapters/thesis/chapter04.tex

157 lines
9.5 KiB
TeX
Raw Normal View History

2024-07-31 22:12:53 +02:00
% !TeX root = ../../thesis.tex
\chapter{Performance-Untersuchung}
\label{ch:performance-checking}
2024-09-15 00:47:49 +02:00
Für die Untersuchung der Performance"=Probleme sollten einige Vorbereitungen getroffen werden. Dazu gehören die
2024-09-26 23:43:15 +02:00
Konfigurationen des Servers und in welcher Art und Umfang Anpassungen für die Performance"=Messungen an der Software
2024-09-15 00:47:49 +02:00
durchgeführt werden müssen. Hierbei ist zu beachten, dass die Anpassungen minimal sind, damit die Messung selbst nicht
das Ergebnis verfälscht. Zum Abschluss wird noch auf die Untersuchung der Abfragen eingegangen, wie diese im
PostgreSQL"=Server durchgeführt wird.
2024-04-02 22:10:08 +02:00
2024-09-15 00:47:49 +02:00
\section{Überprüfung des Servers}
\label{sec:performance-checking:server-checking}
2024-09-15 00:47:49 +02:00
Die einfachste Art die Einstellungen am PostgreSQL"=Server zu überprüfen, ist die Abfrage von
\ref{lst:postgresql-select-settings} am Datenbankserver auszuführen.
2024-09-12 23:02:22 +02:00
\begin{lstlisting}[language=SQL,caption={Ermitteln der PostgreSQL Einstellungen},label=lst:postgresql-select-settings]
SELECT name AS setting_name
, setting AS setting_value
, unit AS setting_unit
FROM pg_settings
WHERE name IN (
'shared_buffers'
, 'temp_buffers'
, 'work_mem'
, 'max_connections'
, 'maintenance_work_mem'
2024-09-15 00:47:49 +02:00
, 'autovacuum'
2024-09-12 23:02:22 +02:00
)
\end{lstlisting}
2024-09-15 00:47:49 +02:00
Zusätzlich sollte noch die aktuelle Auslastung des Server überprüft werden.
Als Server wird hier ein Redhat"=Server mit der Standard"=Konfiguration des PostgreSQL"=Server 10 verwendet. Daher
wird von einer richtigen Konfiguration der Speicher ausgegangen. Ebenfalls wird davon ausgegangen, dass der
2024-09-26 23:43:15 +02:00
automatische Dienst für \texttt{VACUUM} und \texttt{ANALYZE} aktiv ist. Eine weitere Überprüfung des Servers ist nicht
2024-09-15 00:47:49 +02:00
möglich, da kein Zugang zum aktuellen Produktionsservers möglich ist.
\section{Einbau und Aktivieren von Performance-Messung}
\label{sec:performance-checking:performance-measure}
2024-08-31 00:09:15 +02:00
Um eine Messung der Performance in der Webseite durchführen zu können, gibt es in \ac{JSF} die Möglichkeit, über eine
2024-09-26 23:43:15 +02:00
eigene Implementierung der Klasse \texttt{ViewDeclarationLanguageWrapper} sich in das Generieren der Webseite
einzuhängen. Hierbei können die Funktionen für das Erstellen, das Bauen und das Rendern der Webseite überschrieben
2024-09-01 23:06:28 +02:00
werden. In den überschriebenen Funktionen werden nun Laufzeiten gemessen und die ermittelten Zeiten mit einer Kennung
2024-09-28 13:33:24 +02:00
in die Log"=Datei eingetragen. Durch die Kennung können die Zeiten im Nachgang über ein Script ermittelt und
2024-09-01 23:06:28 +02:00
ausgewertet werden.
2024-08-31 00:09:15 +02:00
2024-09-26 23:43:15 +02:00
Zusätzlich wird noch eine Implementierung der zugehörigen Factory"=Klasse \texttt{ViewDeclarationLanguageFactory}
2024-09-29 11:02:28 +02:00
benötigt. Durch diese Factory"=Klasse wird der eigentlichen Wrapper mit der Performance"=Messung in die Bearbeitungsschicht
2024-09-26 23:43:15 +02:00
eingehängt. Diese Implementierung wird dann noch in der \texttt{faces-config.xml} eingetragen, wie das in
2024-09-27 20:58:59 +02:00
\autoref{lst:activate-factory} aufgezeigt wird, damit die Factory durch das System aufgerufen wird.
2024-08-31 00:09:15 +02:00
\begin{lstlisting}[language=xml,caption={Einbindung Factory},label=lst:activate-factory]
<factory>
<view-declaration-language-factory>
de.wedekind.utils.VdlLoggerFactory
</view-declaration-language-factory>
</factor>
\end{lstlisting}
2024-09-27 20:58:59 +02:00
Der Quellcode der Klassen ist in \autoref{ap:jsf_performance_measure} zu finden.
2024-09-08 00:33:09 +02:00
2024-09-27 20:58:59 +02:00
Um die Abfragen im \textit{PostgreSQL} untersuchen zu können, ist es am einfachsten, wenn man die Konfiguration so
2024-09-15 00:47:49 +02:00
anpasst, dass alle Abfragen mit entsprechenden Zeitmessungen in die Log"=Datei ausgegeben werden.
Über die Einstellungen in \autoref{lst:postgresql_logfile} wird die Datei und das Format der Ausgabe definiert.
2024-09-08 00:33:09 +02:00
\begin{lstlisting}[language=yaml,caption={PostgreSQL Dateikonfiguration},label=lst:postgresql_logfile]
log_destination = 'jsonlog'
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_file_mode = 0640
log_rotation_size = 100MB
\end{lstlisting}
2024-09-15 00:47:49 +02:00
Über die Konfiguration unter \autoref{lst:postgresql_logconf} wird definiert welche Werte protokolliert werden. Die
2024-09-26 23:43:15 +02:00
wichtigste Einstellung ist \texttt{log\_min\_duration\_statement}, diese definiert, ab welcher Laufzeit eine Abfrage
2024-09-28 21:50:12 +02:00
protokolliert werden soll. Mit dem Wert 0 werden alle Abfragen protokolliert. Alle weiteren Einstellungen sind so
2024-09-29 11:02:28 +02:00
gesetzt, dass nur notwendige Abfragen für die spätere Auswertung mit \textit{pgBadger} protokolliert werden.
2024-09-26 23:43:15 +02:00
Zusätzlich ist die Einstellung \texttt{log\_temp\_files} auf 0 zu setzen, dadurch werden alle erzeugten temporären
2024-09-12 23:02:22 +02:00
Dateien und ihre Größe ebenfalls protokolliert. Diese Dateien entstehen, wenn der temporäre Puffer für die Abfrage
nicht ausreicht und die Zwischenergebnisse ausgelagert werden müssen.
2024-09-08 00:33:09 +02:00
\begin{lstlisting}[language=yaml,caption={PostgreSQL Ausgabekonfiguration},label=lst:postgresql_logconf]
log_min_duration_statement = 0
log_autovacuum_min_duration = 10
log_checkpoints = off
log_connections = on
log_disconnections = on
log_disconnections = on
log_duration = off
log_error_verbosity = default
log_hostname = on
log_lock_waits = on
log_statement = 'none'
2024-09-12 23:02:22 +02:00
log_temp_files = 0
2024-09-08 00:33:09 +02:00
log_timezone = 'Europe/Berlin'
\end{lstlisting}
2024-09-15 00:47:49 +02:00
\section{Prüfung von Abfragen}
\label{sec:performance-checking:sql-query-checking}
2024-09-29 11:02:28 +02:00
Das Untersuchen der protokollierten Abfragen auf Performance"=Optimierungen ist ein weiterer Bestandteil dieser Arbeit.
2024-09-26 23:43:15 +02:00
Das Schlüsselwort \texttt{EXPLAIN} ist im PostgreSQL vorhanden, um den Abfrageplan einer Abfrage zu ermitteln und
2024-09-27 20:58:59 +02:00
darzustellen, um diese anschließend zu untersuchen. Der Abfrageplan ist als Baum dargestellt, bei welchem die Knoten die
2024-09-26 23:43:15 +02:00
unterschiedlichen Zugriffsarten darstellen. Die Verbindung der Knoten und der Aufbau zeigt die Operationen, wie
2024-09-28 13:33:24 +02:00
etwa Joins, Aggregierung und Sortierung, und die Reihenfolgen der Abarbeitung. Zusätzlich sind auch Zwischenschritte
2024-09-15 00:47:49 +02:00
wie Zwischenspeicherungen ersichtlich. Zu jeder Operation gibt es neben dem Typ noch zusätzliche Informationen, wie
die geschätzten Anlauf"= und Gesamtkosten (\textit{costs}), die geschätzte Anzahl der Zeilen (\textit{rows}) und die
geschätzte Breite jeder Zeile (\textit{width}). Der Wert von \textit{costs} wird bei übergeordneten Knoten summiert.
2024-09-28 13:33:24 +02:00
Bei der Option \texttt{ANALYZE} wird die Abfrage ausgeführt und die echten Werte und Laufzeiten angezeigt. Ohne diese
2024-09-26 23:43:15 +02:00
wird nur der Plan erstellt und dargestellt. Durch \texttt{VERBOSE} wird der Abfrageplan um zusätzliche Informationen
angereichert. Die Option \texttt{BUFFERS} erweitert die Informationen über die Nutzung der Caches. Für eine
2024-09-28 21:50:12 +02:00
Zusammenfassung am Ende des Abfrageplans, gibt es die Option \texttt{SUMMARY}. Eine vereinfachte Form des Aufrufs
2024-09-15 00:47:49 +02:00
ist in \autoref{lst:explain-easy} dargestellt.
\begin{lstlisting}[language=SQL,caption={Aufruf von EXPLAIN},label=lst:explain-easy]
EXPLAIN (ANALYZE, VERBOSE, BUFFERS, SUMMARY)
select * from document;
\end{lstlisting}
2024-09-27 20:58:59 +02:00
Die zwei bekanntesten Knotentypen sind \texttt{Seq Scan} und \texttt{Index Scan}. Wenn eine Tabelle Zeile für Zeile
gelesen wird, zeigt der Abfrageplan einen \texttt{Seq Scan}"=Knoten an. Hierbei entsteht, unabhängig davon ob eine
2024-09-28 13:33:24 +02:00
Bedingung zum filtern vorhanden ist, eine unsortierte Liste, deren Startkosten entsprechend niedrig sind. Je weiter die
2024-09-26 23:43:15 +02:00
Liste durchlaufen wird, desto höher steigen die notwendigen Kosten. Die kostengünstigere Alternative ist der
\texttt{Index Scan}, bei dem der Index nach den Kriterien durchsucht wird, was meist durch den Aufbau des Index als
BTree (Multi"=Way Balanced Tree) rapide geht.
2024-09-15 00:47:49 +02:00
2024-09-27 20:58:59 +02:00
Eine weitere Optimierungsmöglichkeit ist die Verwendung von Indexen. Diese sind aber mit Bedacht zu wählen, da bei
2024-09-28 13:33:24 +02:00
mehreren Indexen, die sehr ähnlich sind, nicht immer der gewünschte Index bei der Abfrage verwendet wird. Auch bedeutet
2024-09-27 20:58:59 +02:00
ein Index bei jeder Änderung der Daten zusätzliche Arbeit, da dieser entsprechend mit gepflegt werden muss und ebenso
2024-09-26 23:43:15 +02:00
dessen Statistik muss regelmässig aktualisiert werden. Ebenfalls ist die Reihenfolge der Spalte in einem
2024-09-15 00:47:49 +02:00
zusammengesetzten Index von Bedeutung. Als Grundlage sollte hier mit der Spalte gestartet werden, welche die größte
Einschränkung durchführt. Zusätzlich muss die Art des Index definiert werden, welche davon abhängig ist, mit welcher
Vergleichsoperation auf die Tabellenspalte zugegriffen wird.
2024-09-26 23:43:15 +02:00
Um größere und aufwendigere Abfragen zu optimieren, bietet der PostgreSQL noch die Möglichkeit von
2024-09-27 20:58:59 +02:00
\textit{Materialized View}. Diese sind sehr ähnlich zu den Sichten, zusätzlich werden aber die Ergebnisse in einer
tabellenähnlichen Form abgespeichert, somit sind die Zugriff auf diese Daten häufig performanter als die eigentliche Abfrage.
2024-09-29 11:02:28 +02:00
Daher muss abgewägt werden, ob die Performance"=Verbesserung trotz der zusätzlichen Aktualisierung des Datenbestandes
2024-09-26 23:43:15 +02:00
als sinnvoll erachtet werden kann.
2024-09-15 00:47:49 +02:00
2024-09-29 11:02:28 +02:00
Zusätzlich können über die Systemtabelle \texttt{pg\_statistic} oder die lesbarere Systemsicht \texttt{pg\_stats} die
2024-09-28 21:50:12 +02:00
aktuellen statistischen Informationen über eine Tabelle und deren Spalten ermittelt werden. In dieser Tabelle werden
2024-09-26 23:43:15 +02:00
durch das \texttt{ANALYZE} beziehungsweise \texttt{VACUUM ANALYZE} Kommando die Informationen zum Anteil der
2024-09-28 13:33:24 +02:00
\texttt{NULL}"=Werte (null\_frac), durchschnittlichen Größe (avg\_width), unterschiedlicher Werte (n\_distinct) und
2024-09-24 00:08:33 +02:00
weitere gesammelt und für die Erstellung der Abfragepläne verwendet \citep{PostgreS39:online}. Diese Information
sollte vor dem erstellen eines Index betrachtet werden.
2024-09-15 00:47:49 +02:00
2024-09-29 11:02:28 +02:00
Durch das Kommando \texttt{CREATE STATISTICS} können diese Informationen erweitert werden, um das Erstellen des Abfrageplans
2024-09-28 21:50:12 +02:00
zu verbessern. Das Aktivieren der zusätzlichen Statistiken sollte immer in Verbindung mit der Überprüfung des
2024-09-26 23:43:15 +02:00
Abfrageplans durchgeführt werden, um zu ermitteln inwieweit die Anpassung zu einer Optimierung und keiner
Verschlechterung führt.