web-dev-qa-db-fra.com

Comment copier des données d'une table Cassandra vers une autre structure pour de meilleures performances

À plusieurs endroits, il est conseillé de concevoir nos tables Cassandra en fonction des requêtes que nous allons effectuer sur elles. Dans cet article de DataScale , elles déclarent ceci:

La vérité est qu'avoir de nombreux tableaux similaires avec des données similaires est une bonne chose à Cassandra. Limitez la clé primaire à ce que vous rechercherez exactement. Si vous prévoyez de rechercher les données avec des critères similaires, mais différents, faites-en un tableau distinct. Il n'y a aucun inconvénient à avoir les mêmes données stockées différemment. La duplication des données est votre amie à Cassandra.

[...]

Si vous devez stocker la même donnée dans 14 tables différentes, écrivez-la 14 fois. Il n'y a pas de handicap contre plusieurs écritures.

J'ai compris cela, et maintenant ma question est: à condition d'avoir une table existante, disons

CREATE TABLE invoices (
    id_invoice int PRIMARY KEY,
    year int,
    id_client int,
    type_invoice text
)

Mais je veux interroger par année et par type à la place, donc j'aimerais avoir quelque chose comme

CREATE TABLE invoices_yr (
    id_invoice int,
    year int,
    id_client int,
    type_invoice text,
    PRIMARY KEY (type_invoice, year)
)

Avec id_invoice comme clé de partition et year comme clé de clustering, quelle est la meilleure façon de copier les données d'une table vers une autre vers effectuer des requêtes optimisées plus tard?

Ma Cassandra:

user@cqlsh> show version;
[cqlsh 5.0.1 | Cassandra 3.5.0 | CQL spec 3.4.0 | Native protocol v4]
12
astrojuanlu

Pour faire écho à ce qui a été dit à propos de la commande COPY, c'est une excellente solution pour quelque chose comme ça.

Cependant, je ne suis pas d'accord avec ce qui a été dit sur le chargeur en vrac, car il est infiniment plus difficile à utiliser. Plus précisément, car vous devez l'exécuter sur chaque nœud (alors que COPY ne doit être exécuté que sur un seul nœud).

Pour aider à l'échelle COPY pour des ensembles de données plus volumineux, vous pouvez utiliser les paramètres PAGETIMEOUT et PAGESIZE.

COPY invoices(id_invoice, year, id_client, type_invoice) 
  TO 'invoices.csv' WITH PAGETIMEOUT=40 AND PAGESIZE=20;

En utilisant ces paramètres de manière appropriée, j'ai déjà utilisé COPY pour exporter/importer avec succès 370 millions de lignes.

Pour plus d'informations, consultez cet article intitulé: Nouvelles options et meilleures performances dans la copie cqlsh .

8
Aaron

Vous pouvez utiliser la commande cqlsh COPY :
Pour copier les données de vos factures dans un fichier csv, utilisez:

COPY invoices(id_invoice, year, id_client, type_invoice) TO 'invoices.csv';

Et copiez à partir du fichier csv vers la table dans votre cas factures_yr utiliser:

COPY invoices_yr(id_invoice, year, id_client, type_invoice) FROM 'invoices.csv';

Si vous avez d'énormes données, vous pouvez utiliser sstable writer pour écrire et sstableloader pour charger les données plus rapidement. http://www.datastax.com/dev/blog/using-the-cassandra-bulk-loader-updated

11
Ashraful Islam

Une alternative à l'utilisation de la commande COPY (voir d'autres réponses pour des exemples) ou Spark pour migrer les données est de créer une vue matérialisée pour faire la dénormalisation pour vous.

CREATE MATERIALIZED VIEW invoices_yr AS
       SELECT * FROM invoices
       WHERE id_client IS NOT NULL AND type_invoice IS NOT NULL AND id_client IS NOT NULL
       PRIMARY KEY ((type_invoice), year, id_client)
       WITH CLUSTERING ORDER BY (year DESC)

Cassandra remplira alors le tableau pour vous, vous n'aurez donc pas à migrer vous-même. Avec 3.5, sachez que les réparations ne fonctionnent pas bien (voir CASSANDRA-12888 ).

Remarque: les vues matérialisées ne sont probablement pas la meilleure idée à utiliser et ont été changées en statut "expérimental"

4
Chris Lohfink