Ich versuche, einen Zeitreihendienst basierend auf Cassandra zu entwerfen, der einige Protokollinformationen verfolgen wird. Die Datenbank wird ein relativ hohes Volumen an Schreibvorgängen (mit ~ 500 mil Einsätzen/Tag) und weniger häufigen, aber großen Lesevorgängen (denken Sie an einen Tag Daten oder einen Monat Daten) sehen.Cassandra timeseries modellieren
Das vereinfachte Datenmodell von einem Protokolleintrag sieht wie folgt aus (in Wirklichkeit hat es 50 oder so Spalten):
log_datetime date
log_some_field text
log_some_other_field text
Die meisten Anfragen lesen um die Auswahl von Daten aus einem bestimmten Datumsbereich drehen wird, immer bestellt absteigend Nach Datum. (z.B. SELECT * FROM logs WHERE log_datetime >= 2012-01-01 and log_datetime <= 2012-02-01 ORDER BY log_datetime DESC
). Dies wird normalerweise viel Zeit in Anspruch nehmen, deshalb möchte ich so viel wie möglich dafür optimieren.
Wie Bestellung und die Filterung nach Datum sind die wichtigsten Eigenschaften, solange schreibt nicht zu schrecklich sind, die erste Idee war so etwas wie dieses zu definieren (wo log_day der Tag des Jahres):
CREATE TABLE logs(
log_day tinyint
log_datetime timeuuid
log_some_field text
log_some_other_field text
PRIMARY KEY (log_day, log_datetime)
WITH CLUSTERING ORDER BY (log_datetime DESC)
)
Es ist mein Verständnis, dass dies den Abruf so gut wie möglich macht, da die Daten geordnet sind und eine einzelne Partition benötigt wird, um einen Tag abzurufen (ich kann in dem Client die Fälle behandeln, in denen mehrere Tage ausgewählt sind). Dies würde jedoch dazu führen, dass Schreibvorgänge auf einen einzelnen Server übertragen werden, was die Schreibleistung erheblich beeinträchtigen würde. Die andere Option ist die Auswahl eines zufälligen Sets, das als Partitionsschlüssel verwendet wird und vom Client auf Round-Robin verteilt wird, was die Schreibvorgänge schneller und skalierbarer macht, aber zu schlechterer Leseperformance führt, insbesondere wenn wir neu sortieren müssen die Daten. Die meisten Beispiele, die ich gesehen habe, haben normalerweise natürliche Partitionsschlüssel in der Datenmenge wie eine user_id oder eine post_id, was nicht mein Fall ist.
Hat jemand hier einen ähnlichen Anwendungsfall? Wenn ja, welche Kompromisse haben Sie gemacht, um eine ordentliche Leistung zu erzielen? Kennen Sie Datenbanken, die in solchen Anwendungsfällen besser funktionieren?
Mit dem Zeitfenster würden wir immer noch eine ungleichmäßige Verteilung sehen oder fehlt mir etwas (z. B. würde ein Server alle Anfragen für 5 Minuten erhalten)? Kann ein einzelner Node von Cassandra ~ 10k req/Sekunde verarbeiten oder wäre es besser, nur Round Robin für die Client-Anwendung zu verwenden? – woland
Ja, es würde Daten für die Dauer des Zeitbereichs in den primären Knoten schreiben, z. B. 5 Minuten. Sie können dies so klein wie Sie möchten.Alternativ können Sie mit minutes% 10 10 Buckets erstellen, die jede Minute zwischen Knoten rotiert werden. Ihre Hardware wird wirklich bestimmen, ob 10k/sec nachhaltiger Durchsatz ist oder nicht. – Bradski