2016-10-10 1 views
0

Je souhaite interroger une partition complète de ma table. Ma clé de partition composée est constituée de (id, date, hour_of_timestamp). id et date sont des chaînes, hour_of_timestamp est un nombre entier.Cassandra - Requête IN ou TOKEN pour interroger une partition entière?

J'avais besoin d'ajouter le champ hour_of_timestamp à ma clé de partition à cause des hotspots lors de l'ingestion des données.

Maintenant, je me demande quel est le moyen le plus efficace d'interroger une partition complète de mes données? Selon this blog, l'utilisation de SELECT * from mytable WHERE id = 'x' AND date = '10-10-2016' AND hour_of_timestamp IN (0,1,...23); entraîne beaucoup de surcharge sur le nœud du coordinateur.

Vaut-il mieux utiliser la fonction TOKEN et interroger la partition avec deux jetons? Tels que SELECT * from mytable WHERE TOKEN(id,date,hour_of_timestamp) >= TOKEN('x','10-10-2016',0) AND TOKEN(id,date,hour_of_timestamp) <= TOKEN('x','10-10-2016',23);

Ma question est: Dois-je utiliser la requête IN ou TOKEN pour interroger une partition complète de mes données? Ou devrais-je utiliser 23 requêtes (une pour chaque valeur de hour_of_timestamp) et laisser le conducteur faire le reste? J'utilise Cassandra 3.0.8 et le dernier pilote Java Datastax pour me connecter à un cluster à 6 nœuds.

+0

Pouvez-vous publier l'ensemble de votre définition PRIMARY KEY? – Aaron

+0

@AARON PRIMARY KEY ((log_creator, date, heure), ts, log_id) est la définition réelle. J'ai ajusté les noms de champs dans la question pour qu'ils soient plus "génériques" ... 'ts' est de type' timestamp' et 'log_id' est une autre chaîne. – j9dy

Répondre

1

Vous dites:

Maintenant, je me demande quelle est la façon la plus efficace d'interroger une partition complète de mes données? Selon ce blog, en utilisant SELECT * de mytable WHERE id = 'x' ET date = '10 -10-2016 'AND hour_of_timestamp IN (0,1, ... 23); provoque beaucoup de surcharge sur le noeud coordinateur.

mais en fait vous interroger 24 partitions. Ce que vous vouliez probablement dire, c'est que vous aviez une conception dans laquelle une seule partition était constituée de 24 partitions, car vous ajoutiez l'heure pour éviter un hotspot pendant l'ingestion de données. Notant que dans les deux modèles (l'ancien avec les hotspots et ce nouveau) Les données sont encore affichés par ordre timestamp, vous avez deux choix:

  1. Run 1 requête à temps.
  2. Exécutez 2 requêtes la première fois, puis une à la fois pour "préextraire" les résultats.
  3. Exécutez 24 requêtes en parallèle.

CASE 1

Si vous traitez de manière séquentielle de données, le premier choix est d'exécuter la requête pour l'heure 0, traiter les données et, lorsque vous avez terminé, exécutez la requête pour l'heure 1 et ainsi sur ... Ceci est une mise en œuvre simple, et je ne pense pas qu'elle mérite plus que cela.

CASE 2

Si vos requêtes prennent plus de temps que votre traitement de données, vous pouvez "prefetch" des données. Ainsi, la première fois que vous pourriez exécuter 2 requêtes en parallèle pour obtenir les données des heures 0 et 1, et commencer le traitement des données pour l'heure 0.En attendant, les données pour l'heure 1 arrivent, donc quand vous finissez de traiter les données pour l'heure 0, vous pouvez pré-visualiser les données pour l'heure 2 et commencer le traitement des données pour l'heure 1. Et ainsi de suite .... De cette façon vous pouvez accélérer les données En traitement. Bien sûr, en fonction de vos horaires (traitement des données et temps de requête), vous devez optimiser le nombre de requêtes "prefetch". Notez également que le pilote Java effectue automatiquement la pagination. En fonction de la taille de la partition récupérée, vous pouvez désactiver cette fonctionnalité pour éviter de bloquer le traitement des données ou récupérer plus de données de manière préventive comme this:

ResultSet rs = session.execute("your query"); 
for (Row row : rs) { 
    if (rs.getAvailableWithoutFetching() == 100 && !rs.isFullyFetched()) 
     rs.fetchMoreResults(); // this is asynchronous 
    // Process the row ... 
} 

où vous pouvez syntoniser que rs.getAvailableWithoutFetching() == 100 pour mieux répondre à vos besoins de prélecture.

Vous souhaiterez peut-être également pré-charger plus d'une partition la première fois, de sorte que vous vous assuriez que votre traitement n'attendra pas sur n'importe quelle partie de récupération de données.

CASE 3

Si vous avez besoin de traiter des données de différentes partitions ensemble, par exemple, vous avez besoin des deux données pour l'heure 3 et 6, vous pourriez essayer de regrouper les données par « dépendance » (par exemple interroger les deux heures 3 et 6 en parallèle). Si vous en avez besoin, exécutez 24 requêtes en parallèle, puis joignez-les au niveau de l'application (vous savez déjà pourquoi vous devez éviter l'entrée IN pour plusieurs partitions). Rappelez-vous que vos données sont déjà commandées, donc vos efforts au niveau de l'application seraient très faibles.