Eine häufige Antwort auf Redundanzprobleme lautet „Sharding“ oder „Partitionierung“. Tatsächlich ließen sich die potenziellen Folgen technischer Störungen eingrenzen, wenn Zustand und Verarbeitung auf mehrere voneinander unabhängige Maschinen aufgeteilt werden könnten. Auch die Systemleistung wäre höher, da die einzelnen Partitionen weniger ausgelastet werden und schneller arbeiten.
Doch normale Börsen sind von Haus aus zentralisiert: Für jedes Finanzinstrument wird ein Orderbuch mit sämtlichen Orders aller Kunden geführt. Dieses Buch lässt sich extrem schwer auf mehrere Serverinstanzen aufteilen. Deshalb gibt es keine andere Möglichkeit als das Orderbuch auf einem einzigen Server zu belassen. De facto bedeutet das: Ohne zusätzliche Technologie würde eine Börse den Absturz eines Servers mit Orderbuch nicht überleben. Doch die Börsen arbeiten in der Regel mit mehreren Segmenten der angebotenen Finanzinstrumente, wobei jedes Segment nur einen Teil des gesamten Instrumentenspektrums bedient.
Naheliegend: Der Einsatz einer Datenbank
Ist die Partitionierung des Central Limit Order Book (CLOB) nicht möglich, müssen andere Maßnahmen ergriffen werden, damit keine Daten verloren gehen und die Börse den Ausfall eines (oder mehrerer) Server verschmerzen kann.
Eine nahe liegende Idee wäre der Einsatz einer Datenbank. Hierbei wird jede Transaktion (etwa eine Order oder ein Trade) zuverlässig in der Datenbank aufgezeichnet, bevor die Transaktionsergebnisse dem Kunden übermittelt werden. Diese Lösung ist zwar möglich, hat jedoch ihre Schwächen – denn die Datenbank muss auch in der Lage sein, einen System-Crash zu überstehen. Außerdem ist die Latenzzeit einer Datenbank meist sehr viel länger als sich eine gute Börse leisten kann, denn eine einzige Datenbanktransaktion nimmt mehrere Millisekunden in Anspruch. Von Börsen wird aber normalerweise eine End-to-End-Latenzzeit von unter einer Millisekunde erwartet.
Diese hohe Latenz lässt sich darauf zurückführen, dass Datenbanken meist zusätzliche „Hops“ (Sprünge von einem Netzwerksegment zum nächsten) benötigen und auf Festplattendaten zuzugreifen – was sehr lange dauern kann. Deshalb sind auch Datenbanken nicht die beste Wahl für eine moderne Börse.
Der bessere Weg: Replicated State Machine
Wenn die Daten nicht segmentiert und keine Datenbanken eingesetzt werden können – welche Möglichkeit gibt es dann noch? Die einzig praktikable Lösung scheint eine Replicated State Machine zu sein: Hierbei wird jedes Orderbuch als Modell angesehen, für das es eine bestimmte Anzahl an Inputs gibt (etwa die Platzierung einer Order oder die Stornierung sämtlicher Orders), die mehrere Outputs erzeugen (wie Trades, Marktdaten oder Ausführungsberichte). Die Outputs werden ausschließlich durch den internen Zustand und die Inputs determiniert – und durch nichts anderes. Externe Taktgeber beispielsweise gibt es nicht.
Dieses Modell ist sehr nützlich, denn damit können mehrere identische Instanzen einer Matching-Engine ausgeführt und alle Inputs in alle Instanzen kopiert werden. Ist der Ausgangszustand derselbe, sind auch die Outputs dieselben – womit für Redundanz gesorgt wäre. Sollte eine dieser Instanzen versagen, kann die Arbeit mit den übrigen Instanzen fortgesetzt werden.
Fast jede auf dem Markt eingesetzte Matching-Engine ist als „Replicated State Machine“ konzipiert, bei der mehrere Instanzen in Clustern ausgeführt werden. Doch viele Fragen bleiben offen: Wie wird gewährleistet, dass alle Maschinen den gleichen Input in der gleichen Order erhalten? Was geschieht, wenn eine Maschine versagt? Was passiert im Fall einer Netzwerkstörung? Hier gibt es verschiedene Algorithmen, die diese Fragen beantworten. Das Problem, das sie lösen, wird in der Regel als „Problem des verteilten Konsenses“ bezeichnet. Hierfür stehen verschiedene Protokolle zu Verfügung, von denen Paxos und Raft am bekanntesten sind.. Sie stellen sicher, dass ein Cluster sich letztendlich auf seine Inputs einigt – und jede Serverinstanz somit denselben Output bereitstellen kann.
Konsensalgorithmen haben zwar eine solide theoretische Grundlage, sind aber berüchtigt für ihre schwierige Neuimplementierung. Das ist auch einer der Hauptgründe dafür, dass es auf dem Markt nicht viele quelloffene, hochleistungsfähige Matching-Engines gibt: Die Entwicklung einer zuverlässigen Matching-Engine mit geringer Latenzzeit erfordert viel Mühe, viele Tests und viele Trial-and-Error-Durchläufe.
Was eine Matching-Engine ausbremst
Selbst eine gute Konsensimplementierung reicht nicht aus, um schnelle, ausfallsichere Matching-Engines aufzusetzen. Folgende Faktoren verhindern es. die Latenzzeiten in Schach zu halten
- Laufzeitumgebungs-Jitter: Die meisten modernen Hochsprachen arbeiten mit einer Form der automatischen Speicherverwaltung, auch „Garbage Collection“ (Müllabfuhr) genannt. Die Programmierer können nach Bedarf Speicher zuweisen, und die Laufzeitumgebung ist dann dafür verantwortlich, ihn zu beanspruchen. Auch wenn es sich um eine sehr nützliche Funktion handelt – sie verursacht eine Latenzzeit, die bis zu mehrere Sekunden betragen kann.
Solange die „Garbage Collection“ läuft, wird die Anwendung womöglich sehr viel langsamer ausgeführt oder komplett gestoppt. Das ist auch der Grund, warum Börsenplattformen mit relativ maschinennahen Programmiersprachen entwickelt werden, die die volle Kontrolle über die Speicherzuweisung haben (wie C oder C++). Sind sie in höheren Sprachen wie Java geschrieben, ist eine spezielle Herangehensweise notwendig.
- Laufzeitinkonsistenz infolge des Netzwerk-Stacks oder des Betriebssystems: Normalerweise werden Betriebssysteme und Netzwerke in Hinblick auf Standard-Anwendungsfälle optimiert, bei denen mehrere Prozesse gleichzeitig ausgeführt werden. Dabei kann das Betriebssystem Prozesse vorübergehend unterbrechen und sie zwischen den CPUs hin- und herschieben, so dass Latenzen auftreten. Doch in Situationen, in denen jede Mikrosekunde zählt, ist das nicht tolerierbar. Auch eine Virtualisierung ist inakzeptabel.
Um dieses Problem zu lösen, laufen Börsensysteme so hardwarenah wie möglich: CPU-Kerne werden ausschließlich für die Matching-Engine-Anwendung reserviert und komplexe Koordinationsvorgänge zwischen den Prozessen tunlichst vermieden. Auch spezialisierte Netzwerk-Hardware kommt in der Regel zum Einsatz.
- Schwächen im System Design: Selbst mit einem guten Technologie-Stack sollte man bei der Systementwicklung sehr sorgfältig sein. Die Auswahl der Algorithmen und Datenstrukturen ist hierbei sehr wichtig: ein Entwickler sollte „Mechanical Sympathy“ besitzen – ein Begriff, den LMAX in den frühen 2010er Jahren einführte. Das bedeutet: Er sollte die Funktionsweise der Hardware kennen, um die effizienteste Software schreiben zu können.
Eventuell arbeiten manche Börsen auch mit FPGA-basierten Lösungen, also mit speziellen, programmierbaren Chips. Diese führen die Programme ohne den Overhead aus, der durch die Unterstützung von Betriebssystemen oder Standardschnittstellen entsteht. Allerdings gibt es zu diesem Thema keine öffentlich zugänglichen Informationen. Zudem kann sich die Implementierung höchst komplex gestalten, da Matching-Engines mitunter eine sehr ausgereifte Logik besitzen.
Fazit
Beim Aufbau einer Börse den Mittelweg zwischen Performance und Ausfallsicherheit zu finden, ist äußerst schwierig. Nahe liegende Methoden wie das Sharding oder eine Datenbankimplementierung mögen auf den ersten Blick vielleicht geeignet erscheinen – denn sie mildern die Folgen von Störfällen ab und verbessern eindeutig die Leistung. Doch leider sind sie mit zu vielen Nachteilen verbunden. Die bessere Option ist deshalb eine Replicated State Machine: Sie sollte mit einer sorgfältig entwickelten Software kombiniert werden, die für geringe Latenzzeiten sorgt.
Autor Yuri Kudryashov ist Technical Lead bei Devexperts und verantwortet die Handelsplattform DXtrade. Er hat mehr als 15 Jahre Erfahrung in der Entwicklung von Finanzsystemen und bereits an Handelssystemen für einige der größten Broker der Welt, an Vermögensverwaltungssystemen, Optionen/Futures und Krypto-Börsen gearbeitet.