\documentclass[11pt,a4paper,parskip=half]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage[margin=1.9cm]{geometry}
\usepackage{booktabs}

\setkomafont{title}{\Huge}
\pagestyle{empty}

\begin{document}

{\Huge Handout - Ringstats}\\[1mm]
{\small von Justin Rost, Michelle Reichelt, Yasin Ergün}

\section*{Anwendungsszenario}
Ringstats verbindet das laufende Spiel (Elden Ring) mit einer Datenbank voller hilfreicher Spielinformationen.
 Eine Eldenring-Mod liest in Echtzeit aus, wo der Spieler gerade steht, wie viel Leben er hat und was er ausgerüstet hat, und schickt das laufend an die Datenbank. Im Spiel tauchen die passenden Infos dann von selbst auf: Visiert der Spieler einen Boss an, öffnet sich ein kleines Panel mit dessen Resistenzen und häufigsten Fähigkeiten. Beim Gebietswechsel zeigt eine Checkliste an, was in der Region noch offen ist (Truhen oder Bosse). Im Browser kann man dann noch mehr Informationen lesen.

\section*{Modellierung des Anwendungsszenarios}
Grundlage ist unser ER-Modell. Der Player hängt über sein Gear an Weapon, Armor, Shield und Talisman und steht immer in einer Region, in der Items und Enemies aufzufinden sind.

\begin{center}
    \includegraphics[width=0.42\textwidth]{../../assets/er-modell}
\end{center}

Das Modell oben haben wir in verschiedenen Datenbanken modelliert. Im \textbf{Key-Value-Modell} bekommt alles einen Key nach dem Muster \texttt{entität:\{id\}} und wird als Hash Map in der Datenbank gespeichert. Beziehungen wie die Ausrüstung speichern wir in Sets, z.B. \texttt{player:\{id\}:armor}. \textbf{Dokumentenorientiert} speichert zu jeder Entität ein Dokument in einer eigenen Collection. Und im \textbf{Graph-Modell} ist jede Entität ein Knoten. Die Verbindungen aus dem ER-Modell werden zu Kanten wie \texttt{has\_equipped} oder \texttt{drops}.

Entschieden haben wir uns für das Key-Value-Modell. Ringstats schreibt die Daten des Spieler laufend und liest sie sofort wieder aus, viel mehr passiert da nicht. Die komplexen Abfragen, bei denen Dokumentenorientiert oder Graph stark wären, kommen bei uns kaum vor, und tief verschachtelt sind unsere Daten auch nicht.

\section*{Marktrecherche und Nutzwertanalyse}
Für das Key-Value-Modell haben wir uns sechs verschiedene Datenbanken angeschaut: Redis, Memcached, ArangoDB (multimodal), Amazon DynamoDB, etcd und Riak KV. Jedes Kriterium bekommt pro Datenbank 0 bis 2 Punkte, multipliziert mit dem Gewicht.

\begin{table}[h]
\centering
\small
\begin{tabular}{l c c c c c c c}
\toprule
\textbf{Kriterium} & \textbf{Gewicht} & \textbf{Redis} & \textbf{Memc.} & \textbf{Arango} & \textbf{Dynamo} & \textbf{etcd} & \textbf{Riak} \\
\midrule
Hohe Perfomanz & 5 & 2 & 2 & 1 & 1 & 1 & 1 \\
Daten-Streaming & 3 & 2 & 0 & 0 & 2 & 1 & 0 \\
Niedrige Latenz & 3 & 2 & 2 & 1 & 1 & 1 & 1 \\
Skalierbarkeit & 1 & 1 & 1 & 1 & 2 & 0 & 2 \\
Keine Lizenzkosten & 5 & 2 & 2 & 2 & 0 & 2 & 2 \\
Indexing & 2 & 1 & 0 & 1 & 1 & 0 & 1 \\
Vektorrechnungen & 1 & 1 & 0 & 1 & 0 & 0 & 0 \\
\midrule
\textbf{Gewichtete Summe} & & \textbf{36} & \textbf{27} & \textbf{22} & \textbf{18} & \textbf{21} & \textbf{22} \\
\bottomrule
\end{tabular}
\end{table}

Redis hat als einziger bei Performanz, Latenz und Daten-Streaming die volle Punktzahl. Memcached hält mit, hat aber weder Sets noch Persistenz. DynamoDB scheitert mit seinen laufenden Kosten am Muss-Kriterium \glqq keine Lizenzkosten\grqq{}, etcd ist eher für Konfigurationsdaten gedacht und an Riak KV wird kaum noch entwickelt.

Am ende haben wir davon 3 Stück umgesetzt: Redis, Memcached und ArangoDB.

\section*{Benchmarks}
Gemessen haben wir zwei typische Anwendungsfälle. Beim Live-Player-Sync werden Spielerdaten gelesen und geschrieben. Beim Gebietswechsel sind es für alle Entitäten im Gebiet mehr oder weniger Anfragen. Die Ergebnise in Operationen pro Sekunde:

\begin{table}[h]
\centering
\small
\begin{tabular}{l c c c c}
\toprule
\textbf{Ops/s} & \textbf{Spieler Schreiben} & \textbf{Spieler Lesen} & \textbf{Region Lesen} & \textbf{Region Schreiben} \\
\midrule
Redis & 74,407 & 75,108 & 81,416 & 78,688\\
Memcached & 65,254 & 62,512 & 72,065 & 69,745 \\
ArangoDB & 2,568 & 7,546 & 2,365 & 717 \\
\bottomrule
\end{tabular}
\end{table}

Redis und Memcached liegen nah beieinander. Die multimodale Flexibilität kostet spürbar Geschwindigkeit, und genau die brauchen wir für unser schreiblastiges Live-Szenario.

\section*{Fazit}
Darum haben wir uns für Redis entschieden. Genauso schnell wie Memcached, aber mit Hashes und Sets. Und im gegensatz zu Memcached ist Redis sogar Persistenz. Genau das brauchen wir bei der Anwendung.

\end{document}
