2017-06-09 1 views
0

Ich grabe tiefer in CouchDB 2 und ich finde einige unerwartete Reihenfolge mit Sequenznummern. In einem Fall fand ich, dass eine frühe Änderung in einer _changes Feed die Sequenznummer hatSequenznummer Bug in CouchDB 2 oder gibt es eine andere Möglichkeit, Sequenznummern zu vergleichen?

99-g1AAAAI-eJyd0EsOgjAQBuAGiI-dN9C9LmrBwqzkJtrSNkgQV6z1JnoTvYneBEvbhA0aMU1mkj6-_NMSITTJfYFm2anOcsFT10mpTzyG-LxpmiL32eqoN8aEAcWE9dz_jPCFrnzrHGQchiFM4kSgaV0JqQ6VFF-AtAV2DggMgCEGxrNhQfatc3bOyDiKUalg2EBVoCu66KapazcUh41e69-GssjNIvcWWRokk2oNofwj0MNazy4QFURhGQ0J9LKI-SHPIBHEgiak51nxBhxnrRk 

Die letzte Sequenznummer in meinem _changes Futtermittel, für die gleiche DB ist

228-g1AAAAJFeJyd0EkOgjAUBuAGTJCdN9AjlIKFruQm2jFAEFes9SZ6E72J3gQ7JW7QCGnyXtLhy-vfAgCWVSjAip96XglW-o5afRJQwNbDMDRVSOuj3ogQJRgiOnL_O8I2urKdd4B1KCRpkRcCxH0npKo7KX4ApQH2HogsAElOKOPTBjkY5-yd2DqKYqnItA91C13BRTdNXY0VWouRrV7JDOvmrLuxlLW4VAlJ5Qzr4aznJ2wskIIy-y9sh7wcYoMKLJKRXOACjTxr3uHcsBE 

in einem Browser Konsole ist das folgende falsch

'228-g1AAAAJFeJyd0EkOgjAUBuAGTJCdN9AjlIKFruQm2jFAEFes9SZ6E72J3gQ7JW7QCGnyXtLhy-vfAgCWVSjAip96XglW-o5afRJQwNbDMDRVSOuj3ogQJRgiOnL_O8I2urKdd4B1KCRpkRcCxH0npKo7KX4ApQH2HogsAElOKOPTBjkY5-yd2DqKYqnItA91C13BRTdNXY0VWouRrV7JDOvmrLuxlLW4VAlJ5Qzr4aznJ2wskIIy-y9sh7wcYoMKLJKRXOACjTxr3uHcsBE' > '99-g1AAAAI-eJyd0EsOgjAQBuAGiI-dN9C9LmrBwqzkJtrSNkgQV6z1JnoTvYneBEvbhA0aMU1mkj6-_NMSITTJfYFm2anOcsFT10mpTzyG-LxpmiL32eqoN8aEAcWE9dz_jPCFrnzrHGQchiFM4kSgaV0JqQ6VFF-AtAV2DggMgCEGxrNhQfatc3bOyDiKUalg2EBVoCu66KapazcUh41e69-GssjNIvcWWRokk2oNofwj0MNazy4QFURhGQ0J9LKI-SHPIBHEgiak51nxBhxnrRk' 

Ist das ein Fehler oder muss ich eine andere Methode verwenden, um Sequenznummern zu vergleichen?

Wenn ich mir die anderen Sequenznummern in meinem _changes-Feed anschaue, sieht es so aus, als wären sie im Allgemeinen so geordnet, wie ich es erwarten würde, aber in diesem Fall scheint es, dass wenn die erste Nummer, z.B. 99, springt von 2 Ziffern auf 3 Ziffern, die Reihenfolge bricht. Wenn Sie dies auf ein einfaches String-Vergleich-Beispiel herunterkochen, können Sie sehen, dass '228'> '99' => false

+0

Das ist immer so, wie Zahlen sortiert werden, wenn Sie sie alphanumerisch sortieren. – Flimzy

Antwort

1

Die folgende Antwort enthält Auszüge aus einem E-Mail-Thread mit @rnewson. Ich hoffe, dass es jemand anderen hilft, Sequenznummern in CouchDB 2 zu verstehen. Danke, Robert!

Der Hintergrund:

Es gibt keine einfache Möglichkeit, sie in 2.0 und keine Notwendigkeit zu vergleichen für sie in Ordnung zu sein. Sie sind nicht, kurz gesagt, entworfen, um überprüft zu werden, oder verglichen außerhalb von couchdb; behandle sie undurchsichtig.

Die Nummer auf der Vorderseite ist die Summe der einzelnen Update-Sequenzen im zweiten Teil codierten und existiert nur ältere Versionen von die couchdb Replikator in der Herstellung Checkpoints zu betrügen.

Die zweite Hälfte der Sequenz Zeichenfolge ist eine codierte Liste von {node, Bereich, seq} Tupel (wobei seq den ganzzahligen Wert von Sie pre-2,0 Veröffentlichungen wissen, ist). Wenn ein Sequenzstring zurückgegeben wird, wie zum Beispiel der since = Parameter, dekodiert couchdb diese Zeichenfolge und übergibt den entsprechenden Ganzzahl-Seq-Wert an den einzelnen Shard.

Alles, was gesagt wird, sollte im Allgemeinen die Frontnummer erhöhen. Die vollständigen Strings selbst sind nicht vergleichbar, da es keine definierte Reihenfolge zu der codierten Liste gibt (so könnten zwei Strings generiert werden, die unterschiedlich codiert sind, aber in die gleiche Tupelliste dekodieren, nur in einer anderen Reihenfolge).

Ein weiterer Aspekt ist, dass der Änderungsvorschub nicht vollständig bestellt wurde. Für einen gegebenen Shard ist total geordnet (ein Shard, der ist, der zu einer pre 2.0 Datenbank mit einer Ganzzahlfolge identisch ist), couchdb mischt nicht diese Ausgabe (obwohl Korrektheit der Replikation beibehalten würde, wenn es tat). Eine Cluster-Datenbank besteht jedoch aus mehreren Shards (der 'q' Wert, der standardmäßig 4 irc ist). Der gruppierte Änderungs-Feed kombiniert diese separaten Änderungs-Feeds in einen einzigen, , unternimmt jedoch keine Anstrengungen, um eine Gesamtbestellung darüber zu erzwingen.Wir tun es nicht , weil es teuer und unnötig wäre.

Die Lösung, wenn Sie auf einem _changes Feed hören und dann neu starten von wo aus man später aufhörte:

Der Algorithmus für den richtigen Änderungen raubend füttern ist:

  1. lesen/dbname/_changes
  2. jede Zeile idempotent verarbeiten
  3. periodisch (alle X Sekunden oder alle X Zeilen) speichern die „seq“ Wert der letzten Zeile, die Sie

verarbeitet Wenn Sie jemals abstürzen, oder wenn Sie nicht kontinuierlich verwendet haben = true, Sie dies tun können gleiche Prozedur erneut, aber in Schritt 1 modifiziert;

überarbeitet 1. Schreib-/dbname/_changes? Da = X

wobei X für den Wert, den Sie in Schritt gespeichert 3. Wenn Sie nicht kontinuierlichen Modus verwenden, dann könnte man einfach den „last_seq“ Wert notieren am Ende des Verbrauchs der nicht kontinuierlichen Antwort. Sie laufen das Risiko von Verarbeitung viel mehr Elemente, obwohl.

Mit diesem Schema (dem der Replikator und alle Indexer folgen), ist es egal, wenn die Ergebnisse aus der Reihenfolge kommen, müssen Sie keine zwei Seq-Werte vergleichen.

Sie tun müssen sicherstellen, dass Sie die gleiche Änderung mehrmals korrekt verarbeiten können. Betrachten Sie zum Beispiel den Replikator, wenn eine Zeile aus einem Änderungsfeed angezeigt wird, fragt sie die Zieldatenbank, ob sie die Werte _id und _rev aus dieser Zeile enthält. Wenn dies der Fall ist, geht der Replikator in die nächste Zeile über. Wenn dies nicht der Fall ist, versucht es, das Dokument in dieser Zeile in die Zieldatenbank zu schreiben . Im Falle eines Crashs und damit eines Aufrufs von _changes mit einem Seq-Wert vor wird die Zieldatenbank abgefragt, ob die _id/_rev erneut vorhanden ist, nur dieses Mal wird das Ziel ja sagen.

Verwandte Themen