2014-01-06 5 views
15

Ich habe eine Kassandra Frage. Wissen Sie, wie Cassandra Aktualisierungen/Inkremente von Zählern durchführt?Wie schnell Zähler in Cassandra w/o Staleness zu erhöhen

Ich möchte eine Sturmschraube (CassandraCounterBatchingBolt von Storm-Contrib Repo auf Github) verwenden, die in Cassandra schreibt. Aber ich bin nicht sicher, wie ein Teil der Umsetzung des incrementCounterColumn() Methode funktioniert .. und es gibt auch die Grenzen mit cassandra Zähler (aus: http://wiki.apache.org/cassandra/Counters), die sie nutzlos für meine Szenario IMHO macht:

  • Wenn ein Schreibvorgang unerwartet fehlschlägt (Timeout oder Verbindungsverlust zum Koordinatorknoten), weiß der Client nicht, ob der Vorgang ausgeführt wurde. Ein erneuter Versuch kann zu einer Überzählung von CASSANDRA-2495 führen.

  • Zählerentfernung ist an sich begrenzt. Zum Beispiel, wenn Sie sehr schnell die Sequenz ausgeben „Schritt, zu entfernen, erhöhen“ es möglich ist, die Entfernung

Wie dem auch sei verloren, hier ist mein Szenario:
aktualisiere ich die gleichen Zähler schneller als die Aktualisierungen werden an andere Cassandra-Knoten weitergegeben.

Beispiel:
Say I 3 cassandra Knoten haben. Die Zähler auf jedem dieser Knoten sind 0.
Node1: 0, Knoten2: 0, node3: 0

Ein Zuwachs kommt: 5 -> Knoten 1: 0, Knoten2: 0, node3: 0

Increment am Knotenpunkt beginnt, 2 - noch
node1 zu node1 und node3 fortzupflanzen benötigt: 0, node2: 5, node3: 0

In der Zwischenzeit kommt ein weiteres Inkrement, bevor vorheriges Inkrement
ausbreitet: 3 -> Knoten 1: 0, Knoten2: 5, Knoten3: 0

Unter der Annahme, 3 beginnt an einem anderen Knoten als die 5 haben uns begonnen haben:
Node1: 3, Knoten2: 5, node3: 0

Wenn nun 3 zu dem anderen Knoten als eine Erhöhung propagiert wird und nicht als neuer Wert (und das gleiche für 5) dann würden schließlich die Knoten alle gleich 8 und das ist was ich will.

Wenn 3 überschreibt 5 (weil es einen späteren Zeitstempel hat) ist das problematisch - nicht was ich will.

Wissen Sie, wie diese Aktualisierungen/Inkremente von Cassandra gehandhabt werden?

Hinweis, dass ein Lese vor einem Schreib ist immer noch anfällig für das gleiche Problem in Abhängigkeit von der Replika-Knoten der Lese ausführt (Quorum kann immer noch fehlschlagen, wenn die Ausbreitung entlang ist nicht weit)

ich auch denke, dass vielleicht, indem ich einen Cache s/w setze, könnte mein Sturmbolzen und Cassandra dieses Problem lösen, aber das ist eine Geschichte für ein anderes Mal.

Antwort

17

Zähler in C * haben eine komplexe interne Darstellung, die die meisten (aber nicht alle) Probleme beim Zählen von Dingen in einem führerlosen verteilten System vermeidet. Ich mag es, sie als sharded counters zu sehen. Ein Zähler besteht aus einer Anzahl von Teilzählern, die durch die Host-ID und eine Versionsnummer identifiziert werden. Der Host, der die Zähleroperation empfängt, inkrementiert nur seinen eigenen Subzähler und inkrementiert auch die Version. Es repliziert dann seinen gesamten Zählerstand auf die anderen Replikate, die es mit ihren Zuständen verschmelzen. Wenn der Zähler gelesen wird, bestimmt der Knoten, der die Leseoperation behandelt, den Zählerwert, indem er die Summe der Zählerstände von jedem Host aufsummiert.

Auf jedem Knoten ist ein Zählerinkrement genau wie alles andere in Cassandra, nur ein Schreiben. Das Inkrement wird in die Memtable geschrieben, und der lokale Wert wird zur Lesezeit bestimmt, indem alle Inkremente aus dem memable und allen SSTables zusammengeführt werden.

Ich hoffe, dass diese Erklärung Ihnen hilft, mir zu glauben, wenn ich sage, dass Sie sich nicht darum sorgen müssen, Zähler schneller zu erhöhen, als Cassandra verarbeiten kann. Da jeder Knoten seinen eigenen Zähler behält und niemals Inkrementierungsoperationen repliziert, gibt es keine Möglichkeit, dass Zählungen durch Race-Bedingungen verloren gehen, wie dies ein Read-Modify-Write-Szenario einführen würde. Wenn Cassandra den Schreibvorgang akzeptiert, sind Sie ziemlich sicher, dass es zählt.

Was Sie jedoch nicht garantieren können, ist, dass die Zählung immer korrekt erscheint, es sei denn. Wenn ein Inkrement auf einen Knoten geschrieben wird, aber der Zählerwert unmittelbar danach von einem anderen gelesen wird, gibt es keine Garantie, dass das Inkrement repliziert wurde, und Sie müssen auch berücksichtigen, was während einer Netzwerkpartition passieren würde. Dies ist mehr oder weniger das gleiche wie bei jedem anderen Schreibvorgang in Cassandra, es ist in seiner letztendlich konsistenten Natur und hängt davon ab, welche Konsistenzstufen Sie für die Operationen verwendet haben.

Es besteht auch die Möglichkeit einer verlorenen Bestätigung. Wenn Sie ein Inkrement machen und die Verbindung zu Cassandra verlieren, bevor Sie die Antwort zurückbekommen können, können Sie nicht wissen, ob Ihr Schreibvorgang obwohl kam oder nicht. Und wenn du die Verbindung zurückbekommst, kannst du es auch nicht sagen, da du nicht weißt, wie hoch die Anzahl war, bevor du inkrementiert hast. Dies ist ein inhärentes Problem bei Systemen, bei denen Verfügbarkeit und Konsistenz im Vordergrund stehen, sowie der Preis, den Sie für viele andere Vorteile zahlen müssen.

Schließlich ist das Problem der schnellen Entfernung, Inkrementieren, Entfernen real, und etwas, das Sie vermeiden sollten. Das Problem ist, dass die increment-Operation die Spalte im Wesentlichen wiederbeleben wird, und wenn diese Operationen nahe genug kommen, erhalten sie möglicherweise den gleichen Zeitstempel. Cassandra ist strikt Last-Write-Wins und bestimmt zuletzt basierend auf dem Zeitstempel der Operation. Wenn zwei Operationen denselben Zeitstempel haben, gewinnt der "größere", also derjenige, der nach einer genauen Byte-Reihenfolge sortiert. Es ist real, aber ich würde mich nicht zu viele Gedanken darüber machen, es sei denn, Sie schreiben sehr schnell und löschen auf den gleichen Wert (was wahrscheinlich ein Fehler in Ihrem Datenmodell ist).

Hier ist ein guter Leitfaden für die Interna von Cassandras Zählern: http://www.datastax.com/wp-content/uploads/2011/07/cassandra_sf_counters.pdf

+0

Danke für die sehr gründliche Erklärung. Ausgezeichneter Link und Post! Ja, der Grund, warum die letzten Zeitstempel gewinnen, ist, warum ich diese Frage gestellt habe. Jetzt verstehe ich, dass es eine Inkrementierungsanweisung für Zähler gibt (anstatt ein Lesen + Schreiben). "Ist das wahr?" Wenn ich in die Cloud ziehe, werden die Verzögerungen zunehmen und um die falsche Zahl zu lesen, muss ich nach dem Schreiben erhöhen, wie lange ich aggregiere, bevor ich in db speichere. Ich hoffe, dass ein Zählerinkrementbefehl existiert. – Adrian

+0

Es gibt eine Inkrement-Anweisung, und Sie müssen nicht lesen, bevor Sie ein Inkrement durchführen. Wenn Sie mit dem Konsistenzlevel QUORUM inkrementieren und mit dem Konsistenzlevel QUORUM lesen, sollten Sie nie Inkonsistenzen in den Zählungen sehen. – Theo

+0

Ich sollte hinzufügen, dass es natürlich die Möglichkeit gibt, in Ausnahmefällen wie Partitionen und Abstürzen zu viel oder zu wenig zu zählen. – Theo

2

Um Updates/Inkremente zu verstehen, d. H. Schreibvorgänge, werde ich vorschlagen, dass Sie Gossip, Protokoll von Cassandra für die Kommunikation verwendet gehen.In Gossip behält jeder Teilnehmer (Knoten) seinen Status unter Verwendung des Tupels σ(K) = (V*N) bei, wobei σ(K) der Status K Schlüssel mit V Wert und N als Versionsnummer ist.

Um die einzige Version der Wahrheit für ein Datenpaket beizubehalten, unterhält Gossip einen Reconciliation-Mechanismus, nämlich Precise & Scuttlebutt (aktuell). Gemäß Scuttlebutt Reconciliation kommunizieren sie vor dem Aktualisieren eines Tupels miteinander, um zu überprüfen, wer die höchste Version (den neuesten Wert) des Schlüssels hält. Wer die höchste Version hält, ist für den Schreibvorgang verantwortlich.

Für weitere Informationen lesen Sie diese article.

3

Die aktuelle Version von Zählern ist einfach nicht eine gute Passform für einen Anwendungsfall, die garantiert keine über Zähl- und sofortige Konsistenz erfordert.

Es gibt Inkrement- und Dekrement-Operationen, die nicht miteinander kollidieren. Wenn keine Mutationen oder Mutationen verloren gegangen sind, erhalten Sie ein korrektes Ergebnis.

Das Umschreiben von Cassandra-Zählern (https://issues.apache.org/jira/browse/CASSANDRA-6504) könnte für Sie interessant sein, und es sollte alle aktuellen Bedenken bezüglich einer korrekten Zählung berücksichtigen.

In der Zwischenzeit, wenn ich dies auf einer aktuellen Version von Cassandra implementieren musste, und eine genaue Zählung war wichtig, würde ich wahrscheinlich jedes Inkrement oder Dekrement als Spalte speichern, und lesen-Zeit-Aggregation der Ergebnisse, während Sie einen Prüfpunkt zurückschreiben, so dass Sie nicht zum Anfang der Zeit zurücklesen müssen, um nachfolgende Ergebnisse zu berechnen.

Das fügt der Leseseite eine Menge Last hinzu, obwohl es auf dem Schreibpfad äußerst effizient ist, so dass es für Ihren Anwendungsfall funktioniert oder nicht.

+0

das Lesen war nur zum Lesen neuer Werte vor dem Inkrementieren und Schreiben; Jetzt, wo ich erhöhen kann, muss ich nicht zuerst lesen, nur inc; Ich lese, aber alle 30 Minuten oder 20 Minuten, also nicht sehr oft :) – Adrian

Verwandte Themen