\chapter{Prehľad databázových systémov}\label{chp:db_overview}

V~nasledujúcej kapitole popisujem existujúce databázové systémy, ktoré by mohli
byť použité vo~výslednom systéme, ich vlastnosti a~výhody, či prekážky pri~ich
použití.

\section{InfluxDB}

InfluxDB\footnote{\url{https://github.com/influxdata/influxdb}} je databázový
systém pre~uchovávanie hodnôt v~čase (\texten{Time-series Database}).
Okrem komerčnej licencie pre~nasadenie v~ich cloude a \texten{Enterprise} verzie
je tento systém distribuovaný aj pod~otvorenou MIT licenciou, a~tak ho~je možné
nasadiť aj na~vlastnom stroji ako samostatne bežiaci program, prípadne v~Docker
kontajneri.

\subsection{Formát uložených dát}

Základnou kolekciou dát je \texten{bucket} (ekvivalentom databázy v~klasickom
relačnom databázovom systéme), v~ktorom môžu byť dáta uchované po~určitý čas,
kedy po~tomto čase sú automaticky zmazané, alebo navždy.
Jednotlivé záznamy v~\texten{bucket}-e obsahujú názov merania
(\texten{\_measurement}), slovník tvaru kľúč-hodnota pre~značky (\texten{Tag
Set}), názov položky (\texten{\_field}) a hodnotu položky (\texten{\_value})
(Tab.~\ref{tbl:influxdb_entries}).
Hodnoty značiek sú na~rozdiel od~hodnôt položiek indexované pre~rýchlejšie
vyhľadávanie.
Každý záznam má aj časovú známku (\texten{\_time}) merania uloženú s~presnosťou
na~nanosekundy.

\begin{table}[!h]
    \centering
    \begin{otherlanguage}{english}
    \small
    \begin{tabular}{l l l l l l}
        \_measurement & device (tag) & port (tag) & \_field & \_value & \_time \\
        \hline
        router & ares1 & 0 & status & 1 & 2022-01-09T12:00:00Z \\
        router & ares1 & 0 & rx\_bytes & 4200 & 2022-01-09T12:00:00Z \\
        router & ares1 & 0 & status & 1 & 2022-01-09T12:01:00Z \\
        router & ares1 & 0 & rx\_bytes & 6900 & 2022-01-09T12:01:00Z
    \end{tabular}
    \end{otherlanguage}
    \caption{Príklad záznamov v~databázovom systéme InfluxDB}%
    \label{tbl:influxdb_entries}
\end{table}

Unikátna kombinácia názvu merania, značiek a~názvu položky následne označuje rad
hodnôt v~čase, ktoré je možné získať, prípadne dané časové intervaly spracovať
agregačnými funkciami (Tab.~\ref{tbl:influxdb_series}).

\begin{table}[!h]
    \centering
    \begin{otherlanguage}{english}
        \verb|router,device=ares1,port=0 status|\\
        \begin{tabular}{l l }
            \_value & \_time \\
            \hline
            1 & 2022-01-09T12:00:00Z \\
            1 & 2022-01-09T12:01:00Z \\
        \end{tabular}
        \verb|router,device=ares1,port=0 rx_bytes|\\
        \begin{tabular}{l l }
            \_value & \_time \\
            \hline
            4200 & 2022-01-09T12:00:00Z \\
            6900 & 2022-01-09T12:01:00Z \\
        \end{tabular}
    \end{otherlanguage}
    \caption{Príklad radov v~databázovom systéme InfluxDB}%
    \label{tbl:influxdb_series}
\end{table}

\subsection{Vkladanie údajov}

InfluxDB podporuje niekoľko spôsobov, ako je možné dáta do~databázy vložiť.
Okrem klasického HTTP API s~knižnicami v~niekoľkých jazykoch (Go, JavaScript,
Python\ldots, pre~Perl však knižnica pre InfluxDB vo~verzii 2 chýba), má
k~dispozícii aj konzolové rozhranie, pomocou ktorého je možné vložiť jeden
záznam alebo importovať súbor obsahujúci viac záznamov v~jeho vlastnom formáte
alebo ako CSV.

Taktiež si vie dáta získavať aj sám v~pravidelných intervaloch z~definovaného
HTTP zdroja.
Ten musí poskytovať dáta vo formáte Prometheus.
Neumožňuje však nastavenie vlastného intervalu, v~ktorom tieto dáta zbiera.

Na~zbieranie metrík je tiež možné použiť nástroj Telegraf, ktorý dokáže
pomocou InfluxDB
pluginu\footnote{\url{https://github.com/influxdata/telegraf/blob/release-1.22/plugins/outputs/influxdb_v2/README.md}}
automaticky ukladať zozbierané dáta do~preddefinovaného \texten{bucketu}
v~databáze cez už spomenuté HTTP API.

\subsection{Získavanie údajov}

Na získanie údajov má InfluxDB vlastný vyhľadávací jazyk Flux, ktorý
podporuje mnohé funkcie na~filtrovanie, agregovanie dát, tvorbu histogramov
a~iných štatistík.
Vykonanie samotného dopytu je možné tiež viacerými možnosťami, či už pomocou
HTTP API a knižníc alebo rozhrania príkazového riadku.

Na~rozdiel od~obyčajnej databázy má InfluxDB aj vlastné webové rozhranie, ktoré
umožňuje uložené hodnoty prechádzať a~zobrazovať v~grafoch
(Obr.~\ref{fig:data_explorer}), či tabuľkách
(Obr.~\ref{fig:data_explorer_table}) pomocou \texten{Data Explorer}.

\begin{figure}[!h]
    \centering
    \includegraphics[width=14cm]{./Images/Db/data_explorer.png}
    \caption{Graf hodnôt v~\texten{Data Explorer} v~rozhraní databázového systému
    InfluxDB}%
    \label{fig:data_explorer}
\end{figure}
\begin{figure}[!h]
    \centering
    \includegraphics[width=14cm]{./Images/Db/data_explorer_table.png}
    \caption{Tabuľka hodnôt v~\texten{Data Explorer} v~rozhraní databázového
    systému InfluxDB}%
    \label{fig:data_explorer_table}
\end{figure}

Dáta je možné zobraziť aj pomocou vlastných kontrolných panelov
(\texten{Dashboard}), kam sa dajú pridať grafy a~iné vizualizácie hodnôt podľa
zadaného Flux dotazu (Obr.~\ref{fig:dashboard}).
Týchto panelov je možné vytvoriť niekoľko a~pomenovať ich, umožňujú tak
jednoduchý dohľad nad~systémom.

\begin{figure}[!h]
    \centering
    \includegraphics[width=14cm]{./Images/Db/dashboard.png}
    \caption{Vlastný kontrolný panel v~rozhraní databázového systému InfluxDB}%
    \label{fig:dashboard}
\end{figure}

\subsection{Ďalšie funkcie}

V~neposlednom rade umožňuje InfluxDB aj nastavenie alarmov (\texten{Alerts}),
ktoré v~pravidelných intervaloch kontrolujú dáta a~v~prípade splnenia podmienky,
napríklad prekročenie stanovenej hodnoty (Obr.~\ref{fig:alarm}), užívateľovi
odošle oznámenie.
Tieto oznámenia vie odosielať tromi spôsobmi, buď ako POST požiadavku
na~ľubovoľnú URL adresu, Slack \texten{webhook} alebo cez~službu Pagerduty.

\begin{figure}[!h]
    \centering
    \includegraphics[width=14cm]{./Images/Db/alarm.png}
    \caption{Nastavenie alarmu pomocou rozhrania databázy InfluxDB}%
    \label{fig:alarm}
\end{figure}

Pokročilejšie nastavenie alarmov je možné pomocou vlastných skriptov
(\texten{Tasks}), avšak~ani takto nie je možné oznámenia posielať priamo cez
protokol SMTP, ale iba pomocou rovnakých metód, ako v~predchádzajúcom prípade.

\section{Prometheus}

Ďalším podobným systémom je
Prometheus\footnote{\url{https://github.com/prometheus/prometheus}}.
Rovnako ako InfluxDB je naprogramovaný v~jazyku Go.
Používa licenciu Apache 2.0 a~na~zjednodušenie nasadenia ponúka aj Docker obraz.

\subsection{Formát záznamov}

Formát záznamov je veľmi podobný InfluxDB, každý obsahuje všeobecný názov
metriky (\texten{Metric name}) a~slovník značiek (\texten{Labels}).
Rozdielom je, že takýto záznam môže obsahovať len jednu hodnotu, nie je možné
pridať viac položiek s~rôznymi hodnotami.
Ďalší rozdiel je v~type uložených hodnôt, zatiaľ čo InfluxDB podporuje typy
\verb|int64|, \verb|float64|, \verb|string|, \verb|boolean| a~časové známky
s~presnosťou na~nanosekundy, Prometheus má podporu len pre~\verb|float64|, čo
môže teoreticky spôsobiť problémy s~presnosťou veľkých čísiel, a~časové známky
s~presnosťou na~milisekundy.

\begin{lstlisting}[
    captionpos=b,
    caption=Príklad záznamov v~databázovom systéme Prometheus
]
    status{device="ares1", port="0"} 1 1641729600000
    rx_bytes{device="ares1", port="0"} 4200 1641729600000
    status{device="ares1", port="0"} 1 1641729660000
    rx_bytes{device="ares1", port="0"} 6900 1641729660000
\end{lstlisting}

\subsection{Vkladanie údajov}

Prometheus v~určených intervaloch zbiera dáta z~HTTP zdrojov definovaných
v~konfiguračnom súbore.
Tieto dáta musia byť v~jeho Prometheus formáte, podobne ako pri~InfluxDB.
Na~rozdiel od~InfluxDB sú však možnosti vkladania údajov menšie, keďže používa
\texten{pull} model.

Na~\texten{push} model vkladania dát je možné použiť PushGateway.
Jeho použitie je samotnými tvorcami odporúčané len vo~veľmi špecifických
prípadoch, napríklad dávkové procesy, ktoré nezávisia na~konkrétnom zariadení.

\subsection{Získavanie údajov}

Na~získanie údajov z~databázy je možné použiť HTTP API s~vlastným dopytovacím
jazykom PromQL.

Taktiež má aj jednoduché webové rozhranie, v~ktorom je možné zobraziť výsledky
PromQL dotazov v~grafe (Obr.~\ref{fig:prom_graph}), ale na~rozdiel od InfluxDB
neumožňuje dotaz graficky poskladať z~blokov, prípadne iné typy vizualizácií.
Na~zložitejšie vizualizovanie dát je ale možné použiť nástroj Grafana, ktorá
zahŕňa aj plugin pre~Prometheus.

\begin{figure}[!h]
    \centering
    \includegraphics[width=14cm]{./Images/Db/prom_graph.png}
    \caption{Graf hodnôt v~rozhraní databázového systému Prometheus}%
    \label{fig:prom_graph}
\end{figure}

\subsection{Ďalšie funkcie}

Prometheus taktiež umožňuje nastavenie alarmov.
To je rozdelené na~dve časti, nastavenie pravidiel, kedy sa má daný alarm
spustiť je priamo v~hlavnom konfiguračnom súbore.
Doručenie oznámení používateľovi ale prebieha prostredníctvom samostatnej
aplikácie AlertManager.
Oznámenia je možné filtrovať a~doručovať ich rôznym adresátom a~taktiež
podporuje viacero spôsobov, napríklad emailom, cez~ďalšie služby ako Pagerduty,
Opsgenie, VictorOps, Slack alebo na~akúkoľvek URL adresu ako POST požiadavku.
Jeho možnosti sú tak oproti InfluxDB výrazne rozsiahlejšie.

\section{RRDTool}

RRDTool\footnote{\url{https://oss.oetiker.ch/rrdtool/}} (\texten{Round Robin
Database Tool}) je oproti predchádzajúcim dvom riešeniam výrazne jednoduchší
nástroj.
Ide o~samostatný program v~jazyku C distribuovaný pod~GNU GPL licenciou, avšak
vďaka FLOSS (\texten{Free/Libre and Open Source Software}) výnimke umožňuje
distribuovať programy využívajúce RRDTool aj pod~inou licenciou ako GNU GPL.

Zatiaľ čo InfluxDB aj Prometheus umožňujú uložiť dáta v~akomkoľvek čase, tento
nástroj ich očakáva v~predom zadaných intervaloch a~v~prípade, že hodnota nie je
vložená do~uplynutia časového limitu (\texten{heartbeat}), tak sa použije
hodnota \verb|*UNKNOWN*|.
Taktiež umožňuje ukladať len pevný počet hodnôt, ktoré postupom času prepisuje
novými.

\subsection{Formát údajov}

Jednotlivé zdroje dát (\texten{Data Source}) radov sú identifikované jedinečným
menom a~každý môže obsahovať niekoľko cyklických archívov (\texten{Round Robin
Archive}), ktoré sa môžu líšiť intervalom, agregačnou funkciou (napríklad
priemer, maximum, minimum) alebo iným parametrom.
To umožňuje uchovávať údaje za~dlhší časový úsek na~úkor nižšieho rozlíšenia,
čím sa dá ušetriť diskový priestor.

\subsection{Vkladanie a získavanie údajov}

Všetka interakcia s~nástrojom vrátane vkladania a získavania údajov z~databázy
prebieha prostredníctvom rozhrania príkazového riadku, prípadne pomocou knižníc,
ktoré slúžia ako jeho nadstavba.
Taktiež má príkaz na~generovanie jednoduchých grafov z~uložených dát.
