Best Practices für Cloud Firestore

Nutzen Sie die hier aufgeführten Best Practices als Kurzreferenz. wenn Sie eine Anwendung erstellen, die Cloud Firestore verwendet.

Datenbankspeicherort

Wählen Sie beim Erstellen Ihrer Datenbankinstanz den Datenbankspeicherort aus, der Ihren Nutzern und Rechenressourcen am nächsten ist. Weit reichende Netzwerk-Hops sind fehleranfälliger und erhöhen die Abfragelatenz.

Wählen Sie zum Maximieren der Verfügbarkeit und Langlebigkeit Ihrer Anwendung einen Standort mit mehreren Regionen aus und platzieren Sie wichtige Rechenressourcen in mindestens zwei Regionen.

Wählen Sie einen regionalen Standort aus, um die Kosten niedrig zu halten, um eine niedrige Schreiblatenz zu erzielen, wenn Ihre Anwendung empfindlich auf Latenz reagiert, oder um die Datenbank gemeinsam mit anderen GCP-Ressourcen am selben Standort zu speichern.

Dokument-IDs

  • Vermeiden Sie die Dokument-IDs . und ...
  • Verwenden Sie in Dokument-IDs keine Schrägstriche (/).
  • Verwenden Sie keine kontinuierlich ansteigenden Dokument-IDs, z. B.:

    • Customer1, Customer2, Customer3, ...
    • Product 1, Product 2, Product 3, ...

    Solche aufeinanderfolgenden IDs können zum Heißlaufen führen, was sich auf die Latenz auswirkt.

Feldnamen

  • Vermeiden Sie die folgenden Zeichen in Feldnamen, da sie zusätzliche Escapezeichen erfordern:

    • Punkt (.)
    • Eckige Klammer links ([)
    • Eckige Klammer rechts (])
    • Sternchen (*)
    • Backtick (`)

Indexe

Schreiblatenz reduzieren

Der Hauptfaktor für die Schreiblatenz ist das Index-Fanout. Die Best Practices für Index-Fanout reduzieren:

  • Festlegen Indexausnahmen auf Sammlungsebene. Deaktivieren Sie einfach die absteigende Sortierung und die Array-Indexierung. Wenn Sie nicht verwendete indexierte Werte entfernen, senken Sie auch die Speicherkosten.

  • Reduzieren Sie die Anzahl der Dokumente in einer Transaktion. Zum Schreiben großer Zahlen von Dokumenten, sollten Sie einen Bulk-Schreiber anstelle des atomaren Batch-Schreibvorgangs verwenden. Schreibende Person.

Indexausnahmen

Bei den meisten Anwendungen sind die automatische Indexierung sowie Fehlermeldungslinks zur Verwaltung der Indexe ausreichend. In den folgenden Fällen können Sie aber Ausnahmen für einzelne Felder hinzufügen:

Fall Beschreibung
Große Stringfelder

Wenn Sie ein Stringfeld haben, das oft lange Stringwerte enthält, die Sie nicht für Abfragen verwenden, können Sie die Speicherkosten senken, indem Sie das Feld von der Indexierung ausnehmen.

Hohe Schreibraten für eine Sammlung, die Dokumente mit aufeinanderfolgenden Werten enthält

Wenn Sie ein Feld indexieren, dessen Werte über die Dokumente einer Sammlung hinweg kontinuierlich zu- oder abnehmen, z. B. im Fall eines Zeitstempels, beträgt die maximale Schreibrate für die Sammlung 500 Schreibvorgänge pro Sekunde. Wenn Sie keine Abfrage basierend auf dem Feld mit aufeinanderfolgenden Werten durchführen, können Sie das Feld von der Indexierung ausnehmen, um dieses Limit zu umgehen.

In einem IoT-Anwendungsfall mit einer hohen Schreibrate kann sich beispielsweise eine Sammlung, die Dokumente mit einem Zeitstempelfeld enthält, dem Limit von 500 Schreibvorgängen pro Sekunde nähern.

TTL-Felder

Wenn Sie TTL-Richtlinien (Gültigkeitsdauer) verwenden, muss das TTL-Feld ein Zeitstempel sein. Die Indexierung für TTL-Felder ist standardmäßig aktiviert und kann die Leistung bei höheren Traffic-Raten beeinträchtigen. Fügen Sie als Best Practice Einzelfeldausnahmen für Ihre TTL-Felder.

Große Array- oder Map-Felder

Große Array- oder Kartenfelder können sich dem Limit von 40.000 Indexeinträgen pro Dokument nähern. Wenn Sie keine Abfragen basierend auf einem großen Array- oder Kartenfeld durchführen, sollten Sie dieses von der Indexierung ausnehmen.

Lese- und Schreibvorgänge

  • Die genaue maximale Rate, mit der eine App ein einzelnes Dokument aktualisieren kann, hängt stark von der Arbeitslast ab. Weitere Informationen finden Sie unter Aktualisierungen für ein einzelnes Dokument.

  • Verwenden Sie sofern verfügbar asynchrone Aufrufe anstelle von synchronen Aufrufen. Asynchrone Aufrufe minimieren die Auswirkung auf die Latenz. Angenommen, eine Anwendung benötigt das Ergebnis eines Dokument-Lookups sowie die Ergebnisse einer Abfrage, bevor eine Antwort gerendert wird. Wenn der Lookup und die Abfrage keine Datenabhängigkeit haben, muss nicht synchron auf den Abschluss des Lookups gewartet werden, bevor die Abfrage initiiert wird.

  • Verwenden Sie keine Offsets. Verwenden Sie stattdessen Cursors. Wenn Sie einen Offset verwenden, werden die übersprungenen Dokumente nicht an Ihre Anwendung zurückgegeben, werden aber intern abgerufen. Die übersprungenen Dokumente wirken sich auf die Latenz der Abfrage aus und Ihrer Anwendung werden die zum Abrufen erforderlichen Lesevorgänge in Rechnung gestellt.

Wiederholungsversuche für Transaktionen

Die Cloud Firestore SDKs und der Client Fehler beim automatischen Wiederholen von Bibliotheken um vorübergehende Fehler zu vermeiden. Wenn Ihre Anwendung auf Cloud Firestore über die REST oder RPC APIs direkt und nicht über ein SDK, Anwendung sollten Transaktionswiederholungen implementieren, um die Zuverlässigkeit zu erhöhen.

Echtzeitaktualisierungen

Best Practices für Echtzeitaktualisierungen findest du unter Echtzeitabfragen in großem Umfang verstehen

Skalierbares Programmdesign

Die folgenden Best Practices beschreiben, wie Situationen vermieden werden können, die zu Konflikten führen.

Aktualisierungen für ein einzelnes Dokument

Überlegen Sie beim Entwerfen Ihrer App, wie schnell einzelne Dokumente aktualisiert werden sollen. Die beste Möglichkeit, die Leistung Ihrer Arbeitslast zu charakterisieren, ist das Ausführen einer Last Tests durchführen. Die genaue maximale Rate, mit der eine App ein einzelnes Dokument aktualisieren kann hängt stark von der Arbeitslast ab. Zu den Faktoren gehören die Schreibrate, Konflikte zwischen Anfragen und die Anzahl der betroffenen Indexe.

Ein Schreibvorgang für ein Dokument aktualisiert das Dokument und alle zugehörigen Indexe. Cloud Firestore wendet den Schreibvorgang synchron auf ein Quorum von Replicas an. Ab einer ausreichend hohen Schreibrate Konflikte, eine höhere Latenz oder andere Fehler auftreten.

Hoher Lese-, Schreib- und Löschraten für einen kleinen Dokumentbereich

Vermeiden Sie hohe Lese- oder Schreibraten bei Dokumenten, die lexikografisch eng beieinanderliegen. Andernfalls treten bei Ihrer Anwendung Konfliktfehler auf. Dieses Problem wird als Heißlaufen bezeichnet. Dazu kann es bei Ihrer Anwendung kommen, wenn sie eine der folgenden Aktionen ausführt:

  • Sie erstellt neue Dokumente mit einer sehr hohen Rate und ordnet ihre eigenen monoton ansteigenden IDs zu.

    Cloud Firestore weist Dokument-IDs mithilfe eines Streualgorithmus zu. Wenn Sie neue Dokumente mit automatischen Dokument-IDs erstellen, sollte es bei Schreibvorgängen nicht zu einem Heißlaufen kommen.

  • Sie erstellt neue Dokumente in einer Sammlung mit wenigen Dokumenten mit einer hohen Rate.

  • Sie erstellt mit einer sehr hohen Rate neue Dokumente mit einem kontinuierlich zunehmenden Feld, z. B. einem Zeitstempel.

  • Sie löscht Dokumente in einer Sammlung mit einer hohen Rate.

  • Sie schreibt mit einer sehr hohen Rate in die Datenbank, ohne den Traffic nach und nach zu erhöhen.

Überspringen gelöschter Daten vermeiden

Vermeiden Sie Abfragen, bei denen kürzlich gelöschte Daten übersprungen werden. Bei einer Abfrage müssen möglicherweise eine große Anzahl von Indexeinträgen übersprungen werden, wenn die ersten Abfrageergebnisse vor Kurzem gelöscht wurden.

Ein Beispiel für eine Arbeitslast, bei der möglicherweise viele gelöschte Daten übersprungen werden müssen, ist eine, bei der versucht wird, die ältesten Arbeitselemente in der Warteschlange zu finden. Die Abfrage könnte so aussehen:

docs = db.collection('WorkItems').order_by('created').limit(100)
delete_batch = db.batch()
for doc in docs.stream():
  finish_work(doc)
  delete_batch.delete(doc.reference)
delete_batch.commit()

Bei jeder Ausführung dieser Abfrage werden die Indexeinträge nach dem created für alle kürzlich gelöschten Dokumente. Dadurch werden Abfragen verlangsamt.

Verwenden Sie die Methode start_at, um den besten Ausgangspunkt für die Leistungsverbesserung zu finden. Beispiel:

completed_items = db.collection('CompletionStats').document('all stats').get()
docs = db.collection('WorkItems').start_at(
    {'created': completed_items.get('last_completed')}).order_by(
        'created').limit(100)
delete_batch = db.batch()
last_completed = None
for doc in docs.stream():
  finish_work(doc)
  delete_batch.delete(doc.reference)
  last_completed = doc.get('created')

if last_completed:
  delete_batch.update(completed_items.reference,
                      {'last_completed': last_completed})
  delete_batch.commit()

HINWEIS: Das obige Beispiel verwendet ein kontinuierlich ansteigendes Feld, das ein Anti-Muster für hohe Schreibraten ist.

Traffic erhöhen

Sie sollten den Traffic zu neuen Sammlungen schrittweise erhöhen oder Dokumente schließen, um Cloud Firestore ausreichend Zeit für die Vorbereitung zu geben Dokumente für erhöhten Traffic zu erstellen. Wir empfehlen, bei einer neuen Sammlung mit maximal 500 Vorgängen pro Sekunde zu beginnen und den Traffic dann alle 5 Minuten um 50 % zu erhöhen. Auf ähnliche Weise können Sie die Zahl der Schreibzugriffe erhöhen, die Cloud Firestore-Standardlimits. Achten Sie darauf, dass die Vorgänge relativ gleichmäßig über den Schlüsselbereich verteilt sind. Dies wird als "500/50/5"-Regel bezeichnet.

Traffic zu einer neuen Sammlung migrieren

Die schrittweise Erhöhung ist besonders wichtig, wenn Sie den Anwendungs-Traffic von einer Sammlung zu einer anderen migrieren. Eine einfache Möglichkeit zur Umsetzung dieser Migration besteht darin, aus der alten Sammlung zu lesen. Wenn das Dokument nicht vorhanden ist, lesen Sie aus der neuen Sammlung. Dies kann aber zu einem plötzlichen Anstieg des Traffics zu lexikografisch eng beieinanderliegenden Dokumenten in der neuen Sammlung führen. Cloud Firestore die neue Sammlung unter Umständen nicht effizient auf den erhöhten Traffic vorbereiten, vor allem, wenn sie nur wenige Dokumente enthält.

Ein ähnliches Problem kann auftreten, wenn Sie die Dokument-IDs vieler Dokumente innerhalb einer Sammlung ändern.

Die beste Strategie für die Migration des Traffics zu einer neuen Sammlung hängt von Ihrem Datenmodell ab. Unten sehen Sie eine Beispielstrategie, die als parallele Lesevorgänge bezeichnet wird. Sie müssen prüfen, ob diese Strategie für Ihre Daten effektiv ist. Ein wichtiger Aspekt sind die Kosten paralleler Vorgänge während der Migration.

Parallele Lesevorgänge

Um für das Migrieren des Traffics zu einer neuen Sammlung parallele Lesevorgänge zu implementieren, lesen Sie zuerst aus der alten Sammlung. Wenn das Dokument fehlt, lesen Sie aus der neuen Sammlung. Eine hohe Rate von Lesevorgängen in nicht vorhandenen Dokumenten kann zum Heißlaufen führen. Achten Sie daher darauf, dass die Last für die neue Sammlung nur allmählich erhöht wird. Eine bessere Strategie besteht darin, das alte Dokument in die neue Sammlung zu kopieren und dann zu löschen. Erhöhen Sie parallele Lesevorgänge nach und nach, um sicherzustellen, dass Cloud Firestore den Traffic zur neuen Sammlung verarbeiten kann.

Ein mögliches Vorgehen zur schrittweisen Steigerung von Lese- oder Schreibvorgängen für eine neue Sammlung ist die Verwendung eines deterministischen Hash-Werts der Nutzer-ID. Damit kann per Zufallsprinzip ein Teil der Nutzer ausgewählt werden, die versuchen, in neue Dokumente zu schreiben. Achten Sie darauf, dass das Ergebnis des Nutzer-ID-Hash-Werts weder durch die Funktion noch durch das Nutzerverhalten verzerrt wird.

Führen Sie einen Batchjob aus, durch den alle Ihre Daten aus den alten Dokumenten in die neue Sammlung kopiert werden. Der Batchjob sollte Schreibvorgänge für aufeinanderfolgende Dokument-IDs vermeiden, damit es zu keinem Heißlaufen kommt. Wenn der Batchjob abgeschlossen ist, können Sie nur aus der neuen Sammlung lesen.

Eine Verfeinerung dieser Strategie besteht darin, kleine Batches von Nutzern gleichzeitig zu migrieren. Fügen Sie dem Nutzerdokument ein Feld hinzu, das den Migrationsstatus des entsprechenden Nutzers verfolgt. Wählen Sie einen Batch von zu migrierenden Nutzern basierend auf einem Hash-Wert der Nutzer-ID aus. Verwenden Sie einen Batchjob, um Dokumente für diesen Batch von Nutzern zu migrieren, und verwenden Sie parallele Lesevorgänge für Nutzer, die gerade migriert werden.

Beachten Sie, dass ein Rollback nur dann problemlos ausgeführt werden kann, wenn Sie bei der Migration doppelte Schreibvorgänge für die alten wie für die neuen Entitäten vornehmen. Dadurch würde sich Angefallene Kosten in Höhe von Cloud Firestore.

Datenschutz

  • Vermeiden Sie die Speicherung vertraulicher Informationen in einer Cloud-Projekt-ID. Eine Cloud-Projekt-ID könnte über die Lebensdauer Ihres Projekts hinaus beibehalten werden.
  • Als Best Practice für die Datencompliance empfehlen wir, keine vertraulichen Daten zu speichern Informationen in Dokumentnamen und Dokumentfeldnamen.

Unbefugten Zugriff verhindern

Verhindern Sie nicht autorisierte Vorgänge in Ihrer Datenbank mit Cloud Firestore Security Rules Beispielsweise lässt sich durch die Verwendung von Regeln ein Szenario vermeiden, in dem ein und der böswillige Nutzer wiederholt Ihre gesamte Datenbank herunterlädt.

Weitere Informationen zur Verwendung von Cloud Firestore Security Rules