Als wir 2018 mit der Implementierung unserer Plattform begannen, haben wir uns gemeinsam verpflichtet, eine hochmoderne Software zu entwickeln, die sich an modernen und bewährten Praktiken orientiert. Zunächst haben wir uns eingehend mit modernen Softwarearchitekturen wie Event Driven, Microservices, verteilten Systemen, Cloud Native und DevOps beschäftigt, was zu einer Reihe positiver Architekturentscheidungen führte.
Wir beschreiben unsere eigene Architektur oft als "komplex, aber überschaubar". Als grundlegendes Gestaltungsprinzip verfolgen wir verbraucherinitiierte Abonnements, wobei die Verantwortung für die Abonnements bei den Verbrauchern liegt. Die Produzenten bieten den Konsumenten Schnittstellen an; die Konsumenten entscheiden selbst, was sie konsumieren und welche Daten sie filtern wollen.
Als wir begannen, die oben beschriebene Architektur in unserem System zu implementieren, haben wir uns voll und ganz auf einen einzigen Cloud-Anbieter festgelegt - AWS. Die Verwendung von AWS SNS für Verteilungsereignisse und AWS SQS für Verbrauchsereignisse eignet sich am besten für die Unterstützung dieses Architekturansatzes.
Nebenbei bemerkt, glauben wir fest an das AWS-Kerncredo "You build it, you run it!" Das bedeutet, dass jedes Team seinen eigenen Satz von AWS-Konten verwaltet, ohne zentrale Betriebs- oder SRE-Teams. Daher müssen die Hersteller die AWS-Konto-IDs ihrer Kunden in einer Liste zulassen. Dieser Ansatz für die Erlaubnisliste fühlte sich nie richtig an, da er umfangreiche manuelle Eingriffe erforderte. Es war jedoch akzeptabel, da unser gesamter interner Code unter Versionskontrolle auf GitHub steht und die Kunden entweder PRs (Pull Requests) erstellen oder sich direkt per Chat mit den Produzenten in Verbindung setzen können, um auf die Allowlist gesetzt zu werden. Nachdem sich der Kunde angemeldet hat, kümmert sich Terraform bei jedem Durchlauf in einer CI/CD-Pipeline darum, die Verbindung aufrechtzuerhalten.
Diese Lösung hat jedoch neben der Verwaltung von Abonnements noch einige andere Komplikationen. Wenn ein Datenverlust auftritt (was ziemlich selten vorkommt), muss ein Konsument mit dem Produzenten interagieren, um die Ereignisse wiederholen zu können. In unserem Fall haben die Teams oft über unser Kollaborationstool gechattet, um fehlende Ereignisse von einem bestimmten Zeitpunkt wiederherzustellen. Dies führt natürlich zu einem großen Aufwand sowohl auf Seiten des Produzenten als auch auf Seiten des Konsumenten.
Die Nutzdaten selbst werden transparent mit AWS KMS verschlüsselt , und dies erfüllt die wichtigsten Datenschutzregeln, die die Einhaltung der GDPR sicherstellen. Wann immer wir Daten länger speichern, implementieren wir auch eine Verschlüsselung auf Feldebene für alle PII-Daten (personenbezogene Daten wie Namen, Geburtstage, Adressen usw.). Da wir den Zugriff auf Warteschlangen und Themen innerhalb unseres Austauschsystems ohne zentrale Schlüsselverwaltung gemeinsam nutzen, müssen wir die Verschlüsselung zwischen den Teams im laufenden Betrieb austauschen. Wir haben verschiedene Möglichkeiten des Austauschs von Schlüsseln oder Zugriffsschlüsseln zwischen Teams in Betracht gezogen, aber keine wirklich zufriedenstellende Lösung gefunden. Daher haben wir uns darauf geeinigt, personenbezogene Daten nicht länger in Warteschlangen und Themen zu speichern, um eine langfristige Datenspeicherung hier zu vermeiden. Ein zusätzliches Plus ist, dass dies die Verwendung von Warteschlangen mit toten Buchstaben nahezu unmöglich macht.
Als wir uns im Jahr 2020 mit Multicloud befassen mussten, stieg die Komplexität des Nachrichtenaustauschs sprunghaft an. AWS SQS kann nicht direkt von Google Cloud Pub/Sub Topics konsumieren - und umgekehrt. Um dies zu umgehen, haben wir für beide Flussrichtungen serverlose Funktionen (wie hier und hier) implementiert, die HTTP-basiert sind und die Event-Zustellung zwischen beiden Cloud-Anbietern ermöglichen. Bei der Abonnementverwaltung haben wir wieder einmal viel manuelle Arbeit festgestellt: Verbraucher mussten ihren HTTP-Endpunkt an die Erzeuger übergeben - und die Erzeuger mussten die Identitäten der ausgehenden Themen (wie AWS ARNs für SNS) benennen, um sicherzustellen, dass Verbraucher die Ereignisquelle validieren konnten. Wiederum sehr unbefriedigend... aber anstatt die Komplexität zu reduzieren, begannen wir, eine weitere Logikebene bezüglich der Abonnementverwaltung hinzuzufügen: Jedes Team musste einen Endpunkt erstellen, an dem die Verbraucher ihr Abonnement initiieren und überprüfen konnten, ob das Abonnement existiert. Das funktionierte zwar - aber da diese Codeschnipsel nicht oft verwendet wurden und Authentifizierung und Autorisierung das Gesamtbild noch mehr vernebelten, wurde es schwierig zu verstehen, was der Code wirklich tat. Wir hatten das Gefühl, dass wir eine einfachere Lösung brauchten!
Mitte 2021 begannen wir, darüber nachzudenken, wie wir die Hauptprobleme der bestehenden Datenplattform für den event-exchange lösen könnten. Unsere Ziele waren zu erreichen:
Als sehr heterogene Arbeitsgruppe aus Entwicklern, technischen Leitern und Architekten begannen wir, verschiedene Cloud-agnostische Event-Austauschplattformen zu untersuchen. Ich möchte hier nicht näher auf die verschiedenen Möglichkeiten eingehen, die wir evaluiert haben (Du kannst dich gerne an mich wenden ;>), und natürlich bin ich mir bewusst, dass alle Lösungen ihre Vor- und Nachteile haben. Dennoch erschien uns Apache Kafka als die branchenweit führende Plattform für die Verarbeitung von Ereignisströmen in den letzten Jahren am vielversprechendsten. Apache Kafka verfügt über großartige integrierte Funktionen wie Replay (durch Zurücksetzen des Offsets einer bestimmten Verbrauchergruppe), es hat einen hohen Durchsatz - viel mehr als wir je erwartet hatten - und bietet Client-Bibliotheken für die am häufigsten verwendeten Sprachen und Frameworks. Um mit unserem technischen Manifest im Einklang zu bleiben, waren wir mehr als glücklich, ein Unternehmen zu finden, das einen verwalteten Hosting-Service für Apache Kafka anbietet: Confluent.
Mit all diesen Vorteilen begannen wir, mit Apache Kafka, das in der Confluent Cloud gehostet wird, zu experimentieren, um unsere Erwartungen zu bestätigen. Und diese Erfahrung war ein Knaller! Kafka ist so einfach zu bedienen, dass sich unsere Entwickler bereits in der Experimentierphase in diese Event-Stream-Plattform verliebt haben. Sie lässt sich nahtlos in die anderen von uns verwendeten Technologien integrieren, z. B. Spring Boot, und bietet die meisten der fehlenden Funktionen, die wir in unserer SNS/SQS Pub/Sub-Umgebung bemängelt haben. Wir hatten schnell das Gefühl, dass dies unsere zukünftige Plattform ist - sie ist Cloud-unabhängig und einfach zu implementieren. Zwei Aspekte fehlten allerdings noch. #Nr. 1: Confluent bietet keine Selbstbedienungsoptionen aus Sicht des Produktteams. #Nr. 2: Da wir mit themenbezogenen PII-Daten zu kämpfen hatten, wollten wir eine zusätzliche Sicherheitsebene und die Möglichkeit, Felder in der Nutzlast zu verschlüsseln.
Um auf Nr. 1 zurückzukommen: Entweder ist man ein Organisationsadmin und verwaltet das gesamte Confluent-Konto, oder man hat keine Zugriffsrechte auf die Plattform. Wir waren mehr als froh, dass unsere Freunde bei Hermes Deutschland dieses Problem bereits angegangen sind und eine DevOps Self-Service Plattform für Kafka namens Galapagos implementiert haben. Galapagos implementiert den fehlenden Teil und gibt Produktteams Zugang, um Themen zu erstellen, Transparenz über Ereignisse zu erhalten, die von anderen Teams bereitgestellt werden, eine Schema-Registry anzubieten und Abonnements zu verwalten.
Um Problem Nr. 2 zu lösen (Verschlüsselung auf Feldebene on-the-fly), hatten wir mehrere Treffen mit den Ingenieuren von Confluent. Deren Accelerator kann die Ver-/Entschlüsselungsaufgabe übernehmen - bietet aber keine Plattform, auf der Produktteams den Zugang zu Verschlüsselungsschlüsseln gemeinsam nutzen können. Der Confluent Accelerator bietet Verbindungen zu verschiedenen KMS-Lösungen (Key Management System) wie AWS KMS oder GCP KMS. Auch hier waren wir auf der Suche nach einer Cloud-agnostischen Lösung. Glücklicherweise passt Hashicorp Vault (https://www.vaultproject.io) wunderbar in diese Rolle: Es ist Cloud-agnostisch, kann sich mit allen Cloud-Anbietern verbinden und ist bereits eine implementierte Option innerhalb des Accelerators. Da das Team, das das Confluent-Konto und die Galapagos-Instanz verwaltet, bereits umfangreiche Erfahrungen mit dem Betrieb von Hashicorp Vault gesammelt hatte, war es für uns ein Kinderspiel, Vault als unser externes KMS zu wählen.
Kurz gesagt, unser Datenaustausch sieht jetzt so aus (vereinfacht und mit weniger Teams und Verbindungen als im echten Leben):
Die Erfahrungen, die wir als Entwickler bisher mit Kafka gemacht haben, sind um Lichtjahre besser als ein selbst entwickeltes serverloses Datenaustauschsystem. Die Entscheidung, mehr als 50 Teams auf Kafka zu migrieren, war ein schwieriger Weg, da das Management auf der Geschäftsseite die Vorteile eines Cloud-agnostischen Systems nicht von Anfang an verstanden hat. Wir sind uns jedoch darüber im Klaren, dass technische Migrationen immer die Geschäftsziele unterstützen sollten. Confluent Kafka wird die Entwicklungszyklen beschleunigen, und wir sind sehr zuversichtlich, dass es viel robuster ist als eine handgefertigte Lösung. Wir glauben fest an eine wartungsarme Software, die leicht anpassbar ist und schnell auf geschäftliche Anforderungen reagieren kann. Kafka unterstützt uns definitiv auf unserem Weg dorthin - und gibt uns auch das Vertrauen, neue Funktionen schneller zu implementieren, da wir viele nicht-funktionale Anforderungen (z.B. Replay, Verschlüsselung) nicht selbst implementieren müssen. Kafka lässt sich viel besser skalieren als die meisten anderen Datenaustauschplattformen, da es kein HTTP für den Datenaustausch verwendet und einen unglaublich schnellen Durchsatz bietet.
Wir sind sehr gespannt, wie wir uns mit Kafka in Zukunft entwickeln werden!
Möchtes du Teil des Teams werden?
We have received your feedback.