Echtzeitabfragen im großen Maßstab verstehen

In diesem Dokument finden Sie eine Anleitung zum Skalieren Ihrer serverlosen Anwendung über Tausende von Vorgängen pro Sekunde oder Hunderttausende gleichzeitiger Nutzer. Dieses Dokument enthält weiterführende Themen zur Sie das System im Detail verstehen. Wenn Sie gerade erst mit Cloud Firestore finden Sie in der Kurzanleitung.

Cloud Firestore und die Firebase Mobile/Web SDKs sind ein leistungsstarkes Modell für die Entwicklung serverloser Anwendungen, bei denen clientseitiger Code direkt auf die Datenbank. Mit den SDKs können Clients in Echtzeit Aktualisierungen der Daten überwachen. Ich Echtzeit-Updates nutzen, um responsive Apps zu erstellen, die keine Server erfordern und Infrastruktur. Es ist zwar sehr einfach, etwas einzurichten, um die Einschränkungen in den Systemen zu verstehen, aus denen Cloud Firestore besteht damit Ihre serverlose Anwendung skaliert wird und auch bei steigendem Traffic eine gute Leistung erzielt.

In den folgenden Abschnitten finden Sie Tipps zur Skalierung Ihrer App.

Datenbankspeicherort in der Nähe der Nutzer auswählen

Das folgende Diagramm zeigt die Architektur einer Echtzeitanwendung:

Beispiel für eine Echtzeit-App-Architektur

Wenn eine App, die auf dem Gerät eines Nutzers ausgeführt wird (Mobilgerät oder Web), eine Verbindung zu Cloud Firestore wird die Verbindung an einen Cloud Firestore Frontend-Server im selben Region, in der sich Ihre Datenbank befindet. Beispiel: Wenn sich Ihre Datenbank in us-east1 befindet, geht die Verbindung auch zu einem Cloud Firestore-Frontend auch in us-east1. Diese Verbindungen sind und bleiben geöffnet, bis sie von der App explizit geschlossen werden. Die Front-End liest Daten aus den zugrunde liegenden Cloud Firestore-Speichersystemen.

Die Entfernung zwischen dem physischen Standort eines Nutzers und dem Speicherort der Cloud Firestore-Datenbank wirkt sich auf die Latenz aus, die der Nutzer erfährt. Ein Nutzer in Indien, dessen App mit einer Datenbank in einer Google Cloud-Region in Nordamerika kommuniziert, könnte beispielsweise feststellen, dass die App langsamer und weniger reaktionsschnell ist als wenn sich die Datenbank näher befindet, z. B. in Indien oder in einem anderen Teil Asiens.

Einhaltung von Zuverlässigkeitsvorgaben

Die folgenden Themen verbessern oder beeinflussen die Zuverlässigkeit Ihrer App:

Offlinemodus aktivieren

Die Firebase SDKs ermöglichen Offline-Datenpersistenz. Wenn die App auf dem Gerät des Nutzers keine Verbindung zu Cloud Firestore herstellen, Die Anwendung bleibt nutzbar, weil mit lokal zwischengespeicherten Daten gearbeitet wird. Dadurch wird sichergestellt, dass auch wenn die Internetverbindung schlecht oder unterbrochen ist. mehrere Stunden oder Tage lang vollständig den Zugriff verlieren. Weitere Informationen zu Informationen zum Aktivieren des Offlinemodus finden Sie unter Offlinedaten aktivieren.

Automatische Wiederholungsversuche

Die Firebase SDKs kümmern sich um Wiederholungsversuche und die Wiederherstellung unterbrochener Verbindungen. So können Sie vorübergehende Fehler vermeiden, durch einen Neustart von Servern oder Netzwerkproblemen zwischen Client und Datenbank.

Regionale und multiregionale Standorte auswählen

Bei der Auswahl zwischen regionalen und multiregionalen Standorten gibt es mehrere Abwägungen. Der Hauptunterschied besteht darin, wie Daten repliziert werden. Dieses für die Verfügbarkeitsgarantien Ihrer App. Eine multiregionale Instanz sorgt für eine höhere Bereitstellungs- und Langlebigkeit Ihrer Daten, der Kompromiss sind die Kosten.

Das Echtzeit-Abfragesystem verstehen

Echtzeitabfragen, auch Snapshot-Listener genannt, ermöglichen es der App, in der Datenbank ändern und Benachrichtigungen mit niedriger Latenz erhalten, Änderungen. Eine App kann dasselbe Ergebnis erzielen, indem sie die Datenbank regelmäßig auf Updates prüft. Das ist jedoch oft langsamer, teurer und erfordert mehr Code. Für Beispiele für die Einrichtung und Verwendung von Echtzeitabfragen finden Sie unter Echtzeitinformationen erhalten In den folgenden Abschnitten erfahren Sie mehr über die Funktionsweise von Snapshot-Listenern und einige Best Practices für die Skalierung von Echtzeitabfragen bei gleichzeitiger Beibehaltung der Leistung.

Stell dir zwei Nutzer vor, die sich Cloud Firestore über eine App, die mit einem der mobilen SDKs erstellt wurde.

Client A schreibt in die Datenbank, um Dokumente in einer Sammlung hinzuzufügen und zu aktualisieren. mit dem Namen chatroom:

collection chatroom:
    document message1:
      from: 'Sparky'
      message: 'Welcome to Cloud Firestore!'

    document message2:
      from: 'Santa'
      message: 'Presents are coming'

Client B wartet mit einem Snapshot-Listener auf Aktualisierungen in derselben Sammlung. Kunde B wird sofort benachrichtigt, wenn jemand eine neue Nachricht erstellt. Das folgende Diagramm zeigt die Architektur hinter einem Snapshot-Listener:

Architektur einer Snapshot-Listener-Verbindung

Die folgende Ereignissequenz findet statt, wenn Client B einen Snapshot verbindet Listener für die Datenbank:

  1. Client B öffnet eine Verbindung zu Cloud Firestore und registriert einen indem Sie onSnapshot(collection("chatroom")) über das Firebase SDK. Dieser Listener kann stundenlang aktiv bleiben.
  2. Das Cloud Firestore-Frontend fragt das zugrunde liegende Speichersystem ab, um den Datensatz zu initialisieren. Es werden alle übereinstimmenden Ergebnisse geladen. Dokumente. Dies wird als Abfrage bezeichnet. Das System die Leistung der Datenbank auswertet, Firebase-Sicherheitsregeln für um zu prüfen, ob der Nutzer auf diese Daten zugreifen kann. Wenn der Nutzer autorisiert ist, gibt die Datenbank die Daten an den Nutzer zurück.
  3. Die Abfrage von Client B wird dann in den Wartemodus verschoben. Der Listener registriert sich bei einem Abo-Handler und wartet auf Aktualisierungen der Daten.
  4. Client A sendet jetzt einen Schreibvorgang, um ein Dokument zu ändern.
  5. Die Datenbank überträgt die Dokumentänderung Speichersystem.
  6. Transaktionsweise überträgt das System dasselbe Update an eine interne changelog. Das Änderungsprotokoll legt eine strikte Reihenfolge der Änderungen fest, sie passieren.
  7. Beim Änderungsprotokoll werden die aktualisierten Daten dann auf einen Pool von Abonnements ausgeweitet. Handler.
  8. Ein umgekehrter Abfrage-Matcher wird ausgeführt, um festzustellen, ob das aktualisierte Dokument übereinstimmt. Alle aktuell registrierten Snapshot-Listener. In diesem Beispiel enthält das Dokument entspricht dem Snapshot-Listener von Client B. Wie der Name schon sagt, können Sie sich den umgekehrten Abfrageabgleich als eine normale Datenbankabfrage vorstellen, die aber in umgekehrter Reihenfolge ausgeführt wird. Anstatt in Dokumenten nach übereinstimmenden Dokumenten zu suchen, Abfragen, um diejenigen zu finden, die mit einem eingehenden Dokument übereinstimmen. Bei einer Übereinstimmung leitet das System das betreffende Dokument an die Snapshot-Listener weiter. Anschließend wertet das System die Firebase-Sicherheitsregeln der Datenbank aus. damit nur autorisierte Nutzer die Daten erhalten.
  9. Das System leitet die Dokumentaktualisierung an das SDK auf dem Gerät von Client B weiter und wird der onSnapshot-Callback ausgelöst. Wenn die lokale Persistenz aktiviert ist, wendet das Update auch auf den lokalen Cache an.

Ein wichtiger Teil der Skalierbarkeit von Cloud Firestore hängt von der Verzweigung vom Änderungslog an die Abo-Handler und die Frontend-Server ab. Die Durch Fan-Out kann eine einzelne Datenänderung effizient weitergegeben werden und Millionen von Echtzeitabfragen und vernetzte Nutzer. Durch die Ausführung vieler Repliken all dieser Komponenten in mehreren Zonen (oder mehreren Regionen im Fall einer multiregionalen Bereitstellung) wird mit Cloud Firestore eine hohe Verfügbarkeit und Skalierbarkeit erreicht.

Alle Lesevorgänge, die über mobile und Web-SDKs ausgeführt werden, folgen dem oben beschriebenen Modell. Sie führen eine Abfrageabfrage gefolgt vom Überwachungsmodus durch. um Konsistenzgarantien zu gewährleisten. Das gilt auch für Echtzeit-Zuhörer, Aufrufe zum Abrufen eines Dokuments und One-Shot-Abfragen. Sie können sich die Abrufvorgänge einzelner Dokumente und einmalige Abfragen als kurzlebige Snapshot-Listener vorstellen, die ähnliche Leistungseinschränkungen haben.

Best Practices für die Skalierung von Echtzeitabfragen anwenden

Wenden Sie die folgenden Best Practices an, um skalierbare Echtzeitabfragen zu entwerfen.

Hohe Anzahl von Schreibvorgängen im System verstehen

In diesem Abschnitt erfahren Sie, wie das System auf eine steigende Zahl von Anzahl der Schreibanfragen.

Die Cloud Firestore-Änderungsprotokolle, auf denen die Echtzeitabfragen basieren automatisch horizontal skaliert werden, wenn der Schreib-Traffic steigt. Wenn die Schreibrate für eine Datenbank über die Kapazität eines einzelnen Servers hinausgeht, wird der Änderungsverlauf auf mehrere Server aufgeteilt und die Abfrageverarbeitung beginnt, Daten von mehreren Abo-Handlern anstelle von einem zu verwenden. Aus Sicht des Clients und des SDKs ist das alles transparent und es sind keine Maßnahmen erforderlich, wenn es zu Aufteilungen kommt. Das folgende Diagramm zeigt, Echtzeitabfragen skalieren:

Architektur des Fan-Outs für Änderungslogs

Mit Autoscaling können Sie den Schreibtraffic uneingeschränkt erhöhen, aber wenn der Verkehr zunimmt, kann es eine Weile dauern, bis das System reagiert. Folgen Sie den Empfehlungen der 5-5-5-Regel, um Hotspots zu vermeiden. Key Visualizer ist ein ein nützliches Tool zur Analyse von Schreib-Hotspots.

Viele Apps haben ein vorhersehbares organisches Wachstum, das Cloud Firestore ohne Vorsichtsmaßnahmen einzugehen. Batch-Arbeitslasten wie das Importieren eines großen Dataset jedoch die Zahl der Schreibvorgänge zu schnell erhöhen kann. Achten Sie bei der Entwicklung Ihrer App darauf, wissen, woher der Schreib-Traffic stammt.

Verstehen, wie Schreib- und Lesevorgänge interagieren

Sie können sich das Echtzeit-Abfragesystem als eine Pipeline vorstellen, die eine Verbindung mit Lesern kommunizieren. Jedes Mal, wenn ein Dokument erstellt, aktualisiert oder gelöscht wird, wird die Änderung vom Speichersystem auf das aktuell registrierte System übertragen zu hören. Die Struktur des Änderungsprotokolls von Cloud Firestore garantiert starke Konsistenz, was bedeutet, dass Ihre App nie Benachrichtigungen Aktualisierungen, die nicht in der richtigen Reihenfolge im Vergleich zum Zeitpunkt des Commits für die Daten in der Datenbank sind Änderungen. Dies vereinfacht die App-Entwicklung, da Grenzfälle in Bezug auf die Datenkonsistenz vermieden werden.

Diese verbundene Pipeline bedeutet, dass ein Schreibvorgang oder Sperrenkonflikte, kann sich negativ auf Lesevorgänge auswirken. Wenn Schreibvorgänge fehlschlagen oder eine Drosselung auftritt, kann ein Lesevorgang auf konsistente Daten aus dem Änderungsprotokoll wartet. Wenn das der Fall ist, Ihrer Anwendung können Sie sowohl langsame Schreibvorgänge als auch korrelierte langsame Reaktionen sehen. Mal für die Abfragen. Die Vermeidung von Hotspots ist der Schlüssel, um aus diesem Problem.

Dokumente und Schreibvorgänge klein halten

Wenn Sie Anwendungen mit Snapshot-Listenern erstellen, sollen Nutzer sich schnell über Datenänderungen informieren. Versuchen Sie, die Dinge klein zu halten. Die kann das System kleine Dokumente mit einer großen Anzahl von Feldern schnell ändern. Größere Dokumente mit Hunderten von Feldern und großen Datenmengen dauern länger zu verarbeiten.

Gleichermaßen sollten Sie kurze, schnelle Commit- und Schreibvorgänge bevorzugen, um die Latenz niedrig zu halten. Große Batches können aus Sicht des Autors zu einem höheren Durchsatz führen aber die Benachrichtigungszeit für Snapshot-Listener verlängern. Dies ist im Vergleich zur Verwendung anderer Datenbanksysteme, können Sie die Leistung mit Batching verbessern.

Effiziente Zuhörer verwenden

Wenn die Schreibraten für Ihre Datenbank steigen, verteilt Cloud Firestore die Datenverarbeitung auf viele Server. Der Sharding-Algorithmus von Cloud Firestore versucht, Daten aus derselben Sammlung oder Sammlungsgruppe auf demselben Änderungsprotokollserver zu speichern. Die versucht das System, den möglichen Schreibdurchsatz zu maximieren, während die Anzahl so wenig Server wie möglich an der Verarbeitung einer Anfrage beteiligt sind.

Bestimmte Muster können jedoch zu einem suboptimalen Verhalten für Snapshots führen. zu hören. Wenn Ihre App die meisten Daten z. B. auf einem muss der Listener möglicherweise eine Verbindung zu vielen Servern herstellen, um alle Daten, die es benötigt. Dies gilt auch dann, wenn Sie einen Abfragefilter anwenden. Verbinden... erhöht das Risiko langsamerer Antworten.

Um diese langsameren Antworten zu vermeiden, entwerfen Sie Ihr Schema und Ihre Anwendung so, dass das System die Hörer bedienen können, ohne viele verschiedene Server nutzen zu müssen. Es könnte funktionieren Ihre Daten am besten in kleinere Sammlungen mit geringeren Schreibraten aufzuteilen.

Das ist vergleichbar mit Leistungsabfragen, in einer relationalen Datenbank, die vollständige Tabellenscans erfordern. In einer relationalen entspricht eine Abfrage, die einen vollständigen Tabellenscan erfordert, Snapshot-Listener, der sich eine Sammlung mit hoher Abwanderung ansieht. Die Leistung ist möglicherweise langsam. im Vergleich zu einer Abfrage, die die Datenbank mit einem spezifischeren Index verarbeiten kann. Eine Abfrage mit einem spezifischeren Index ist wie ein Snapshot-Listener, ein einzelnes Dokument oder eine Sammlung, die sich seltener ändert. Sie sollten Ihre App testen, um das Verhalten und die Anforderungen Ihres Anwendungsfalls bestmöglich zu verstehen.

Schnelle Abfrage von Abfragen

Ein weiterer wichtiger Bestandteil von responsiven Echtzeitabfragen ist es, sicherzustellen, zum Bootstrapping der Daten schnell und effizient ist. Wenn ein neuer Snapshot-Listener zum ersten Mal eine Verbindung herstellt, muss der Listener den Parameter und an das Gerät des Nutzers senden. Langsame Abfragen verlangsamen Ihre App. Dazu gehören z. B. Suchanfragen, viele Dokumente oder Abfragen zu lesen, die nicht die entsprechenden Indexe verwenden.

Ein Listener kann auch von einem Überwachungsstatus in einen Abfragestatus unter unter bestimmten Umständen. Das geschieht automatisch und ist für alle SDKs und deine App Die folgenden Bedingungen können einen Abfragestatus auslösen:

  • Das System gleicht aufgrund von Laständerungen ein Änderungsprotokoll neu aus.
  • Hotspots verursachen fehlgeschlagene oder verzögerte Schreibvorgänge in die Datenbank.
  • Vorübergehende Serverneustarts wirken sich vorübergehend auf Listener aus.

Wenn Ihre Abfrageabfragen schnell genug sind, wird ein Abfragestatus transparent. für die Nutzer Ihrer App.

Langlebige Zuhörer bevorzugen

Es ist oft am wichtigsten, die Zuhörer so lange wie möglich zu öffnen und zu halten. kostengünstige Methode zum Erstellen von Apps, für die Cloud Firestore verwendet wird. Bei der Verwendung von Cloud Firestore werden Ihnen nur die Dokumente in Rechnung gestellt, die an Ihre App zurückgegeben werden, nicht die Aufrechterhaltung einer offenen Verbindung. Ein langlebiger Snapshot-Listener liest die für die Abfrage während der gesamten Lebensdauer benötigt werden. Dieses enthält einen anfänglichen Abfragevorgang, gefolgt von Benachrichtigungen, wenn die Daten tatsächlich ändert. Bei einmaligen Abfragen werden dagegen Daten noch einmal gelesen, die sich möglicherweise nicht geändert haben, seit die App die Abfrage zuletzt ausgeführt hat.

Wenn Ihre App eine hohe Datenrate verbrauchen muss, sind Snapshot-Listener möglicherweise nicht geeignet. Wenn Ihr Anwendungsfall z. B. viele Dokumente über einen längeren Zeitraum über eine Verbindung pro Sekunde, sollten Sie sich für einmalige Abfragen entscheiden, die mit geringerer Häufigkeit ausgeführt werden.

Weitere Informationen