2016-07-25 37 views
0

Ich verwende [cqlsh 5.0.1 | Kassandra 2.2.1 | CQL-Spezifikation 3.3.0 | Natives Protokoll v4] Version. Ich habe 2 Knoten cassandra Cluster mit Replikationsfaktor als 2.Cassandra Abfrage auf Sekundärindex: ReadTimeout: code = 1200

$ nodetool status test_keyspace 
Datacenter: datacenter1 
======================= 
Status=Up/Down 
|/ State=Normal/Leaving/Joining/Moving 
-- Address  Load  Tokens  Owns (effective) Host ID       Rack 
UN 10.xxx.4.xxx 85.32 GB 256   100.0%   xxxx-xx-xx-xx-xx    rack1 
UN 10.xxx.4.xxx 80.99 GB 256   100.0%   x-xx-xx-xx-xx     rack1 

[I mit x ersetzt Nummern haben]

Dies ist defination Schlüsselraum.

cqlsh> describe test_keyspace; 

CREATE KEYSPACE test_keyspace WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '2'} AND durable_writes = true; 

CREATE TABLE test_keyspace.test_table (
    id text PRIMARY KEY, 
    listids map<int, timestamp> 
) WITH 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 dclocal_read_repair_chance = 0.1 
    AND default_time_to_live = 0 
    AND gc_grace_seconds = 864000 
    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 = '99.0PERCENTILE'; 
CREATE INDEX list_index ON test_keyspace.test_table (keys(listids)); 

id sind einzigartig und listids's Schlüssel hat Mächtigkeit der Nähe von 1000. Ich Millionen Datensätze in dieser Schlüsselraum haben.

Ich möchte die Anzahl der Datensätze mit bestimmten Schlüssel und auch Liste dieser Datensätze erhalten. Ich habe versucht, diese Abfrage von cqlsh:

select count(1) from test_table where listids contains key 12; 

habe diesen Fehler nach wenigen Sekunden:

ReadTimeout: code=1200 [Coordinator node timed out waiting for replica nodes' responses] message="Operation timed out - received only 0 responses." info={'received_responses': 0, 'required_responses': 1, 'consistency': 'ONE'} 

Ich habe bereits modifizierte Timeout-Parameter in cqlshrc und cassandra.yaml.

cat /etc/cassandra/conf/cassandra.yaml | grep read_request_timeout_in_ms 
#read_request_timeout_in_ms: 5000 
read_request_timeout_in_ms: 300000 

cat ~/.cassandra/cqlshrc 
[connection] 
timeout = 36000 
request_timeout = 36000 
client_timeout = 36000 

Wenn ich /var/log/cassandra/system.log geprüft habe ich nur this-

WARN [SharedPool-Worker-157] 2016-07-25 11:56:22,010 SelectStatement.java:253 - Aggregation query used without partition key 

Ich bin mit Java-Client meinen Code bilden. Der Java-Client erhält auch viele Lese-Timeouts. Eine Lösung könnte die Umgestaltung meiner Daten sein, aber das wird mehr Zeit in Anspruch nehmen (obwohl ich mir nicht sicher bin). Kann jemand eine schnelle Lösung dieses Problems vorschlagen?

Hinzufügen Statistik:

$ nodetool cfstats test_keyspace 
Keyspace: test_keyspace 
    Read Count: 5928987886 
    Read Latency: 3.468279416568199 ms. 
    Write Count: 1590771056 
    Write Latency: 0.02020026287239664 ms. 
    Pending Flushes: 0 
     Table (index): test_table.list_index 
     SSTable count: 9 
     Space used (live): 9664953448 
     Space used (total): 9664953448 
     Space used by snapshots (total): 4749 
     Off heap memory used (total): 1417400 
     SSTable Compression Ratio: 0.822577888909709 
     Number of keys (estimate): 108 
     Memtable cell count: 672265 
     Memtable data size: 30854168 
     Memtable off heap memory used: 0 
     Memtable switch count: 0 
     Local read count: 1718274 
     Local read latency: 63.356 ms 
     Local write count: 1031719451 
     Local write latency: 0.015 ms 
     Pending flushes: 0 
     Bloom filter false positives: 369 
     Bloom filter false ratio: 0.00060 
     Bloom filter space used: 592 
     Bloom filter off heap memory used: 520 
     Index summary off heap memory used: 144 
     Compression metadata off heap memory used: 1416736 
     Compacted partition minimum bytes: 73 
     Compacted partition maximum bytes: 2874382626 
     Compacted partition mean bytes: 36905317 
     Average live cells per slice (last five minutes): 5389.0 
     Maximum live cells per slice (last five minutes): 51012 
     Average tombstones per slice (last five minutes): 2.0 
     Maximum tombstones per slice (last five minutes): 2759 

     Table: test_table 
     SSTable count: 559 
     Space used (live): 62368820540 
     Space used (total): 62368820540 
     Space used by snapshots (total): 4794 
     Off heap memory used (total): 817427277 
     SSTable Compression Ratio: 0.4856571513639344 
     Number of keys (estimate): 96692796 
     Memtable cell count: 2587248 
     Memtable data size: 27398085 
     Memtable off heap memory used: 0 
     Memtable switch count: 558 
     Local read count: 5927272991 
     Local read latency: 3.788 ms 
     Local write count: 559051606 
     Local write latency: 0.037 ms 
     Pending flushes: 0 
     Bloom filter false positives: 4905594 
     Bloom filter false ratio: 0.00023 
     Bloom filter space used: 612245816 
     Bloom filter off heap memory used: 612241344 
     Index summary off heap memory used: 196239565 
     Compression metadata off heap memory used: 8946368 
     Compacted partition minimum bytes: 43 
     Compacted partition maximum bytes: 1916 
     Compacted partition mean bytes: 173 
     Average live cells per slice (last five minutes): 1.0 
     Maximum live cells per slice (last five minutes): 1 
     Average tombstones per slice (last five minutes): 1.0 
     Maximum tombstones per slice (last five minutes): 1 
+0

Ich konfrontiert das gleiche Problem. Ausprobiert 1) # Kann auch auf Keine gesetzt werden, um zu deaktivieren: client_timeout = Keine in cqlshrc in home .cassandra. Hat nicht geholfen. 2) Erhöht das Timeout * timeout_in_ms in ym.cassandra.yaml Hat auch nicht geholfen. Schließlich entschied ich mich für eine laufende Schleife auf Select-Klausel in meinem Java-Code und empfangene Anzahl. 12 Millionen Zeilen gaben mir in 7 Sekunden. Es ist schnell. –

Antwort

0

können Sie entweder Ihre Tabellen neu zu gestalten, oder teilen Sie Ihre Abfrage in mehreren kleineren Abfragen.

Sie wählen mit einem sekundären Index, ohne den Partitionsschlüssel zu verwenden (das ist, was die Warnung Ihnen sagt). Auf diese Weise führen Sie im Wesentlichen einen vollständigen Tabellenscan durch. Ihre Knoten müssen in jede Partition schauen, um Ihre Anfrage zu erfüllen.

Eine Lösung ohne Änderung des Datenmodells wäre, über alle Partitionen zu iterieren und Ihre Abfrage einmal pro Partition auszuführen.

select count(*) from test_table where id = 'somePartitionId' and listids contains key 12; 

Auf diese Weise wissen Ihre Knoten, auf welcher Partition Sie nach diesen Informationen suchen. Sie müssten dann die Ergebnisse dieser Abfrage auf der Clientseite aggregieren.

+0

Eine Klärung .. In meinem Fall, ID sollte Partition Schlüssel (nicht sicher) und Ids sind fast einzigartig (auch Millionen Datensätze) dann wie werde ich abfragen? –

+0

Ich würde ehrlich empfehlen, Ihr Datamodell umzugestalten. Bei Millionen von Partitionen könnte man natürlich jede Partition separat (parallel) abfragen, aber das wird natürlich viel Zeit in Anspruch nehmen. – HashtagMarkus

0

Ich konfrontiert das gleiche Problem. versucht 1) # Kann auch auf Keine gesetzt werden, um zu deaktivieren: client_timeout = Keine in cqlshrc in home .cassandra. Hat nicht geholfen.

2) erhöhte den Timeout * timeout_in_ms in ym.cassandra.yaml

Haben auch nicht geholfen. Schließlich entschied ich mich für eine laufende Schleife auf Select-Klausel in meinem Java-Code und empfangene Anzahl. 12 Millionen Zeilen gaben mir in 7 Sekunden. Es ist schnell.

Cluster cluster = Cluster.builder() 
      .addContactPoints(serverIp) 
      .build(); 

    session = cluster.connect(keyspace); 


    String cqlStatement = "SELECT count(*) FROM imadmin.device_appclass_attributes"; 
    //String cqlStatement = "SELECT * FROM system_schema.keyspaces"; 
    for (Row row : session.execute(cqlStatement)) { 
     System.out.println(row.toString()); 
    }