2016-08-07 11 views
0

Ich habe mit einem rätselhaften Verhalten beim Ausführen von SELECTs auf Cassandra 2.2.3. Ich habe 4 Knoten im Ring, und ich erstelle den folgenden Schlüsselraum, Tabelle und Index.Cassandra SELECT auf sekundären Index gibt keine Zeile zurück

CREATE KEYSPACE IF NOT EXISTS my_keyspace 
    WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}; 

CREATE TABLE my_keyspace.my_table (
    id text, 
    some_text text, 
    code text, 
    some_set set<int>, 
    a_float float, 
    name text, 
    type int, 
    a_double double, 
    another_set set<int>, 
    another_float float, 
    yet_another_set set<text>, 
    PRIMARY KEY (id, some_text, code) 
) WITH read_repair_chance = 0.0 
    AND dclocal_read_repair_chance = 0.1 
    AND gc_grace_seconds = 864000 
    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' } 
    AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' } 
    AND default_time_to_live = 0 
    AND speculative_retry = '99.0PERCENTILE' 
    AND min_index_interval = 128 
    AND max_index_interval = 2048; 

CREATE INDEX idx_my_table_code ON my_keyspace.my_table (code); 

Dann füge ich einige Zeilen auf dem Tisch ein. Einige von ihnen haben leere Sätze. Ich führe diese Abfrage durch die Standard CQL Client und bekommen Sie die Zeile ich erwarte:

SELECT * FROM my_table WHERE code = 'test'; 

Dann laufe ich ein paar Tests, die außerhalb meiner Kontrolle sind. Ich weiß nicht, was sie tun, aber ich erwarte, dass sie einige Zeilen lesen und möglicherweise einfügen/aktualisieren/löschen. Ich bin sicher, dass sie keine der Einstellungen im Index, in der Tabelle oder im Schlüsselraum löschen oder ändern.

Nach den Tests logge ich mich erneut über den Standard-CQL-Client ein und führe die folgenden Abfragen aus.

SELECT * FROM my_table WHERE code = 'test'; 
SELECT * FROM my_table; 
SELECT * FROM my_table WHERE id = 'my_id' AND some_text = 'whatever' AND code = 'test'; 

Der erste gibt nichts zurück. Der zweite gibt alle Zeilen zurück, einschließlich der mit code = 'test'. Der dritte gibt die erwartete Zeile zurück, die die erste Abfrage nicht abrufen konnte.

Der einzige Unterschied, den ich zwischen dieser Zeile und anderen sehen kann, ist, dass es eine der Zeilen ist, die einige leere Sätze enthält, wie zuvor erläutert. Wenn ich nach einer anderen der Zeilen suche, die auch einige leere Mengen enthalten, bekomme ich das gleiche Verhalten.

Ich würde sagen, das Problem bezieht sich auf den sekundären Index. Irgendwie verlassen die während der Tests durchgeführten Operationen den Index in einem Zustand, in dem bestimmte Zeilen nicht sichtbar sind.

Ich vermisse offensichtlich etwas. Hast du irgendwelche Ideen, was zu diesem Verhalten führen könnte?

Vielen Dank im Voraus.

UPDATE:

arbeitete ich, um das Problem, aber jetzt fand ich das gleiche Problem woanders. Da das Problem zum ersten Mal aufgetreten ist, habe ich mehr über die vor dem Fehler ausgeführten Vorgänge erfahren: Aktualisierungen für bestimmte Spalten, die eine TTL für diese Spalten festlegen. Nach einigen Untersuchungen fand ich einige Jira Fragen, die zu diesem Problem zusammenhängen könnte:

https://issues.apache.org/jira/browse/CASSANDRA-6782 https://issues.apache.org/jira/browse/CASSANDRA-8206

Allerdings scheinen diese Fragen auf 2.0 und 2.1 gelöst worden zu sein, und ich bin mit 2.2. Ich denke, diese Änderungen sind in 2.2 enthalten, aber ich könnte mich irren.

Antwort

1

Das Hauptproblem ist der Typ der Abfrage, die Sie auf Cassandra ausführen. Das Cassadra-Datenmodell wird abfragegesteuert, Tabellen werden zur Abfrage neu berechnet.

Tabellen werden mit einem klar definierten Primärschlüssel (Partition Key & Clustring Key) erstellt. Cassandra eignet sich nicht für Abfragen vom Typ "Vollständiger Tabellenscan".

Nun zu Ihren Fragen.

  1. SELECT * FROM my_table WHERE code = 'test';

Hier ist die Spalte Spalte clustring verwendet und die Spalte Gleichheit Suche sollte es Teil der Partition Schlüssel sein. Der Glättungsschlüssel wird in verschiedenen Partitionen vorhanden sein. Wenn die Lesekonsistenzstufe 1 ist, kann dies zu einem leeren Ergebnis führen.

  1. SELECT * FROM my_table;

Cassandra für diese Art von Table-Scan-Abfrage nicht gut ist. Hier wird die gesamte Tabelle durchsucht und alle Zeilen abgerufen (schlechte Abfrage).

  1. SELECT * FROM my_table WHERE id = 'my_id' AND some_text = 'whatever' AND code = 'test';

Hier finden Sie alles erwähnt, so dass die richtigen Ergebnisse zurückgegeben wurden.

+0

Danke für die Antwort, aber ich bin mir nicht sicher, dass das das Problem ist. Ich stimme zu, dass die erste Abfrage in der Regel ein Problem wäre und die Verwendung von ALLOW FILTERING erfordern würde, aber ich habe einen sekundären Index für die Spalte "code", der mir eine direkte Abfrage dieser Spalte ermöglichen soll. Read CL = 1 könnte sich auf das Ergebnis auswirken, wenn ich mehrere Replikate hätte und die Daten nicht bei jedem von ihnen wären, aber ich habe RF = 1. – ebautistabar

Verwandte Themen