2016-07-25 2 views
0

J'utilise [cqlsh 5.0.1 | Cassandra 2.2.1 | Spécification CQL 3.3.0 | Version native du protocole v4]. J'ai 2 nœud de cluster de cassandra avec un facteur de réplication comme 2.Cassandra Query sur l'index secondaire: 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 

[J'ai remplacé avec le nombre x]

C'est keyspace defination.

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 sont la clé unique et listids's a cardinalité près de 1000. Je millions de disques dans ce keyspace.

Je souhaite obtenir le nombre d'enregistrements avec une clé spécifique et également la liste de ces enregistrements. J'ai essayé cette requête de cqlsh:

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

obtenu cette erreur après quelques secondes:

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'} 

Je l'ai déjà modifié les paramètres de délai d'attente dans cqlshrc et 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 

Quand je suis arrivé, je /var/log/cassandra/system.log obtenu que this-

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

J'utilise client Java former mon code. Le client Java reçoit également beaucoup de délais d'attente de lecture. Une solution pourrait être de remodeler mes données, mais cela prendra plus de temps (bien que je ne suis pas sûr à ce sujet). Quelqu'un peut-il suggérer une solution rapide à ce problème?

Ajout de statistiques:

$ 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

J'ai rencontré le même problème. essayé 1) # Peut également être défini sur Aucun pour désactiver: client_timeout = Aucun dans cqlshrc dans home .cassandra. N'a pas aidé. 2) Augmenté le timeout * timeout_in_ms dans ym.cassandra.yaml N'a pas aidé aussi. Finalement, je me suis installé en boucle d'exécution sur la clause select de mon code Java et j'ai reçu le compte. 12 millions de lignes m'ont donné le compte en 7 secondes. C'est rapide. –

Répondre

0

Vous pouvez redessiner vos tables, ou diviser votre requête dans plusieurs requêtes plus petites.

Vous sélectionnez en utilisant un index secondaire sans utiliser la clé de partition (c'est ce que l'avertissement vous indique). En faisant cela, vous effectuez essentiellement une analyse de table complète. Vos nœuds doivent regarder dans chaque partition afin de répondre à votre demande.

Une solution sans changer le modèle de données serait, itérer sur toutes les partitions et exécuter votre requête une fois par partition. De cette façon, vos nœuds savent sur quelle partition vous recherchez ces informations. Vous devrez alors agréger les résultats de ces requêtes sur clientide.

+0

Une clarification..Dans mon cas, 'id' devrait être la clé de partition (pas sûr) et les ID sont presque uniques (aussi des millions d'enregistrements) alors comment vais-je interroger? –

+0

Je recommanderais honnêtement de remodeler votre datamodel. Avec des millions de partitions, vous pouvez néanmoins interroger chaque partition séparément (en parallèle), mais cela prendra évidemment beaucoup de temps. – HashtagMarkus

0

J'ai fait face au même problème. 1) # Peut également être défini sur Aucun pour désactiver: client_timeout = Aucun dans cqlshrc dans home .cassandra. N'a pas aidé.

2) a augmenté le délai d'attente * timeout_in_ms dans ym.cassandra.yaml

N'a pas aidé aussi. Finalement, je me suis installé en boucle d'exécution sur la clause select de mon code Java et j'ai reçu le compte. 12 millions de lignes m'ont donné le compte en 7 secondes. C'est rapide.

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()); 
    }