Osprey Event-Engine löst das Problem der Echtzeitverarbeitung von Ereignissen und Regeln bei hohen Lasten. Lassen Sie uns die Architektur untersuchen und die Kompromisse aufdecken, die darin verborgen sind.
Das Problem tritt auf, wenn der Ereignisstrom kontinuierlich wird und die Reaktion synchron bleiben muss. In Plattform-Systemen mit Hunderten Millionen Aktionen pro Tag beginnen klassische Pipelines, Verzögerungen (latency) zu verursachen oder die Konsistenz der Entscheidungen zu verlieren. Dies ist besonders in Szenarien der Bedrohungserkennung bemerkbar, wo selbst eine kleine Verzögerung das Ergebnis verändert. Zusätzlichen Druck erzeugt die Notwendigkeit, Regeln dynamisch zu aktualisieren, ohne das System anzuhalten. An diesem Punkt stößt die Architektur auf einen Konflikt: Verarbeitungsgeschwindigkeit gegen Flexibilität der Logik.
In Osprey wurde ein pragmatischer Kompromiss gewählt — die Trennung des Systems in Data Plane und Control Plane durch einen polyglotten Ansatz. Ein Koordinator in Rust verwaltet die Ereignisströme und die Konkurrenz, während Python-Worker die Geschäftslogik der Regeln ausführen. Dieser Ansatz spiegelt ein verbreitetes industrielles Muster wider: Rust sorgt für vorhersehbare Leistung und Speicherverwaltung, Python für Geschwindigkeit in der Entwicklung und Erweiterbarkeit. Der Trade-off ist offensichtlich: Das Betriebsmodell und die Beobachtbarkeit werden komplexer, aber der Durchsatz und die Flexibilität gewinnen. Im Kontext der ereignisgesteuerten Architektur ermöglicht dies die Skalierung der Verarbeitung ohne strikte Bindung an die Logik.
Die Implementierung basiert auf mehreren Schlüsselfaktoren. Ereignisse kommen im JSON-Format als Actions und durchlaufen den Koordinator, der asynchrone Ströme verwaltet und gRPC-Anfragen für stabile Latenz priorisiert. Die Regelverarbeitung erfolgt auf stateless Python-Workern. Um Overhead durch Interpretation zu vermeiden, werden Regeln in SML (DSL mit Python-Syntax) beim Start in einen Abstract Syntax Tree kompiliert. Dies verlagert die Rechenlast in die Initialisierungsphase und senkt die Kosten für die Verarbeitung jedes Ereignisses.
Die Dynamik des Systems wird über ETCD gewährleistet: Regeln werden ohne Redeployment auf die Worker verteilt. Dies ist entscheidend für Systeme, in denen Änderungen der Logik sofort angewendet werden müssen. Das stateless Design und die Containerisierung über Docker ermöglichen eine horizontale Skalierung der Verarbeitung bei Spitzenlasten. Die Interaktion mit der Außenwelt erfolgt über Output Sinks, die mit Pluggy implementiert sind, wodurch starre interne Abhängigkeiten durch erweiterbare Integrationspunkte ersetzt werden.
Besondere Aufmerksamkeit verdient das Erweiterungsmodell über User Defined Functions. Diese werden in Python geschrieben und bilden faktisch die Standardbibliothek des Systems. Dies ermöglicht den Zugriff auf externe APIs und ML-Modelle, bringt jedoch gleichzeitig das Risiko unkontrollierbarer Abhängigkeiten und steigender Latenz mit sich. Hier setzt die Architektur auf Disziplin in der Nutzung, nicht auf strikte Einschränkungen.
Aus Sicht der Daten operiert das System mit Entities — Objekten, für die der Zustand gespeichert und Labels angewendet werden. Dies ermöglicht den Aufbau kontextueller Regeln, erfordert jedoch eine sorgfältige Verwaltung des Zustands, um die Konsistenz bei der Skalierung nicht zu gefährden. Im ursprünglichen Beschreibungstext werden keine Details zur Speicherung des Zustands offengelegt, was die Frage nach seiner Robustheit bei Ausfällen offenlässt.
Die Ergebnisse zeigen, dass das System in der Lage ist, bis zu 2,3 Millionen Regeln pro Sekunde bei einer Last von mehreren Hundert Millionen Ereignissen pro Tag zu verarbeiten. Dabei werden keine genauen Metriken zu Latenz und Fehlern offengelegt. Architektonisch zeigt das System Robustheit durch die Trennung der Verantwortlichkeiten: Rust stabilisiert den Fluss, Python beschleunigt die Evolution der Logik. Kafka und Druid werden für Routing und Analytik verwendet und schließen den Kreis von der Verarbeitung zur Beobachtbarkeit.
Letztendlich ist Osprey kein Versuch, die Ereignisverarbeitung zu vereinfachen, sondern ein Eingeständnis ihrer Komplexität. Die Architektur setzt auf Skalierbarkeit und Dynamik und akzeptiert steigende Betriebskosten als unvermeidlichen Kompromiss. Dieser Ansatz wird bereits zum Standard für Highload-Systeme, in denen der Datenfluss wichtiger ist als die Einfachheit der Ausführung.