Grundlagen erweitert

This commit is contained in:
Henrik Mertens 2022-06-19 15:00:04 +02:00
parent 73bb96add3
commit a19165fb37
9 changed files with 198 additions and 61 deletions

View file

@ -18,7 +18,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 11,
"id": "43cf5e5c-9542-47ea-9205-89f97a217c51",
"metadata": {},
"outputs": [],
@ -40,7 +40,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 12,
"id": "d6ae2ed0-3363-420f-81d5-56050591a50e",
"metadata": {},
"outputs": [],
@ -61,7 +61,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 13,
"id": "0a3d1adf-5c17-4aa6-8296-bd6bf0d78dc8",
"metadata": {},
"outputs": [],
@ -91,7 +91,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 14,
"id": "9015aa31-9bee-40db-b604-243c8f0b6ee9",
"metadata": {},
"outputs": [],
@ -109,7 +109,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 15,
"id": "7a557626-aaba-4ef4-8b4d-5ff2dd2840ef",
"metadata": {},
"outputs": [],
@ -136,7 +136,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 16,
"id": "59aaa184-b140-432d-8132-cbb179ce4543",
"metadata": {},
"outputs": [],
@ -154,7 +154,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 17,
"id": "cb28ce0d-5d9f-4090-a136-6fa7c8787974",
"metadata": {},
"outputs": [],
@ -176,7 +176,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 18,
"id": "34975883-fa02-469f-8a2a-cc3464ae6c92",
"metadata": {},
"outputs": [],
@ -194,7 +194,7 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 19,
"id": "1c689c54-8215-41e3-97ca-6b6eed76d0fc",
"metadata": {},
"outputs": [
@ -214,6 +214,14 @@
"\n",
"print(results)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ed16d014-5e16-4401-848f-8b6c44c45b83",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {

View file

@ -13,7 +13,7 @@ services:
RESTARTABLE: "yes"
influxdb:
image: influxdb
image: influxdb:2.2
ports:
- 8086:8086
environment:

Binary file not shown.

View file

@ -17,6 +17,76 @@
% \item Hier könnte eine wichtige Gesprächsnotiz stehen
%\end{compactitem}
\anhang{InfluxDB Python Code}
\begin{figure}[bht]
\lstset{numbers=left, numberstyle=\tiny, stepnumber=1, numbersep=5pt}
\begin{lstlisting}[caption=InfluxDB Python Daten schreiben {Quelle: \cite[][]{InfluxAPIPythonClient}}, firstnumber=1, label=list:influxPythonWrite, language=Python],
import influxdb_client
from influxdb_client.client.write_api import SYNCHRONOUS
bucket = "<my-bucket>"
org = "<my-org>"
token = "<my-token>"
url="http://influxdb:8086"
client = influxdb_client.InfluxDBClient(
url=url,
token=token,
org=org
)
write_api = client.write_api(write_options=SYNCHRONOUS)
p = influxdb_client.Point("my_measurement")
.tag("location", "Paderborn")
.field("temperature", 25.3)
write_api.write(bucket=bucket, org=org, record=p)
\end{lstlisting}
\end{figure}
\begin{figure}[bht]
\lstset{
numbers=left,
numberstyle=\tiny,
stepnumber=1,
numbersep=5pt,
}
\begin{lstlisting}[caption=InfluxDB Python Daten lesen {Quelle: \cite[][]{InfluxAPIPythonClient}}, firstnumber=1, label=list:influxPythonRead, language=Python],
query_api = client.query_api()
query = 'from(bucket:"my-bucket")\
|> range(start: -10m)\
|> filter(fn:(r) => r._measurement == "my_measurement")\
|> filter(fn: (r) => r.location == "Prague")\
|> filter(fn:(r) => r._field == "temperature" )'
result = query_api.query(org=org, query=query)
results = []
for table in result:
for record in table.records:
results.append((record.get_field(), record.get_value()))
print(results)
[(temperature, 25.3)]
\end{lstlisting}
\end{figure}
\clearpage %Damit die Bilder richtig positioniert sind.
\anhang{Times Seires DB Rangliste}
\begin{figure}[hbt]
\centering
\begin{minipage}[t]{0.9\textwidth} % Breite, z.B. 1\textwidth
\caption{DB-Engines Ranking} % Überschrift
\includegraphics[width=1\textwidth]{img/DB-Engines-Ranking} % Pfad
\source{https://db-engines.com/de/ranking?msclkid=4f2a29e5d08811ec95ccd74f8f5146ab} % Quelle
\label{fig:db-ranking}
\end{minipage}
\end{figure}
\clearpage %Damit die Bilder richtig positioniert sind.
\anhang{InfluxDB Webinterface Screenshot}
\begin{figure}[hbt]
@ -86,4 +156,4 @@
%Stations_id von_datum bis_datum Stationshoehe geoBreite geoLaenge Stationsname Bundesland
%----------- --------- --------- ------------- --------- --------- ----------------------------------------- ----------
%\end{lstlisting}
%\end{figure}
%\end{figure}

View file

@ -3,13 +3,21 @@
\subsection{Zielsetzung}
Das Ziel dieser Arbeit ist es eine Einführung in die Funktion von \gls{TSDB} zu geben.
Außerdem soll beispielhaft an InfluxDB gezeigt werden, wie mit einer \gls{TSDB} gearbeitet wird.
Dazu werden die Wetterdaten des \glspl{DWD} in InfluxDB importiert und ausgewertet.
Das Ziel dieser Arbeit ist es eine Einführung in die Funktion von \gls{TSDB} zu geben. Dazu wird
beispielhaft an den Temperaturdaten des \glspl{DWD} gezeigt wie einer \gls{TSDB} gearbeitet werden kann.
Als Datenbank wird InfluxDB genutzt.
\subsection{Aufbau und Vorgehensweise}
Im ersten Teil dieser Arbeit werden die Grundlagen von \gls{TSDB} erklärt und Besonderheiten beschreiben.
Im darauf folgenden Kapitel wird dann exemplarisch an InfluxDB gezeigt, wie mit einer \gls{TSDB} gearbeitet wird. Im
letzten Kapitel werden die Inhalte dieser Arbeit zusammengefasst.
Im Grundlagenteil dieser Arbeit werden die Grundlagen von Time Series Data und \gls{TSDB} erläutert.
Des Weiteren wird erklärt was eine \gls{TSDB} ist und wie diese sich von \gls{RDBMS} unterscheidet.
Außerdem wird kurz die für die Entwicklungsumgebung notwendige Software Docker und jupyter Notebooks
erklärt.
Im nächsten Kapitel wird gezeigt wie mit InfluxDB gearbeitet werden kann. Dazu wird das für InfluxDB
wichtige Line Protokoll vorgestellt. Außerdem wird gezeigt wie die abgerufenen Daten mit InfluxDB
visualisiert werden können. Als Daten werden die Wetterdaten das \gls{DWD} genutzt welche auch in diesem
Kapitel erklärt und vorstellt werden.
Im letzten Artikel folgt eine kurze Zusammenfassung der Arbeit und der wichtigsten Informationen
zu \gls{TSDB}

View file

@ -1,6 +1,7 @@
%!TEX root = ../Thesis.tex
\section{Grundlagen}
In diesem Kapitel werden die Grundlagen von \gls{TSDB} und Time Series Data erklärt.
\gls{TSDB} gehören zu den NoSQL Datenbanken und sind besonders darauf optimiert, mit Time Series Data zu
arbeiten. Dadurch können die große Mengen an
Time Series Data verarbeiten, durchsuchen und speichern.\footnote{\cite[vgl.][]{ComputerWeekly}}
@ -13,62 +14,56 @@ sonder die Veränderung über einen Zeitraum. Diese Daten können z.B. Servermet
Netzwerkdaten, \gls{IOT} Sensordaten, Ereignisse, Klicks, Marktgeschäfte und viele andere Arten von Daten sein.
Time Series Data können gut daran erkannt werden, dass die Zeit eine wichtige Achse bei der Darstellung der Werte ist.\footnote{\cite[vgl.][1\psqq]{PaulDix}}
Manchmal ist es nicht notwendig, alle Daten zu erfassen. Zum Beispiel wird in vielen Anwendungen nur der letze Login gespeichert. Mehr ist auch für die
Funktion nicht notwendig. Allerdings können zusätzliche Informationen gewonnen werden, wenn nicht nur die letzen Daten sondern die Veränderung aufgezeichnet wird.
Manchmal ist es nicht notwendig, alle Daten zu erfassen. Zum Beispiel wird in vielen Anwendungen nur der letze Login gespeichert.
Mehr ist auch für die Funktion nicht notwendig. Allerdings können zusätzliche Informationen gewonnen werden, wenn nicht
nur der letze Datenpunkt sondern die Veränderung über einen Zeitraum aufgezeichnet wird.
So kann zum Beispiel festgestellt werden, wie oft und wann sich der Kunde einloggt und ob es dabei ein Muster gibt. Anhand dieser Daten können Kunden
dann kategorisiert werden.\footnote{\cite[vgl.][]{DataScienceTeam2020}}
Eine Besonderheit von Time Series Data ist, dass sie sich nicht verändert. Wenn die Daten einmal erfasst wurden wird an ihnen nichts mehr verändert.
Eine weitere Besonderheit von Time Series Data ist, dass sie sich nicht verändert. Wenn die Daten einmal erfasst wurden wird an ihnen nichts mehr verändert.
Es werden nur neue Daten hinzugefügt.\footnote{\cite[vgl.][]{SamFangman2019}}
%
%\subsection{{Funktionen von Time Series Database}}
%
%Um mit Time Series Data arbeiten zu können sind für eine \gls{TSDB} enige wichtige FUnktionen notwendig. Die wichtigesten Funktionen einer
%\gls{TSDB} ist es Time Series Data zu speichern. Hier muss
%
%
%hese include time-stamp data storage and compression, data lifecycle management, data summarization,
%ability to handle large time series dependent scans of many records, and time series aware queries.
%
%Im Aufbau unterscheiden sich \gls{TSDB} vorallendingen darin das sie nur dazu
\subsection{{Aufbau von Time Series Datenbanken}}
\gls{TSDB} sind darauf ausgelegt Key Value paare zu Speichern. Der Key in einem Key Value Datensatz ist eine
Wert über den die Value referenziert wird. Im Value Teil werden die Daten zum dazugehörigem Key gespeichert.
Der Wert der Value kann ein primitiver Datentyp sein oder auch ein Objekt das in einen primitiven Datentyp
umgewandelt worden ist.
\footnote{\cite[vgl.][]{Key-Value}}
Ein Datenpunkt in einer Time Series Database besteht aus mehreren key Value Paaren. Einige Dieser Key Value Paare sind sogenannte Tags.
Diese Tags sind Werte die sich zwischen den Datenpunkten nicht ändern wie zum Beispiel die Position eines Sensors oder die Kundenummer
eines Kunden der sich gerade eingeloggt hat. Anhand dieser Tags können die Datenpunkte durchsucht werden. Die eigentlichen Messwerte
des Sensors oder andere Daten die erfasst werden sollen werden auch als Key Value Paar gespeichert. Zum Beispiel wird als Name
Temperatur und als Wert 25,2 angeben. Ein Datenpunkt kann mehrere Messwerte haben. Außerdem wird jeder Datenpunkt mit einem Timestamp
versehen nach welchem er Indexiert wird.\footnote{\cite[vgl.][]{hazelcast}} Eine gute Veranschaulichung wie die Daten in einer \gls{TSDB} aufgebaut sind zeigt das InfluxDB
Line Protokoll in \cref{list:lineproto}.
%https://hazelcast.com/glossary/time-series-database/
\subsection{{Unterschiede zwischen Time Series und relationalen Datenbanken}}
%Umschreiben und andere Quellen verwenden
Um Time Series Data zu speichern, ist es nicht unbedingt erforderlich, eine \gls{TSDB} zu nutzen. Auch relationale Datenbanken können Time Series
Data speichern. Einer der wichtigsten Unterschiede zwischen einer \gls{TSDB} im Gegensatz zu einem \gls{RDBMS} ist es, dass kein Datenbank Schema notwendig ist.
Data speichern. Einer der wichtigsten Unterschiede zwischen einer \gls{TSDB} im Gegensatz zu einem \gls{RDBMS} ist es, dass kein Datenbank Schema benötigt wird.
Wenn Time Series Daten in einer Rationalen Datenbank geschrieben werden sollen, müssen erst entsprechende Tabellen angelegt werden, in denen die Daten immer im
gleichen Format abgelegt werden müssen. Im Gegensatz dazu können in einer \gls{TSDB} die Daten einfach schemafrei in die Datenbank geschrieben werden. Ein
weiterer Vorteil ist, dass \gls{TSDB} im Gegensatz zu relationalen Datenbanken besser und einfacher Skaliert werden
können.\footnote{\cite[vgl.][]{InfluxDataSQL}}
Aber \gls{TSDB} haben nicht nur Vorteile. Wie in \cref{fig:db-ranking} zu sehen, sind sie viel weniger verbreitet als nicht zeit basierte Datenbank Systeme. Dadurch gibt
es viel weniger Entwickler die sich mit \gls{TSDB} auskennen und auch das Ökosystem um die Datenbank ist deutlich kleiner. Außerdem sind \gls{RDBMS}
es viel weniger Entwickler die Erfahrungen mit \gls{TSDB} haben. Auch auch das Ökosystem um die Datenbank ist deutlich kleiner. Außerdem sind \gls{RDBMS}
dadurch, dass es sie viel länger gibt, sehr stabil und sehr gut unterstützt.\footnote{\cite[vgl.][]{InfluxDataSQL}}
\gls{RDBMS} arbeiten nach dem \gls{CRUD} Prinzip, welches für Time Series Data nicht optimal ist. Auf Time Seires Data werden keine Update Befehle durchgeführt, da
neue Daten immer nur als neuer Datenpunkt angehängt werden. Auch das Löschen von Daten wird nicht sehr häufig durchgeführt und im Gegensatz zu \gls{RDBMS}
meistens gleichzeitig auf einer großen Menge an Datensätzen. Daher sind \gls{TSDB} besser dafür geeignet, mit Time Series Data zu arbeiten und weisen auch eine
\gls{RDBMS} arbeiten nach dem \gls{CRUD} Prinzip, welches für Time Series Data nicht optimal ist. Auf Time Series Data werden keine Update Befehle durchgeführt, da
neue Daten immer nur angehängt werden. Auch das Löschen von Daten wird nicht sehr häufig durchgeführt und im Gegensatz zu \gls{RDBMS}
meistens gleichzeitig auf einer großen Menge an Datensätzen. \gls{TSDB} sind auf diese Besonderheiten optimiert und daher besser dafür geeignet, mit Time Series Data zu arbeiten und weisen auch eine
höhere Performance auf.\footnote{\cite[vgl.][]{InfluxDataSQL}}
\subsection{Verbreitete DBMS}
Aktuell gibt es wie in \cref{fig:db-ranking} zu sehen, einige beliebte Mulit-Model Datenbanken, die als \gls{TSDB} genutzt werden können.
So können die Datenbanken MongoDB, Redis, Teradata und Couchbase mit Time Series Daten arbeiten. Die erste reine \gls{TSDB} im Ranking ist InfluxDB
So können die Datenbanken wie MongoDB, Redis, Teradata und Couchbase mit Time Series Daten arbeiten. Die erste reine \gls{TSDB} im Ranking ist InfluxDB
auf Platz 29.\footnote{\cite[vgl.][]{dbranking}}
% Wenn ich zu viele Seiten habe kommt das Bild in den Anhang
\begin{figure}[hbt]
\centering
\begin{minipage}[t]{0.9\textwidth} % Breite, z.B. 1\textwidth
\caption{DB-Engines Ranking} % Überschrift
\includegraphics[width=1\textwidth]{img/DB-Engines-Ranking} % Pfad
\source{https://db-engines.com/de/ranking?msclkid=4f2a29e5d08811ec95ccd74f8f5146ab} % Quelle
\label{fig:db-ranking}
\end{minipage}
\end{figure}
Allerdings haben Datenbanken, die nur auf das verarbeiten von Time Series Data ausgelegt sind, deutliche Performance Vorteile
gegenüber Multi Model Datenbanken. In einem Vergleich von InfluxDB und MongoDB, hat InfluxDB eine 2,4 mal bessere
Schreibperformance als MongoDB und ist beim Lesen sogar 5,7 mal schneller. InfluxDB benötigt außerdem 20 mal weniger

View file

@ -11,7 +11,7 @@ eigene Anwendungen ein \gls{HTTP} \gls{API} zur Verfügung, für die es in viele
Bevor InfluxDB genutzt werden kann muss es als erstes installiert werden. Am einfachsten ist dies über Docker möglich. Dazu ist es notwendig das Docker und Docker Compose auf dem System installiert sind.
Mit Docker Desktop lassen sich die beide Tools am einfachsten installieren. Im Anhang dieser Arbeit befindet sich im Ordner Docker eine Docker Compose Datei mit dem Namen docker-compose.yml.
Zum Starten der benötigten Container ist es am einfachsten mit einem Terminal (Powershell, xterm usw.) in den Docker Ordner zu wechseln und den Befehl docker compose up -d auszuführen.
Jetzt beginnt docker damit die notwendigen Images herunterzuladen und zu bauen. Wenn der Befehl erfolgreich ausgeführt worden ist InfluxDB erfolgreich installiert worden und kann
Jetzt beginnt docker damit die notwendigen Images herunterzuladen und zu bauen. Wenn der Befehl ohne Fehler ausgeführt worden ist InfluxDB installiert worden und kann
über die URL:\ \url{http://localhost:8086} aufgerufen werden. Die Login Daten sind als Umgebungsvariable in Docker Compose definiert und lauten: admin e1LjSYaFbzbJeIBC.
Außerdem wurde mit diesem Befehl auch ein Jupyter Notebook in einem Docker Container gestartet. Auf diesen Container kann über die URL:\ \url{http://localhost:8888/}
@ -26,7 +26,7 @@ Lebensdauer für die Daten ausgewählt werden, nach welcher die jeweiligen Daten
\subsubsection{Line Protokoll}
Daten werden immer nach dem InfluxDB Line Protokoll formatiert an die Datenbank gesendet. Das Protokoll ist wie in Listing~\ref{list:lineproto}
Daten werden immer nach dem InfluxDB Line Protokoll formatiert an die Datenbank gesendet. Das Protokoll ist wie in \cref{list:lineproto}
dargestellt aufgebaut. Im ersten Teil des Line Protokolls wird der Name der Messreihe angegeben. Das kann zum Beispiel der Name des Sensors sein oder
der Ort an dem der Messwert genommen wurde. Wichtig ist, dass Groß und Kleinschreibung beachtet werden muss und Unterstriche nicht
genutzt werden dürfen. Sonderzeichen müssen mit einem \textbackslash \ %Bachslash mit Leerzeichen
@ -55,17 +55,34 @@ Um einen Token zu bekommen, kann dieser entweder über das Webinterface, die \gl
den Token über das Webinterface anzulegen. Dazu wird wie beim Anlegen eines Buckets zunächst der Menüpunkt Data ausgewählt und anschließend der Reiter API
Tokens. Mit einem Klick auf Generate API Token kann dann ein API Token erstellt werden.\footnote{vgl. \cref{fig:dashboard}, \cref{fig:load-data-source}, \cref{fig:load-data-api-token}, \cref{fig:load-data-add-token}}
Dabei kann zwischen einem All-Access token und einem Read/Write token ausgewählt werden. Mit dem All Access Token kann auf alles zugegriffen werden.
Mit einem Read/Write Token kann wie in \cref{fig:load-data-add-token} zu sehen, ausgewählt werden, auf welchen Bucket geschrieben oder gelesen werden kann.
\footnote{\cite[vgl.][]{InfluxDBToken}}
\subsubsection{Python library}
%https://docs.influxdata.com/influxdb/cloud/security/tokens/#all-access-token
Mit einem Read/Write Token kann wie in \cref{fig:load-data-add-token} zu sehen, ausgewählt werden, auf welchen Bucket geschrieben oder gelesen werden kann.\footnote{\cite[vgl.][]{InfluxDBToken}}
\subsection{{Daten abrufen}}
%InfluxDB QUerrys
%InfluxDB QUerrys Flux
\subsection{Python library}
Um nicht selbst eigene API Anfragen über die Rest API schreiben zu müssen gibt es für Python und andere Sprachen fertige
Bibliotheken.\footnote{\cite[vgl.][]{InfluxAPIClientLibs}} Bevor mit der Client Library gearbeitet werden kann muss diese als erste
Installiert und importiert werden. Am besten wird zur Installation der Python Paketmanager pip genutzt. Mit dem Befehl pip install influxdb-client
werden alle benötigten Packte installiert.
In \cref{list:influxPythonWrite} kann an einem Beispiel gesehen werden wie Daten mithilfe von Python in die Datenbank geschrieben
werden. Ein ähnliches Beispiel findet sich ausführbar und detailliert beschreiben im Jupyter Notebook. In der ersten beiden
Zeile des Codes wird der InfluxDB Client importiert. Danach werden in Zeile vier bis sieben die benötigten Daten bucket,
Organisation, Token und URL in Variablen geschrieben. Was in die Variablen eingetragen werden muss wird im
Kapitel Daten einfügen %eventuell Link einfügen?
beschreiben.
In Zeile neun bis 13 wird der Client mit den hinterlegen Variablen initialisiert. Danach folgt in Zeile 15 die
Initialisierung des write clients. Als nächstes muss ein Datenbank erstellt werden der in die Datenbank geschrieben werden kann.
Dazu wird in Zeile 17 bis 19 der Datenpunkt erstellt. An diesen Datenpunkt kann eine beliebige Menge an Tags und Datenfeldern
über die Methoden tag und field angehängt werden. Hier im Beispiel wird der Datenpunkt my\_measurement mit dem Tag location angelegt,
welcher den Wert Paderborn hat, und dem Datenpunkt temperature mit dem Wert 25,3 angelegt. In der letzten Zeile wird dann
der write client dazu genutzt um diesen Datenbank an die Datenbank zu senden.
\subsection{{Daten verarbeiten und visualisieren}}

View file

@ -67,6 +67,24 @@ year = {2022},
keywords = {web}
}
@misc{InfluxAPIPythonClient,
author = {Influxdata},
title = {{Python client library}},
url = {https://docs.influxdata.com/influxdb/v2.2/api-guide/client-libraries/python/},
urldate = {2022-06-18},
year = {2022},
keywords = {web}
}
@misc{InfluxAPIClientLibs,
author = {Influxdata},
title = {{Use InfluxDB client libraries}},
url = {https://docs.influxdata.com/influxdb/v2.2/api-guide/client-libraries/},
urldate = {2022-06-18},
year = {2022},
keywords = {web}
}
@misc{InfluxDBToken,
author = {Influxdata},
title = {{Manage API tokens}},
@ -76,7 +94,6 @@ year = {2022},
keywords = {web}
}
@misc{InfluxDBLineProtolkoll,
author = {Influxdata},
title = {{Line protocol}},
@ -157,3 +174,25 @@ urldate = {2022-05-10},
year = {2022},
keywords = {web}
}
@misc{Key-Value,
author = {Marc Seeger},
publisher = {Computer Science and Media},
title = {{Key-Value stores: a practical overview}},
url = {http://blog.marc-seeger.de/assets/papers/Ultra_Large_Sites_SS09-Seeger_Key_Value_Stores.pdf},
urldate = {2022-06-19},
year = {2009},
keywords = {web}
} %Ist das eine Internetqulle oder ein Magazin?
@misc{hazelcast,
author = {hazelcast},
title = {{Time Series Database}},
url = {https://hazelcast.com/glossary/time-series-database/},
urldate = {2022-05-10},
year = {2022},
keywords = {web}
}