Wie erhöht man einen Zähler in Cassandra?

8

Ich würde gerne Cassandra verwenden, um einen Zähler zu speichern. Zum Beispiel, wie oft eine bestimmte Seite angesehen wurde. Der Zähler wird niemals dekrementieren. Der Wert des Zählers muss nicht genau sein, aber er sollte im Laufe der Zeit genau sein.

Mein erster Gedanke war, den Wert als Spalte zu speichern und nur die aktuelle Anzahl zu lesen, sie um eins zu erhöhen und dann wieder einzufügen. Wenn jedoch eine andere Operation versucht, den Zähler zu erhöhen, würde ich den endgültigen Wert annehmen sei einfach der mit dem spätesten Zeitstempel.

Ein weiterer Gedanke wäre, jede Seitenladung als neue Spalte in einer CF zu speichern. Dann könnte ich einfach get_count() für diesen Schlüssel ausführen und die Anzahl der Spalten ermitteln. Wenn man die Dokumentation liest, scheint es, dass es überhaupt keine sehr effiziente Operation ist.

Komme ich das Problem falsch an?

    
Stephen Holiday 24.08.2010, 16:48
quelle

5 Antworten

5

Zähler wurden zu Cassandra 0.8 hinzugefügt

Verwenden Sie die incr-Methode, um den Wert einer Spalte um 1 zu erhöhen.

%Vor%

Beschreiben Sie hier: Ссылка

Oder es kann programmatisch gemacht werden

%Vor%

Beschrieben hier: Ссылка

    
Edward Capriolo 24.08.2011, 22:00
quelle
5

[Update] Sieht so aus, als wäre die Counter-Unterstützung in 0.8 zur Primetime bereit!

Ich würde definitiv get_count nicht verwenden, da dies eine O (n) -Operation ist, die jedes Mal ausgeführt wird, wenn Sie den "counter" lesen. Schlimmer als es nur O (n) ist, kann es mehrere Knoten umfassen, die eine Netzwerklatenz einführen würden. Und schließlich, warum binden Sie all diesen Speicherplatz ein, wenn Sie nur eine einzige Nummer benötigen?

Im Moment würde ich Cassandra gar nicht für Counter benutzen. Sie arbeiten an dieser Funktionalität, aber sie ist noch nicht zur Prime Time bereit.

Ссылка

Sie haben in der Zwischenzeit einige Optionen.

1) (Schlecht) Speichern Sie Ihre Anzahl in einem einzigen Datensatz, und nur ein einziger Thread Ihrer Anwendung ist für die Zählerverwaltung verantwortlich.

2) (Besser) Teilen Sie den Zähler in n Shards auf, und n Threads verwalten jeden Shard als separaten Zähler. Sie können festlegen, welcher Thread von Ihrer App jedes Mal für den statusfreien Lastenausgleich über diese Threads verwendet wird. Stellen Sie nur sicher, dass jeder Thread für genau einen Shard verantwortlich ist.

3a) (Am besten) Verwenden Sie ein separates Tool, das entweder transaktional ist (auch bekannt als RDBMS) oder atomare Inkrementoperationen unterstützt (memcached, redis).

[Update.2] Ich würde es vermeiden, eine verteilte Sperre zu verwenden (siehe memcached- und zookeeper-Mutexe), da dies sehr unempfindlich gegen Knotenausfall oder Netzwerkpartitionierung ist, wenn sie nicht ordnungsgemäß implementiert wird.

    
Ben Burns 29.08.2010 21:59
quelle
2

Was ich am Ende gemacht habe, war get_count () zu verwenden und das Ergebnis in einem Caching von ColumnFamily zwischenzuspeichern.

Auf diese Weise konnte ich die Zählung allgemein erraten, aber immer noch die genaue Anzahl erhalten, wann immer ich wollte.

Zusätzlich konnte ich einstellen, wie veraltet die Daten waren, die ich pro Anfrage annehmen wollte.

    
Stephen Holiday 22.09.2010 00:15
quelle
1

Wir werden ein ähnliches Problem angehen, indem wir den aktuellen Wert eines Zählers in einem verteilten Cache behalten (zum Beispiel - memcached). Wenn der Zähler aktualisiert wird, speichern wir seinen Wert in Cassandra. Daher können wir auch dann, wenn ein Cache-Knoten ausfällt, den Wert aus der Datenbank abrufen.

Diese Lösung ist nicht perfekt. Daten wie ein Besuchszähler sind jedoch nicht sehr sensibel, so dass meiner Meinung nach kleinere Unstimmigkeiten möglich sind.

    
Jacek L. 27.05.2011 06:52
quelle
0

Interessanterweise sehe ich niemanden, der die Möglichkeit erwähnt, auf einer Computer-Basis pro App zu zählen. Angenommen, Ihre App läuft auf 5 Computern mit den Namen a1, a2, ... a5. Dann können Sie pro Maschine eine Sperre haben (d. H. Eine Datei, die Sie mit O_EXCL öffnen oder die Sperre verwenden, um auf andere Instanzen mit dem Zähler zu warten) und je nach Ihrer Implementierung entweder eine Zeile pro Maschine oder eine Spalte hinzufügen. Etwas wie

%Vor%

Auf diese Weise erhalten Sie einen Zähler pro Maschine. Wenn Sie die Summe benötigen, lesen Sie einfach a1, a2, ... a5 und summieren sie.

%Vor%

(das ist Pseudocode, der mehr oder weniger mit libQtCassandra funktionieren würde.)

Auf diese Weise vermeiden Sie eine Sperre, die alle Knoten sperrt, und dennoch erhalten Sie eine sichere / konsistente Zählung (offensichtlich ist das Lesen + Summe nicht perfekt und gibt Ihnen nur eine Annäherung an die Gesamtsumme, aber es bleibt konsistent.)

Ich bin mir nicht sicher, ob das, was Ben Burns im Hinblick darauf, n Splitter und n Threads zu haben, das gleiche wäre, aber es klingt für mich nicht genau so.

Und seit 0.8.x können Sie die Cassandra-Zähler verwenden, was sicherlich viel einfacher ist, obwohl es nicht immer Ihren Bedürfnissen entspricht.

    
Alexis Wilke 30.08.2012 18:13
quelle

Tags und Links