Airbnb

Riverbed: Optimierung des Datenzugriffs im Airbnb Maßstab

Stefan
11 Min Read
Airbnb

Ein Überblick über das Daten-Framework von Airbnb für schnellere und zuverlässigere leseintensive Arbeitslasten.

Von: Sivakumar Bhavanari, Krish Chainani, Victor Chen, Yanxi Chen, Xiangmin Liang, Anton Panasenko, Sonia Stan, Peggy Zheng und Amre Shakim

Überblick

Die Weiterentwicklung von Airbnb und seinem Tech-Stack erfordert eine skalierbare und zuverlässige Grundlage, die den Zugriff und die Verarbeitung komplexer Datensätze vereinfacht. Hier kommt Riverbed ins Spiel, ein Datenframework, das auf schnelle Leseleistung und hohe Verfügbarkeit ausgelegt ist. In dieser Blogserie stellen wir Riverbed vor und beleuchten seine Ziele, sein Design und seine Funktionen.

Warum wurde Riverbed erstellt?

Das Wachstum von Airbnb hat die Anzahl der von uns betriebenen Datenbanken, die Vielfalt der von ihnen bedienten Datentypen und die Hinzufügung datenintensiver Dienste für den Zugriff auf diese Datenbanken beschleunigt, was zu einer komplexen Dateninfrastruktur und einer schwierigen serviceorientierten Architektur (SOA) geführt hat managen.

Abbildung 1. Airbnb-SOA Abhängigkeitsdiagramm

Wir haben ein spezifisches Muster von Abfragen festgestellt, die den Zugriff auf mehrere Datenquellen erfordern, eine komplizierte Geschäftslogik für die Hydratation aufweisen und komplexe Datentransformationen beinhalten, die schwer zu optimieren sind. Airbnb-Workloads nutzen diese Abfragen im Lesepfad stark aus, was die Leistungsprobleme verschärft.

Lassen Sie uns untersuchen, wie das Zahlungssystem von Airbnb nach dem Übergang von einem Monolithen zu einer SOA vor Herausforderungen stand. Das Zahlungssystem bei Airbnb ist komplex und erfordert den Zugriff auf mehrere Datenquellen. Gleichzeitig ist eine komplexe Geschäftslogik erforderlich, um Gebühren, Transaktionsdaten, Währungen, Beträge und Gesamteinnahmen zu berechnen. Nach der SOA-Migration waren die für diese Berechnungen benötigten Daten jedoch über verschiedene Dienste und Tabellen verteilt. Dies machte es insbesondere bei leseintensiven Anfragen zu einer Herausforderung, alle erforderlichen Informationen auf einfache und leistungsstarke Weise bereitzustellen. Um mehr über diese und andere Herausforderungen zu erfahren, empfehlen wir die Lektüre dieses Blogbeitrags.

Eine mögliche Lösung besteht darin, die häufigsten Abfragen zu registrieren, die denormalisierten Zahlungsdaten vorab zu berechnen und eine Tabelle zum Speichern der berechneten Ergebnisse bereitzustellen, um sie für leseintensive Anforderungen zu optimieren. Dies wird als materialisierte Ansicht bezeichnet und wird von vielen Datenbanken als integrierte Funktionalität bereitgestellt.

In einer SOA-Umgebung, in der Daten auf mehrere Datenbanken verteilt sind, hängen die von uns erstellten Ansichten von Daten aus verschiedenen Quellen ab. Diese Technik ist in der Industrie weit verbreitet und wird normalerweise mithilfe einer Kombination aus Change-Data-Capture (CDC), Stream-Verarbeitung und einer Datenbank zur Speicherung der Endergebnisse implementiert.

Lambda und Kappa sind zwei Echtzeit-Datenverarbeitungsarchitekturen. Lambda kombiniert Batch- und Echtzeitverarbeitung für die effiziente Verarbeitung großer Datenmengen, während Kappa sich ausschließlich auf die Streaming-Verarbeitung konzentriert. Die Einfachheit von Kappa bietet eine bessere Wartbarkeit, stellt jedoch Herausforderungen bei der Implementierung von Backfill-Mechanismen und der Gewährleistung der Datenkonsistenz dar, insbesondere bei Out-of-Order-Ereignissen.

Um diesen Herausforderungen zu begegnen und die Erstellung und Verwaltung verteilter materialisierter Ansichten zu vereinfachen, haben wir Riverbed entwickelt. Riverbed ist ein Lambda-ähnliches Datenframework, das die Komplexität der Verwaltung materialisierter Ansichten abstrahiert und so schnellere Produktiterationen ermöglicht. In den folgenden Abschnitten besprechen wir die Designentscheidungen von Riverbed und die Kompromisse, die zur Erreichung hoher Leistungs-, Zuverlässigkeits- und Konsistenzziele eingegangen werden.

Flussbett-Design

Überblick

Auf hohem Niveau übernimmt Riverbed die Lambda-Architektur, die aus einer Online-Komponente zur Verarbeitung von Echtzeit-Ereignisänderungen und einer Offline-Komponente zum Auffüllen fehlender Daten besteht. Riverbed bietet Produktingenieuren eine deklarative Schnittstelle zum Definieren der Abfragen und zum Implementieren der Geschäftslogik für die Berechnung mithilfe von GraphQL sowohl für die Online- als auch für die Offline-Komponenten. Unter der Haube führt das Framework die Abfragen effizient aus, berechnet die abgeleiteten Daten und schreibt schließlich in eine oder mehrere festgelegte Senken. Riverbed bewältigt die schwere Arbeit einiger häufiger Herausforderungen datenintensiver Systeme, wie z. B. gleichzeitiges Schreiben, Versionierung, Integrationen mit verschiedenen Infrastrukturkomponenten bei Airbnb, Datenkorrektheitsgarantien, und ermöglicht den Produktteams letztendlich eine schnelle Iteration von Produktfunktionen.

Streaming System

Abbildung 2. Streaming-System

Die Hauptfunktion des Streaming-Systems besteht darin, das Problem der inkrementellen Ansichtsmaterialisierung zu lösen, das auftritt, wenn Änderungen an System-of-Record-Tabellen vorgenommen werden. Um dies zu erreichen, konsumiert das System CDC-Ereignisse (Change-Data-Capture) über ein Kafka-basiertes System. Es wandelt diese Ereignisse in „Benachrichtigungs“-Auslöser um, die bestimmten Dokument-IDs in der Senke zugeordnet sind. Ein „Benachrichtigungs“-Auslöser dient als Signal zum Aktualisieren eines bestimmten Dokuments. Dieser Prozess erfolgt hochparallel bei außer Betrieb befindlichen Batch-Verbrauchern. Innerhalb jedes Stapels werden Benachrichtigungsauslöser dedupliziert, bevor sie in Kafka geschrieben werden.

Ein zweiter Prozess nutzt die zuvor erstellten „Benachrichtigungs“-Trigger. Mithilfe einer Reihe von Verknüpfungen, Datenzusammenfügungen und der Ausführung benutzerdefinierter Vorgänge werden die „Benachrichtigungen“ in ein Dokument umgewandelt. Das resultierende Dokument wird dann in die dafür vorgesehene Spüle abgelassen. Immer wenn eine Änderung an einer System-of-Record-Tabelle auftritt, ersetzt das System das betroffene Dokument durch eine aktuellere Version und sorgt so für letztendliche Konsistenz.

Batch System

Es besteht immer noch die Möglichkeit, dass in der gesamten Pipeline oder aufgrund von Fehlern, beispielsweise in CDC, gelegentlich Ereignisse verloren gehen. Da wir die Notwendigkeit erkannt haben, diese potenziellen Inkonsistenzen zu beheben, haben wir ein Batch-System implementiert, das fehlende Ereignisse aufgrund von Online-Streaming-Änderungen abgleicht. Dieser Prozess hilft dabei, nur die geänderten Daten im Hinblick auf das materialisierte Ansichtsdokument zu identifizieren und bietet einen Mechanismus zum Bootstrapping der materialisierten Ansicht durch einen Backfill. Das Lesen und Verarbeiten großer Datenmengen aus Online-Quellen kann jedoch zu Leistungsengpässen und potenziellen Heterogenitätsproblemen führen, sodass ein direktes Auffüllen oder ein Abgleich aus diesen Quellen nicht möglich ist.

Um diese Herausforderungen zu meistern, nutzt Riverbed Apache Spark in seinen Backfilling- oder Reconciliation-Pipelines und nutzt dabei die täglichen Snapshots, die im Offline-Data Warehouse gespeichert sind. Das Framework generiert Spark SQL basierend auf GraphQL-Abfragen, die von Clients erstellt wurden. Mithilfe der Daten aus dem Warehouse verwendet Riverbed dieselbe Geschäftslogik aus dem Streaming-System erneut, um die Daten umzuwandeln und in Senken zu schreiben.

Abbildung 3. Batch System

Parallelität/Versionierung

In jedem verteilten System können gleichzeitige Updates zu Race Conditions führen, die zu falschen oder inkonsistenten Daten führen. Riverbed vermeidet Race Conditions, indem alle Änderungen für ein bestimmtes Dokument mithilfe von Kafka serialisiert werden. Eingehende Quellmutationen werden zunächst in Zwischenereignisse umgewandelt, die nur die Dokument-ID der Senke enthalten, und in Kafka geschrieben. Anschließend verarbeitet ein sekundärer (Benachrichtigungs-)Prozess diese Zwischenereignisse, materialisiert sie und schreibt sie in die Senke. Da das Kafka-Zwischenthema nach der Dokument-ID des Ereignisses unterteilt ist, werden alle Dokumente mit derselben Dokument-ID seriell von demselben Verbraucher verarbeitet, wodurch das Problem der Race Conditions durch parallele Echtzeit-Streaming-Schreibvorgänge vollständig vermieden wird.

Um parallele Schreibvorgänge zwischen Echtzeit-Streaming und Offline-Jobs zu ermitteln, speichern wir eine auf Zeitstempeln basierende Version in der Senke. Jeder Senkentyp muss Schreibvorgänge nur dann zulassen, wenn die Version größer oder gleich der aktuellen Version ist, wodurch Race-Bedingungen zwischen Streaming- und Batch-Systemen gelöst werden.

Konzeptionell betrachtet Riverbed jede Mutation als einen Hinweis auf eine Veränderung. Der Prozessor verwendet immer Daten aus der wahren Quelle und erstellt daher Senkendokumente im aktuellsten konsistenten Zustand zum Zeitpunkt der Verarbeitung. Jetzt ist die Verarbeitung von Ereignissen idempotent und kann beliebig oft und in beliebiger Reihenfolge durchgeführt werden.

Ergebnisse

Riverbed hat auf Airbnb weitreichende Auswirkungen gehabt. Es verarbeitet derzeit 2,4 Milliarden Ereignisse, schreibt täglich 350 Millionen Dokumente und ermöglicht über 50 materialisierte Ansichten auf Airbnb. Riverbed hilft bei der Bereitstellung von Funktionen wie Zahlungen, Suche in Nachrichten, Darstellung von Bewertungen auf der Eintragsseite und vielen anderen Funktionen rund um Co-Hosting, Reiserouten und interne Produkte.

Zusammenfassung und nächste Schritte

Zusammenfassend stellt Riverbed ein skalierbares und leistungsstarkes Datenframework bereit, das die Effizienz leseintensiver Workloads verbessert. Die Designoptionen von Riverbed bieten eine deklarative Schnittstelle für Produktingenieure, eine effiziente Ausführung von Abfragen und Garantien für die Datenkorrektheit. Dies vereinfacht die Erstellung und Verwaltung verteilter materialisierter Ansichten und ermöglicht Produktteams eine schnelle Iteration von Funktionen. Der Einsatz von Riverbed zur Vorabberechnung von Datenansichten hat bereits zu erheblichen Latenzverbesserungen und einer verbesserten Zuverlässigkeit des Datenflusses geführt und sorgt so für ein schnelleres und zuverlässigeres Erlebnis für die Gastgeber- und Gastgemeinschaften von Airbnb.

In zukünftigen Beiträgen werden wir verschiedene Aspekte von Riverbed detaillierter untersuchen, einschließlich seiner Designüberlegungen, Leistungsoptimierungen und zukünftigen Entwicklungsrichtungen barbie girl.

Danksagungen

All dies war eine bedeutende gemeinsame Anstrengung des Teams und jede Diskussion über leseoptimierte Stores wäre nicht vollständig, ohne die unschätzbaren Beiträge aller Mitglieder des Teams, sowohl in der Vergangenheit als auch in der Gegenwart, anzuerkennen. Großer Dank geht an Will Moss, Krish Chainani, Victor Chen, Sonia Stan, Xiangmin Liang, Siva Bhavanari, Peggy Zheng und Yanxi Chen im Entwicklungsteam; Unterstützung von Juan Tamayo, Zoran Dimitrijevic, Zheng Liu, Chandramouli Rangarajan und Führung von Amre Shakim, Jessica Tai, Parth Shah, Adam Kocoloski, Abhishek Parmar, Bill Farner und Usman Abbasi. Zu guter Letzt möchten wir Shylaja Ramachandra, Lauren Mackevich und Tina Nguyen unseren aufrichtigen Dank für ihre unschätzbare Unterstützung bei der Bearbeitung und Veröffentlichung dieses Beitrags aussprechen. Ihre Beiträge haben die Qualität und Klarheit des Inhalts erheblich verbessert.