IBM Cloudant in der Praxis

Das Dokument IBM Cloudant in der Praxis ist das dritte Dokument mit bewährten Verfahren in der Reihe. Es zeigt Ihnen die folgenden bewährten Verfahren:

  • So vermeiden Sie Konflikte.
  • Funktionsweise des Löschens von Dokumenten
  • Worauf Sie bei Updates achten müssen
  • Wie man in einer letztendlich konsistenten Umgebung arbeitet.
  • Vorgehensweise zum Einrichten der Replizierung.
  • So verwenden Sie die Massen-API.
  • Warum Sie Q, R und N nicht ändern dürfen.
  • Funktionsweise von Ratenbegrenzungen
  • Welche Protokollierung wird verfolgt?
  • So komprimieren Sie Ihren HTTP Verkehr.

Weitere Informationen finden Sie unter Datenmodellierung oder Indexierung und Abfrage.

Der Inhalt dieses Dokuments wurde ursprünglich von Stefan Kruger als Blogbeitrag Best Practice und Worst Practice am 21. November 2019 geschrieben.

Konflikte vermeiden

IBM Cloudant ist so konzipiert, dass Konflikte als natürlicher Zustand von Daten in einem verteilten System behandelt werden. Dieses Feature ist ein leistungsfähiges Feature, mit dem ein IBM Cloudant-Cluster ständig die Hochverfügbarkeit aufrechterhalten kann. Es wird jedoch angenommen, dass Konflikte immer noch recht selten sind. Die Verfolgung von Konflikten im Kern von IBM Cloudant verursacht erhebliche Kosten, die damit verbunden sind.

Es ist durchaus möglich (aber keine gute Idee!), Konflikte zu ignorieren. Die Datenbank arbeitet fröhlich weiter, indem sie eine zufällige, aber deterministische Revision von Konfliktdokumenten auswählt. Da die Anzahl der nicht aufgelösten Konflikte jedoch zunimmt, fällt die Leistung der Datenbank in ein schwarzes Loch, insbesondere wenn Sie replizieren.

Als Entwickler liegt es in Ihrer Verantwortung, auf Konflikte zu prüfen und diese zu lösen, oder, besser noch, Datenmodelle einzusetzen, die Konflikte unmöglich machen.

Wenn Sie routinemäßig Konflikte erzeugen, müssen Sie wirklich Modelländerungen erwägen: Selbst wenn Sie Ihre Konflikte fleißig lösen, verbleiben die Konfliktzweige in der Revisionsstruktur, ohne dass eine einfache Möglichkeit besteht, diese zu bereinigen. Weitere Informationen finden Sie auf den folgenden Websites:

  • IBM Cloudant Leitfaden für Konflikte
  • IBM Cloudant-Handbuch zu Versionen und MVCZ
  • Dreiteilige Blogserie über Konflikte

Durch das Löschen von Dokumenten werden diese nicht gelöscht

Wenn Sie ein Dokument aus einer IBM Cloudant-Datenbank löschen, wird es nicht gelöscht. Das Löschen wird implementiert, indem eine neue Überarbeitung des zu löschenden Dokuments mit einem hinzugefügten Feld _deleted: true geschrieben wird. Diese spezielle Überarbeitung wird als tombstone bezeichnet. Tombstones nehmen weiterhin Platz ein und werden auch vom Replikator übergeben.

Modelle, die auf häufigen Löschungen von Dokumenten basieren, sind für IBM Cloudant nicht geeignet. Weitere Informationen finden Sie unter IBM Cloudant tombstone Dokumentation.

Seien Sie vorsichtig mit Updates

Es ist am Ende teurer, vorhandene Dokumente zu mutieren als neue zu erstellen. IBM Cloudant muss immer die Dokumentbaumstruktur Struktur um beibehalten. Diese Regel gilt auch, wenn interne Knoten in der Baumstruktur aus ihren Nutzdaten entfernt werden. Wenn Sie feststellen, dass Sie lange Revisionsbaumstrukturen erstellen, leidet die Replikationsleistung. Außerdem ist es wahrscheinlicher, dass Aktualisierungskonflikte auftreten, wenn die Aktualisierungsfrequenz höher ist als zum Beispiel ein- oder zweimal alle paar Sekunden.

Modelle bevorzugen, die nicht veränderbar sind.

Wenn Sie die folgenden Abschnitte lesen ( Dokumente werden nicht gelöscht ) und Vorsicht bei Aktualisierungenverwenden, stellen sie eine offensichtliche Frage. Diese heißt, wächst das Dataset unbegrenzt, wenn mein Modell unveränderlich ist? Wenn Sie akzeptieren, dass Löschungen die gelöschten Daten nicht vollständig bereinigen und dass Aktualisierungen nicht in Bezug auf das Datenvolumenwachstum aktualisiert werden, gibt es keinen großen Unterschied. Die Verwaltung des Datenvolumens im Laufe der Zeit erfordert unterschiedliche Verfahren.

Die einzige Möglichkeit, Speicherplatz freizugeben, besteht darin, Datenbanken und nicht Dokumente zu löschen. Sie können nur Gewinnerrevisionen in einer neuen Datenbank replizieren und die alten löschen, um die anhaltenden Löschungen und Konflikte zu beseitigen. Oder Sie können es in Ihr Modell integrieren, um regelmäßig neue Datenbanken zu starten (z. B. "Jahresdaten") und veraltete Daten zu archivieren (oder zu entfernen), sofern Ihr Anwendungsfall dies zulässt.

Sukzessive Konsistenz ist ein harter Zuchtmeister (auch bekannt als "Lesen Sie Ihre Schreibvorgänge nicht")

Sukzessive Konsistenz ist eine tolle Idee auf dem Papier und ein wichtiger Beitrag zur Fähigkeit von IBM Cloudant, in der Praxis horizontal zu skalieren. Ehrlich gesagt fühlt sich die Denkweise, die erforderlich ist, um gegen einen letztendlich konsistenten Datenspeicher zu entwickeln, für die meisten Menschen widernatürlich an.

Man wird oft gestochen, wenn man Tests ähnlich den folgenden schreibt:

  1. Datenbank erstellen
  2. Füllen Sie die Datenbank mit einigen Testdaten.
  3. Fragen Sie die Datenbank nach einer Untergruppe dieser Testdaten ab.
  4. Stellen Sie sicher, dass es sich bei den Daten, die Sie zurückerhalten haben, um die Daten handelt, von denen Sie erwartet haben, dass sie zurückgegeben werden.

Kein Problem mit diesem Test? Das funktioniert mit jeder anderen Datenbank, die Sie jemals benutzt haben, richtig?

Nicht mit IBM Cloudant.

Oder besser gesagt, er funktioniert in 99 % der Fälle.

Der Grund für diesen Unterschied ist ein (meist) kleines Inkonsistenzfenster zwischen dem Schreiben von Daten in die Datenbank und dem Verfügbarwerden dieser Daten auf allen Knoten des Clusters. Da alle Knoten in einem Cluster gleich groß sind, gibt es keine Garantie dafür, dass ein Schreibvorgang und ein darauf folgender Lesevorgang von demselben Knoten bearbeitet werden. Unter bestimmten Umständen trifft der Lesevorgang möglicherweise auf einen Knoten, bevor die geschriebenen Daten den Knoten erreichen.

Warum also setzen Sie nicht einfach eine kurze Verzögerung zwischen dem Schreiben und dem Lesen in Ihren Test? Diese Verzögerung macht es unwahrscheinlicher, dass der Test fehlschlägt, aber das Problem besteht noch immer.

IBM Cloudant hat keine Transaktionsgarantien. Während das Schreiben von Dokumenten atomar ist (Sie können sicher sein, dass ein Dokument entweder vollständig oder gar nicht gelesen werden kann), gibt es keine Möglichkeit, das Inkonsistenzfenster zu schließen. Es ist eingebaut.

Ein ernsthaftes Problem, das jeder Entwickler berücksichtigen muss, ist, dass Sie nicht sicher davon ausgehen können, dass Daten, die Sie schreiben, für jemand anderen zu einem bestimmten Zeitpunkt verfügbar sind. An diesen Sachverhalt muss man sich erst einmal gewöhnen, wenn man aus einer anderen Datenbanktradition kommt.

Test-Tipp: Sie können das Inkonsistenz-Fenster beim Testen vermeiden, indem Sie mit einer Single-Node-Instanz von IBM Cloudant oder CouchDB testen, die z. B. unter Docker läuft (Docker-Informationen ). Ein einzelner Knoten beseitigt das mögliche Konsistenzproblem. Beachten Sie jedoch, dass Sie Tests in einer Umgebung durchführen, die ein anderes Verhalten ausweist als das, auf welches Sie in der Produktionsumgebung abzielen. Caveat Emptor.

Replikation ist keine Magie

“So let’s set up three clusters across the world, Dallas, London, Sydney, with bi-directional synchronization between them to provide real-time collaboration between our 100,000 clients.”

Anzahl Nur ... Anzahl IBM Cloudant eignet sich gut für die Replikation. Es mag magisch erscheinen, aber beachten Sie, dass es keine Latenzgarantien macht. In der Tat ist das gesamte System auf letztendliche Konsistenz hin konzipiert. Wenn man die Replikation von IBM Cloudant wie ein Messaging-System in Echtzeit behandelt, nimmt dies kein gutes Ende. Fügen Sie für diesen Anwendungsfall ein System dazwischen ein, das für diesen Zweck konzipiert wurde, z. B. Apache Kafka.

Es ist schwierig, den Replikationsdurchsatz zu quantifizieren. Die Antwort lautet immer: "Je nachdem." Zu den Faktoren, die sich auf die Replikationsleistung auswirken, gehören unter anderem:

  1. Änderungshäufigkeit
  2. Dokumentgröße
  3. Anzahl simultaner Replikationsjobs auf dem Cluster als Ganzes
  4. Breite Dokumentbaumstrukturen (mit Konflikten)
  5. Ihre Einstellungen für reservierte Durchsatzkapazität

Weitere Informationen finden Sie auf den folgenden Websites:

Bulk API verwenden

IBM Cloudant hat nette API-Endpunkte für das Massenladen (und Lesen) vieler Dokumente in einer einzigen Anfrage. Das Lesen vieler Dokumente in einer einzigen Anfrage kann viel effizienter sein als das Lesen und Schreiben vieler Dokumente nacheinander. Das folgende Beispiel zeigt den Schreibendpunkt:

${database}/_bulk_docs

Sein Hauptzweck ist es, ein zentraler Teil des Replikatoralgorithmus zu sein, aber er ist auch für Ihren Gebrauch verfügbar und er ist genial.

Mit _bulk_docs können Sie so zusätzlich zur Erstellung von PouchDB Erstellungs-, Aktualisierungs- und Löschvorgänge sogar für einzelne Dokumente für weniger Codepfade implementieren.

Im folgenden Beispiel wird ein neues Dokument erstellt, ein zweites vorhandenes Dokument aktualisiert und ein drittes Dokument gelöscht:

curl -XPOST 'https://ACCT.cloudant.com/DB/_bulk_docs' \
     -H "Content-Type: application/json" \
     -d '{"docs":[{"baz":"boo"}, \
         {"_id":"463bd...","foo":"bar"}, \
         {"_id":"ae52d...","_rev":"1-8147...","_deleted": true}]}'

Sie können auch viele Dokumente in einer einzigen Anfrage abrufen, indem Sie einen POST an _all_docs senden (es gibt auch einen relativ neuen Endpunkt mit der Bezeichnung _bulk_get, aber dieser Endpunkt ist wahrscheinlich nicht das, was Sie wollen. Der ist für einen bestimmten internen Zweck vorhanden).

Führen Sie den folgenden Befehl aus, um eine feste Gruppe von Dokumenten mithilfe von _all_docs, POST mit einem keys-Hauptteil abzurufen:

curl -XPOST 'https://ACCT.cloudant.com/DB/_all_docs' \
     -H "Content-Type: application/json" \
     -d '{"keys":["ab234....","87addef...","76ccad..."]}'

IBM Cloudant legt (zum Zeitpunkt des Schreibens) eine maximale Anforderungsgröße von 11 MB fest. _bulk_docs-Anforderungen, die diese Größe überschreiten, werden mit einem 413: Payload Too Large error abgelehnt.

Weitere Informationen finden Sie auf den folgenden Websites:

Basteln Sie nicht an Q, R und N herum, es sei denn, Sie wissen wirklich, was Sie tun

Ändern Sie Q, R und N nur, wenn Sie wirklich wissen, was Sie tun. IBM Cloudant die Quorum- und Sharding-Parameter scheinen, nachdem Sie sie entdeckt haben, verlockende Optionen zu sein, um das Verhalten der Datenbank zu ändern.

Stärkere Konsistenz, bestimmt kann ich das Schreibquorum auf die Replikatanzahl setzen?

Nein. Denken Sie daran, dass es keine Möglichkeit gibt, das Inkonsistenzfenster in einem Cluster zu schließen.

Fangen Sie nicht damit an. Das Verhalten kann besonders bei Netzpartitionen viel schwieriger verständlich sein. Wenn Sie Cloudant-the-service verwenden, sind die Standardwerte für die meisten Benutzer in Ordnung.

Manchmal ist es wichtig, die Shardanzahl für eine Datenbank zu optimieren, um die bestmögliche Leistung zu erzielen. Wenn Sie nicht sagen können, warum, werden Sie Ihre Situation wahrscheinlich verschlimmern.

IBM Cloudant ist ratenbegrenzt - lassen Sie diese Ratenbegrenzung in Ihren Code einfließen

Cloudant-the-Service (im Unterschied zur Basis-CouchDB) wird als Modell mit "reservierter Durchsatzkapazität" verkauft. Das bedeutet, dass Sie für die nutzungsrecht bis zu einem bestimmten Durchsatz bezahlen und nicht für den Durchsatz, den Sie tatsächlich nutzen. Es kann eine Weile dauern, bis die Methode Nutzungsrecht durchsickert. Ein etwas bröckliger Vergleich könnte der eines Handyvertrags sein, bei dem Sie für eine bestimmte Anzahl von Minuten bezahlen, unabhängig davon, ob Sie diese nutzen oder nicht.

Obwohl der Vergleich mit dem Handyvertrag nicht die gesamte Situation erfasst, besteht keine Einschränkung bei der Summe der Anforderungen, die Sie in einem Monat an IBM Cloudant stellen können. Die Einschränkung hängt davon ab, wie schnell Sie Anforderungen stellen.

Es ist in Wirklichkeit ein Versprechen, das Sie an IBM Cloudant geben, nicht eines, das IBM Cloudant an Sie gibt. Sie versprechen, nicht mehr Anfragen pro Sekunde zu stellen, als Sie im Voraus vereinbart haben. Eine maximale Geschwindigkeitsbegrenzung, wenn Sie so wollen. Wenn Sie diese überschreiten, lässt IBM Cloudant Ihre Anforderungen mit dem Status 429: Too Many Requests fehlschlagen. Es liegt in Ihrer Verantwortung, diesen Fall im Auge zu behalten und damit umzugehen, was schwierig sein kann, wenn mehrere App-Server vorhanden sind. Wie können sie sich koordinieren, um sicherzustellen, dass sie gemeinsam unter dem Grenzwert für die Anfragen pro Sekunde bleiben?

Die offiziellen IBM Cloudant-Clientbibliotheken verfügen über eine integrierte Bereitstellung für diesen Anwendungsfall, die nach einer "Back-off"-und Wiederholungsstrategie aktiviert werden kann.

Diese integrierte Bereitstellung ist standardmäßig inaktiviert, um Sie zu zwingen, darüber nachzudenken.

Wenn Sie sich jedoch allein auf diese Möglichkeit verlassen, werden Sie letztendlich vielleicht enttäuscht. Die „Zurück und nochmal versuchen“-Strategie hilft nur bei temporären Überschreitungen, nicht, wenn Sie andauernd an die Grenzen Ihre bereitgestellten Durchsatzkapazität stoßen.

Ihre Geschäftslogik muss in der Lage sein, diese Bedingung auszuführen. Sie können es auch so sehen: Sie erhalten die Zuteilung, für die Sie bezahlen. Wenn diese Zuteilung nicht ausreicht, besteht die einzige Lösung darin, für eine höhere Zuteilung zu bezahlen.

Die bereitgestellte Durchsatzkapazität wird in drei verschiedene Buckets aufgeteilt: Suchvorgänge, Schreibvorgänge und Abfragen. Eine Suche ist ein "Primärschlüssel", der gelesen wird und ein Dokument auf der Basis seiner _id abruft. Ein Schreibvorgang speichert ein Dokument oder einen Anhang auf der Platte und eine Abfrage sucht Dokumente mithilfe eines Sekundärindex (ein beliebiger API-Endpunkt, der ein _design oder _find enthält).

Sie erhalten für jeden Bucket unterschiedliche Zuteilungen und die Verhältnisse zwischen ihnen sind festgelegt. Diese Tatsache kann genutzt werden, um Kosten zu optimieren. Sie erhalten 20 Suchvorgänge für jede Abfrage (pro Sekunde). Sie könnten feststellen, dass Sie hauptsächlich das Abfrage-Limit erreichen, aber Sie haben viel Spielraum bei Suchvorgängen. Es könnte möglich sein, die Abhängigkeit von Abfragen durch eine Umgestaltung der Daten zu verringern oder eventuell mehr Arbeit clientseitig auszuführen.

Hieraus folgert jedoch, dass Sie nicht davon ausgehen können, dass eine Drittanbieter-Bibliothek oder ein Drittanbieter-Framework die Kostenoptimierung vor die Zweckmäßigkeit stellt. Clientseitige Frameworks, die mehrere Persistenzebenen mithilfe von Plug-ins unterstützen, sind sich dieser Situation wahrscheinlich nicht bewusst oder sind nicht in der Lage, derartige Kompromisse einzugehen.

Es ist eine gute Idee, die Kompatibilität von Bibliotheken oder Frameworks anderer Anbieter zu überprüfen, bevor Sie sich auf ein bestimmtes Tool festlegen.

Es lohnt sich auch zu verstehen, dass die Raten nicht direkt äquivalent zu HTTP-API-Endpunktaufrufen sind. Sie müssen beispielsweise erwarten, dass eine Massenaktualisierung entsprechend den Schreibvorgängen der zugehörigen Teildokumente zählt.

Mithilfe der Protokollierung können Sie sehen, was vor sich geht

IBM Cloudant die Protokolle, die jeden API-Aufruf, die angeforderten Daten und die Dauer der Antwort aufzeichnen, können zur Analyse und Berichterstellung für IBM Cloud-basierte Dienste automatisch auf IBM Cloud Logs gespeichert werden. Diese Daten sind nützlich, um das Anforderungsvolumen und die Leistung im Auge zu behalten und um festzustellen, ob Ihre Anwendung die bereitgestellte Kapazität für Ihren IBM Cloudant-Service überschreitet.

{Der Dienst IBM Cloud Logs ist ein kostenpflichtiger Dienst, der verschiedene Aufbewahrungszeiträume und Protokollverbrauchsstufen bietet. Auf verschiedenen Ebenen können Daten aufbewahrt werden, um sie in COS zu archivieren, kalt oder heiß zu durchsuchen und zu unterschiedlichen Kosten zu alarmieren. Ausschnitte und Aggregationen Ihrer Daten können in visuelle Dashboards integriert werden, um Ihnen eine Übersicht über Ihren IBM Cloudant-Datenverkehr zu geben. Weitere Informationen finden Sie in der folgenden Dokumentation:

HTTP-Datenverkehr komprimieren

IBM Cloudant komprimiert seine JSON-Antworten an Sie, wenn Sie einen HTTP-Header in der Anforderung angeben, der angibt, dass Ihr Code Daten in diesem Format verarbeiten kann.

Request:

> GET /cars/_all_docs?limit=5&include_docs=true HTTP/2
> Host: myhost.cloudant.com
> Accept: */*
> Accept-Encoding: deflate, gzip

Response:                                                                   

< HTTP/2 200
< content-type: application/json
< content-encoding: gzip

Komprimierter Inhalt nimmt einen Bruchteil der Größe des dekomprimierten Äquivalents ein, d. h., es dauert weniger lange, die Daten von den IBM Cloudant-Servern an Ihre Anwendung zu transportieren.

Sie können HTTP-Anforderungshauptteile wahlweise auch mithilfe des Content-Encoding-Headers komprimieren. Diese Praxis hilft, die Datenübertragungszeiten zu reduzieren, wenn Sie Dokumente auf IBM Cloudant schreiben.