2016-07-29 13 views
1

Ich arbeite an einem einzigen Knoten. Ich habe die folgende Tabelle enthält eine Liste von Dokumenten zu speichern:Langsame Bereich Abfragen in Cassandra

CREATE TABLE my_keyspace.document (
    status text, 
    date timestamp, 
    doc_id text, 
    raw_content text, 
    title text, 
    PRIMARY KEY (status, date, doc_id) 
) WITH CLUSTERING ORDER BY (date ASC, doc_id ASC) 
    AND bloom_filter_fp_chance = 0.01 
    AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'} 
    AND comment = '' 
    AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'} 
    AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'} 
    AND crc_check_chance = 1.0 
    AND dclocal_read_repair_chance = 0.1 
    AND default_time_to_live = 0 
    AND gc_grace_seconds = 0 
    AND max_index_interval = 2048 
    AND memtable_flush_period_in_ms = 0 
    AND min_index_interval = 128 
    AND read_repair_chance = 0.0 
    AND speculative_retry = '99PERCENTILE'; 
CREATE INDEX doc_id_idx ON my_keyspace.document (doc_id); 

ich viele Anfragen wie tun:

SELECT * FROM my_keyspace.document WHERE status='PROCESSED' AND data>=start_date AND data<=end_date; 

Aus irgendeinem Grund ist es sehr langsam ist, zunächst die Warnungen, die ich hatte diese wurden:

[2016-07-26 18:10:46] {cassandra.protocol:378} WARNING - Server warning: Read 5000 live rows and 19999 tombstone cells for query SELECT * FROM my_keyspace.document WHERE token(status) >= token(PROCESSED) AND token(status) <= token(PROCESSED) AND date >= 2016-07-08 02:00+0200 AND date <= 2016-07-23 01:59+0200 LIMIT 5000 (see tombstone_warn_threshold) 
[2016-07-26 18:10:52] {cassandra.protocol:378} WARNING - Server warning: Read 5000 live rows and 19999 tombstone cells for query SELECT * FROM my_keyspace.document WHERE token(status) >= token(PROCESSED) AND token(status) <= token(PROCESSED) AND date >= 2016-07-08 02:00+0200 AND date <= 2016-07-23 01:59+0200 LIMIT 5000 (see tombstone_warn_threshold) 

das Thema Denken wurde zu viele tombestones verknüpft ich getan habe:

ALTER TABLE my_keyspace.document WITH gc_grace_seconds = '0'; 

und dann:

nodetool compact my_keyspace document 

Jetzt muss ich keine Warnung, aber die Anfragen sind immer noch sehr langsam und oft Timeout. In den Protokollen, die die Zeitüberschreitung betreffen, wird keine Nachricht angezeigt. Die Anzahl der Dokumente, die ich habe, beträgt ungefähr 200.000 Instanzen. Diese Dokumente sind über einen Zeitraum von 20 Tagen verteilt, etwa 4500 Dokumente haben status='PROCESSED' jeden Tag. Die Antwortzeit für Abfragen variiert je nach Datumsbereich: etwa 3 Sekunden für einen Zeitraum von einem Tag, 15 Sekunden für 4 Tage und eine Zeitüberschreitung von 2 Wochen. Außerdem habe ich den Swap deaktiviert. Die Version von Cassandra, die ich verwende, ist 3.5.

Kürzlich habe ich festgestellt, dass die Angabe der präzisen Spalten statt * die Reaktionszeit ein wenig verbessert, das System aber immer noch zu langsam ist.

EDIT: Computerpartitionsgröße wie vorgeschlagen von Reveka

So, nach der Formel:

  • Anzahl der Zeilen = 20 * 4500 = 90.000
  • Anzahl der Spalten = 19
  • Anzahl der Primärschlüssel = 3
  • Anzahl der statischen Spalten = 0

So ist die Anzahl der Werte 90000 * ist (19-3) = 1.440.000

Für die Größe der Partition, bekam ich auf eine Schätzung von etwa 1,2 GB. Das könnte ein bisschen groß sein. Aber wie kann ich meinen Partitionsschlüssel ändern, um bei kleineren Partitionen immer noch dieselben Bereichsabfragen ausführen zu können? Ich könnte einen Verbundpartitionsschlüssel enthalten, habe die status und den von date extrahierte Tag, aber nicht ich dann den Tag angeben, bevor durch Bereich abfragen zu können:

SELECT * FROM my_keyspace.document WHERE status='PROCESSED' AND day='someday' AND date>='start_date' AND date<='end_date'; 

Was mich zwingt, eine Abfrage zu tun pro Tag.

Antwort

3

Ich sehe, dass Ihr Primärschlüssel aus Status, Datum und doc_id besteht und Sie nur den Status als Ihren Partitionsschlüssel verwenden. Das bedeutet, dass alle Dokumente des gleichen Status ungeachtet des Datums in derselben Partition gespeichert werden. Ich denke, das sind viele Informationen für eine Partition. Cassandra funktioniert gut in Partitionen, die 100 MB (oder ein paar hundert MB in späteren Versionen) groß sind, siehe here. Datastax D220 cource (es ist kostenlos, Sie müssen nur ein Konto erstellen) hat eine video, die Ihnen zeigt, wie Sie Ihre Partitionsgröße berechnen.Sie können die Ergebnisse in Ihrer Analyse veröffentlichen, damit wir Ihnen weiterhelfen können. :)

EDIT: Nach der Größenanalyse

Sie Ihre Partition nach Datum, um kleinere Partition haben machen müssen. Das bedeutet, dass Sie jetzt nicht mehr nach Bereich suchen können. Eine Problemumgehung dafür wäre, mehrere Abfragen basierend auf dem gewünschten Bereich durchzuführen. Zum Beispiel: Wenn Sie eine Abfrage für den Zeitraum 12. August bis 14. August machen wollen, teilen Sie sich nach Tag auf und machen drei Abfragen, eine für 12. August, eine für 13 und eine für 14. Wenn Ihre Reichweite jedoch groß ist, werden Sie enden nach oben gb von Daten abrufen. Ich kenne Ihren Anwendungsfall nicht, aber ich gehe davon aus, dass Sie bei jeder Datumsbereichsabfrage keine GB-Dateien benötigen. Können Sie mir weitere Informationen zu Ihrem Anwendungsfall geben (a.k.a, was möchten Sie tun?)

ps. Ich kann noch keine Kommentare schreiben, also kann ich dich nur durch diese Antwort beraten

+0

Ich habe gerade meinen Beitrag mit den Ergebnissen der Partitionsanalyse bearbeitet :) – user3091275

Verwandte Themen