27 Oktober 2014

Am 09.10.2014 wurde mein insgesamt 4. Pressebericht von meinem Arbeitgeber veröffentlicht: Big Data durch SEPA: Mehr Zahlungen, mehr Transaktionen, mehr Kosten.
Dort habe ich beschrieben, wie man mit einer nicht relationalen Datenbank Transaktionen abspeichern könnte. In meinem aktuellen Projekt setzen wir dafür Elasticsearch ein.
Dies war allerdings nicht unsere erste Lösung. Zunächst haben wir Apache Lucene verwendet. Dies wird auch in Elasticsearch verwendet. Allerdings kapselt Elasticsearch einiges an Komplexität weg, sodass mit Einstellungen im Auslieferungszustand sehr schnell Informationen durchsuchbar gemacht werden können. Elasticsearch hatte zu Beginn allerdings einen Nachteil: Man kann die Informationen nicht auf einen Schlag sichtbar machen. Da man Transaktionen getrennt von einander speichern möchte, kann man bei z.B. 10.000 Transaktionen innerhalb einer Datei nicht erst alle Transaktionen für eine Suche sichtbar machen, wenn die 10.000. Transaktion indiziert wurde. Die suchende Applikation muss mit diesem Umstand umgehen können. Deshalb haben wir zunächst Apache Lucene direkt verwendet, da man dort einen commit-Mechanismus hat, der das Beschriebene bietet. Allerdings haben wir dazu für die gesamte Datenmenge einen einzelnen Index verwendet. Das hat die Anwendung so sehr verlangsamt, dass wir Gefahr liefen, einen Tag mit etwa 10 Millionen Transaktionen nicht innerhalb von 24 Stunden verarbeiten zu können. Da wir bisher maximal die Menge der letzten 8 Wochen vorhalten müssen, machte es für uns Sinn, die Transaktionen in mehreren Indizes zu unterteilen. Da sich außerdem die Indizes der vergangenen Tage nicht verändern, sondern nur der aktuelle Tag, ist ein Tag die beste Größe für einen Index aus unserer Sicht.
Dafür bringt Elasticsearch einiges mit. Denn eigentlich ist es für den Aufbau eines Clusters, also Verteilung auf mehrere Server-Instanzen, konzipiert, um die Last zu verteilen. Mit Hilfe von Index-Aliasen lassen sich dann mehrere Indizes durch nur einen Namen ansprechen. Jede Abfrage wird ja zu einem bestimmten Zeitpunkt ausgeführt. Da wird der Datumsteil entnommen und der entsprechende Alias draus erzeugt. Anschließend wird abgefragt, ob es den Index gibt. Ist dies nicht der Fall, wird für den vorherigen Tag das gleiche Vorgehen ausgeführt, solange bis ein Index gefunden wird oder eine andere Abbruchbedingung greift. Damit nicht bei jeder Abfrage überprüft werden muss, ob es den Index gibt, sollte man natürlich den aktuellen Alias cachen, wenn man ihn bereits geprüft hat.
Der Entwickler bekommt also einiges an die Hand, um ein solches Konstrukt aufzubauen. Nur den Commit-Mechanismus verliert man mit Elasticsearch. Wie man diesen soweit wie möglich nachbilden kann, beschreibt Patrick Peschlow unter Transactions in Elasticsearch.
Zu den Informationen, nach denen wir suchen wollen, werden die notwendigen Informationen für die Prozesse abgespeichert. Das ist unter anderem auch der Dateiname und die Positionen der maximal drei Ebenen einer Datei (Datei-, Gruppe- und Transaktionsebene) innerhalb der Datei. Mit Hilfe dieser Informationen können zu jeder in der Recherche vorliegenden Transaktion die drei Ebenen einer Transaktion als XML-Zeichenkette ermittelt werden. Mit Hilfe dieser Zeichenkette von Original-Transaktionen (pacs.003 (Lastschrift) und pacs.008 (Gutschrift)) lassen sich dann automatisch R-Transaktionen mit Hilfe eines entsprechenden Konverters erzeugen. Dies lässt sich z.B. nutzen, um Validation-Files von anderen Clearing-Häusern automatisch zu verarbeiten. Auch eine Maske mit den bereits vorerfassten Daten einer Original-Transaktion lässt sich so umsetzen. Es sind viele Möglichkeiten denkbar.
Mit dem beschriebenen Konstrukt ist es möglich, über eine Milliarde Dokumente schnell zu durchsuchen; ohne große Wartezeit selbst an Tagen mit über 40 Mio. Transaktionen. Die größte Hürde stellt bisher noch die Bereitstellung der Daten dar: Innerhalb kürzester Zeit sollen mehrere hundert Megabyte-große Dateien durchsuchbar sein. Dies lässt sich nur durch parallele Verarbeitung lösen. Bisher ist diese leider nicht effizient genug, da mehrere große Dateien auch mal einen Prozess verstopfen können, während alle anderen Prozesse auf Dateien warten. Dies ist aber unbestritten der Art der Bereitstellung geschuldet: Die Dateien kommen in einem Verzeichnis an und werden dann von einem Prozess auf verschiedene Unterverzeichnisse verteilt. Für jedes Unterverzeichnis gibt es dann einen eigenen Prozess, der die Dateien verarbeitet. Leider ist die Verteilung nicht “schlau” genug, um zu erkennen, ob in dem Unterverzeichnis nicht bereits mehrere große Dateien liegen. Wenn diese Parallelisierung verbessert werden könnte, wäre die Echtzeit-Suche nicht mehr weit entfernt, um die automatischen Massenzahlungsverkehrsprozesse noch weiter zu verbessern.