2013-08-29 3 views
6

Je veux insérer une seule ligne avec 50 000 colonnes dans Cassandra 1.2.8. Avant d'insérer, j'ai toutes les données pour toute la ligne prêt à aller (en mémoire):En utilisant Cassandra et CQL3, comment insérer une ligne large entière dans une seule requête?

+---------+------+------+------+------+-------+ 
|   | 0 | 1 | 2 | ... | 49999 | 
| row_id +------+------+------+------+-------+ 
|   | text | text | text | ... | text | 
+---------+------+------+------|------+-------+ 

Les noms de colonnes sont des nombres entiers, ce qui permet le découpage de pagination. Les valeurs de colonne sont une valeur à cet index particulier.

définition de la table CQL3:

create table results (
    row_id text, 
    index int, 
    value text, 
    primary key (row_id, index) 
) 
with compact storage; 

Comme je l'ai déjà row_id et toutes les paires nom 50 000/valeur en mémoire, je veux juste insérer une ligne unique dans Cassandra dans une seule requête/opération il est aussi vite que possible.

La seule chose que je peux sembler trouver est de faire exécuter les 50.000 heures suivantes:

INSERT INTO results (row_id, index, value) values (my_row_id, ?, ?); 

la première ? est est un compteur d'index (i) et la seconde ? est la valeur de texte pour stocker à emplacement i.

Cela prend beaucoup de temps. Même lorsque nous mettons les INSERT ci-dessus dans un lot, cela prend beaucoup de temps.

Nous avons toutes les données dont nous avons besoin (la ligne complète) dans son intégralité, je suppose qu'il est très facile de simplement dire "ici, Cassandra, stocker ces données en une seule ligne dans une demande", par exemple :

//EXAMPLE-BUT-INVALID CQL3 SYNTAX: 
insert into results (row_id, (index,value)) values 
    ((0,text0), (1,text1), (2,text2), ..., (N,textN)); 

Cet exemple n'est pas possible via la syntaxe CQL3 actuelle, mais j'espère que cela illustre l'effet désiré: tout serait inséré comme une seule requête.

Est-il possible de faire cela dans CQL3 et le pilote Java DataStax? Si non, je suppose que je serai obligé d'utiliser Hector ou le pilote Astyanax et l'opération Thrift batch_insert à la place?

+0

Avez-vous essayé d'utiliser les listes/séries/cartes. Pour ce cas, il devrait faire l'affaire mais, comme Alex le dit, cela ferait un ajout intéressant à CQL3. – jorgebg

+0

Oui, nous avons essayé, et il était assez rapide, mais il rompt complètement le modèle de données souhaitées: vous ne pouvez pas faire des requêtes de tranche sur les collections de CQL3. –

Répondre

3

Edit: seulement 4 jours après que j'ai posté cette question concernant Cassandra 1.2.9, Cassandra 2.0 a été libéré finale. 2.0 prend en charge les instructions préparées par lots, qui devrait être beaucoup plus rapide que la CQL3 non-batched qui devait être utilisée pour C * < 2.0.Nous n'avons pas encore testé cela pour être sûr.

Lorsque cette question a été publiée il y a 4 jours le 30 Août 2013, il n'a pas été possible dans CQL3 pour les versions C * moins de 2,0. Cela n'était possible que via un client Thrift, par ex. Astyanax MutationBatch.

Par la suggestion d'Alex, j'ai créé CASSANDRA-5959 comme une demande de fonctionnalité, mais il a été marqué comme un doublon à CASSANDRA-4693, qui a censément résolu le problème pour C * 2.0.

+3

Merci Les. Bien que je sois d'accord que cela pourrait être considéré à ce moment-là comme une limitation du pilote java, je pense en fait qu'il s'agit plus d'une limitation CQL. Espérons que les gars de Cassandra seront d'accord et l'ajouteront. –

+0

En plus de cela - j'ai eu une conversation avec thobbs sur le canal #cassandra. Il a déclaré que les lots non envoyés envoyés à une partition sont exécutés en une seule opération, de sorte que des requêtes assez efficaces peuvent être obtenues de cette manière. La suggestion était de traiter des tailles de ~ 1k pour éviter de mettre trop de pression sur un nœud. –

2
  1. CQL3 déclaration INSERT ne prend pas en charge tuples de valeurs multiples. Mais je pense que cela pourrait faire un ajout intéressant à CQL alors s'il vous plaît submit a feature request. Le pilote Java DataStax est basé sur CQL. Il y a donc quelque chose à faire si l'instruction n'est pas supportée.

  2. Pour le moment si vous avez besoin ce votre meilleure option serait d'utiliser une bibliothèque basée Thrift (nb : Je ne suis pas très familier avec l'API basée Thrift à confirmer cette insertion serait possible, mais Je pense qu'il devrait)

+0

Juste une mise à jour - c'est certainement possible avec Thrift. Notre test avec le pilote Java Datastax et un batch CQL3 (en utilisant l'API 'Batch') sur une machine de développement locale a duré 1,5 minutes. La même opération avec Astyanax (via un [MutationBatch] (http://netflix.github.io/astyanax/javadoc/com/netflix/astyanax/MutationBatch.html) alias 'batch_mutate') a 235 _milliseconds_. Cela n'est pas de bon augure pour le pilote Java Datastax dans notre projet. Cela étant dit, je suis un citoyen ouvert reconnaissant, alors je vais ouvrir une demande de fonctionnalité. –

+0

@Les Hazlewood PERF est si mal avec l'API de bain réelle probablement parce qu'il est question de texte brut (texte pour l'analyse syntaxique est cher). Si vous avez l'occasion de tester l'API par lots en utilisant une instruction préparée, je serai intéressé à en avoir les résultats. Il y avait un grand débat sur CQL3 perf vs Thrift – doanduyhai

+0

Si je me souviens d'afficher les résultats une fois que nous avons testé, je le ferai certainement! –

3

INSERTs/plusieurs mises à jour peuvent être effectuées en utilisant la méthode batch_mutate dans les API Thrift, en utilisant la mutation multi-cartes.

Map<byte[], Map<String, List<Mutation>>> mutationMap = new HashMap<byte[], Map<String, List<Mutation>>>(); 

List<Mutation> mutationList = new ArrayList<Mutation>(); 

mutationList.add(mutation); 
Map<String, List<Mutation>> m = new HashMap<String, List<Mutation>>(); 

m.put(columnFamily, mutationList); 

mutationMap.put(key, m); 
client.batch_mutate(mutationMap, ConsistencyLevel.ALL); 
+0

la question est de savoir comment faire avec 3 CQL pas Thrift – Adrian

0

utilisation Déclaration de lot dans CQL3 si vous voulez faire insérer plusieurs.

Avec C * 2.0, il sera encore plus facile et plus rapide car ils permettent la déclaration préparée par lots

+0

Par mon message d'origine, les instructions Batch dans CQL3 pour les lignes larges

+0

Entièrement d'accord avec vous Les Hazlewood. Heureusement, C * 2.0 vient de sortir et vous pouvez y aller avec :) – doanduyhai

+0

J'ai essayé des instructions batch avec Cassandra 2.0, et ça reste douloureusement lent. http://stackoverflow.com/questions/21778671/how-to-insert-a-wide-row-with-good-performance-using-cql –

Questions connexes