web-dev-qa-db-fra.com

Hive cluster by vs order by vs trier par

Autant que je sache

  • trier par tris seulement avec dans le réducteur

  • commander par les commandes les choses globalement, mais met tout dans un réducteurs

  • cluster par distribue intelligemment des choses dans les réducteurs par le hachage de la clé et faire un tri par

Ma question est donc la suivante: le cluster par garantit-il un ordre global? distribuer par met les mêmes clés dans les mêmes réducteurs mais qu'en est-il des clés adjacentes? 

Le seul document que je peux trouver à ce sujet est ici et à partir de l'exemple, il semble qu'il les commande globalement. Mais de la définition je sens que ça ne fait pas toujours ça.

50
cashmere

Une réponse plus courte: oui, CLUSTER BY garantit la commande globale, à condition que vous soyez prêt à joindre les fichiers de sortie multiples vous-même.

La version la plus longue:

  • ORDER BY x: garantit la commande globale, mais le fait en poussant toutes les données à travers un seul réducteur. Ceci est fondamentalement inacceptable pour les grands ensembles de données. Vous vous retrouvez avec un fichier trié en sortie.
  • SORT BY x: ordonne les données à chacun des N réducteurs, mais chaque réducteur peut recevoir des plages de données qui se chevauchent. Vous vous retrouvez avec au moins N fichiers triés avec des plages qui se chevauchent.
  • DISTRIBUTE BY x: garantit que chaque N réducteur obtient des plages de x qui ne se chevauchent pas, mais ne trie pas la sortie de chaque réducteur. Vous vous retrouvez avec au moins N fichiers non triés avec des plages ne se chevauchant pas.
  • CLUSTER BY x: veille à ce que chacun des N réducteurs obtienne des plages ne se chevauchant pas, puis trie ces plages sur les réducteurs. Cela vous donne un ordre global, et est identique à faire (DISTRIBUTE BY x et SORT BY x). Vous vous retrouvez avec au moins N fichiers triés avec des plages ne se chevauchant pas.

Avoir un sens? Donc, CLUSTER BY est fondamentalement la version la plus évolutive de ORDER BY.

138
Lars Yencken

Permettez-moi de préciser d'abord: clustered by distribue uniquement vos clés dans différents compartiments, clustered by ... sorted by triez les compartiments. 

Avec une expérience simple (voir ci-dessous), vous pouvez voir que vous ne recevrez pas de commande globale par défaut. La raison en est que le partitionneur par défaut divise les clés en utilisant des codes de hachage, quel que soit l'ordre des clés. 

Cependant, vous pouvez obtenir vos données totalement commandées. 

La motivation est "Hadoop: Le guide définitif" de Tom White (3e édition, chapitre 8, p. 274, Tri total), où il discute de TotalOrderPartitioner. 

Je vais d'abord répondre à votre question sur TotalOrdering, puis décrire plusieurs expériences Hive liées au tri que j'ai effectuées. 

N'oubliez pas: ce que je décris ici est une "preuve de concept", j'ai été en mesure de traiter un seul exemple à l'aide de la distribution CDH3 de Claudera. 

A l'origine, j'espérais que org.Apache.hadoop.mapred.lib.TotalOrderPartitioner ferait l'affaire. Malheureusement, ce n’est pas le cas, car il ressemble aux partitions Hive par valeur, pas par clé. Donc, je corrige (il devrait y avoir une sous-classe, mais je n’ai pas le temps pour ça):

Remplacer

public int getPartition(K key, V value, int numPartitions) {
    return partitions.findPartition(key);
}

avec

public int getPartition(K key, V value, int numPartitions) {
    return partitions.findPartition(value);
}

Vous pouvez maintenant définir TotalOrderPartitioner (corrigé) comme partitionneur Hive:

Hive> set Hive.mapred.partitioner=org.Apache.hadoop.mapred.lib.TotalOrderPartitioner;

Hive> set total.order.partitioner.natural.order=false

Hive> set total.order.partitioner.path=/user/yevgen/out_data2

J'ai aussi utilisé

Hive> set Hive.enforce.bucketing = true; 

Hive> set mapred.reduce.tasks=4;

dans mes tests.

Le fichier out_data2 indique à TotalOrderPartitioner comment définir des valeurs de compartiment. Vous générez out_data2 en échantillonnant vos données. Lors de mes tests, j'ai utilisé 4 compartiments et clés de 0 à 10. J'ai généré out_data2 en utilisant une approche ad-hoc:

import org.Apache.hadoop.util.ToolRunner;
import org.Apache.hadoop.util.Tool;
import org.Apache.hadoop.conf.Configured;
import org.Apache.hadoop.fs.Path;
import org.Apache.hadoop.io.NullWritable;
import org.Apache.hadoop.io.SequenceFile;
import org.Apache.hadoop.Hive.ql.io.HiveKey;
import org.Apache.hadoop.fs.FileSystem;


public class TotalPartitioner extends Configured implements Tool{
    public static void main(String[] args) throws Exception{
            ToolRunner.run(new TotalPartitioner(), args);
    }

    @Override
    public int run(String[] args) throws Exception {
        Path partFile = new Path("/home/yevgen/out_data2");
        FileSystem fs = FileSystem.getLocal(getConf());

        HiveKey key = new HiveKey();
        NullWritable value = NullWritable.get();

        SequenceFile.Writer writer = SequenceFile.createWriter(fs, getConf(), partFile, HiveKey.class, NullWritable.class);
        key.set( new byte[]{1,3}, 0, 2);//partition at 3; 1 came from Hive -- do not know why
        writer.append(key, value);
        key.set( new byte[]{1, 6}, 0, 2);//partition at 6
        writer.append(key, value);
        key.set( new byte[]{1, 9}, 0, 2);//partition at 9
        writer.append(key, value);
        writer.close();
        return 0;
    }

}

Ensuite, j'ai copié out_data2 dans HDFS (dans/user/yevgen/out_data2).

Avec ces paramètres, mes données ont été classées/classées (voir le dernier élément de ma liste de tests).

Voici mes expériences.

  • Créer des exemples de données

    bash> echo -e "1\n3\n2\n4\n5\n7\n6\n8\n9\n0"> data.txt

  • Créer une table de test de base:

    Hive> créer un test de table (x int); Hive> charger le fichier inpath local 'data.txt' dans le test de table;

Fondamentalement, cette table contient des valeurs de 0 à 9 sans ordre.

  • Démontrer le fonctionnement de la copie de table (paramètre vraiment mapred.reduce.tasks qui définit le nombre MAXIMAL de tâches de réduction à utiliser)

    Hive> create table test2 (x int);

    Ruche> set mapred.reduce.tasks = 4;

    Hive> insérer la table d'écrasement test2sélectionnez a.x à partir du test a Rejoindre le test b Sur a.x = b.x; - joint stupide pour forcer la carte non-trivial-réduire

    bash> hadoop fs -cat/user/Hive/warehouse/test2/000001_0

    1

    5

    9

  • Démontrer le seau. Vous pouvez voir que les clés sont assignées au hasard sans ordre de tri:

    Hive> create table test3 (x int) Groupé par (x) en 4 compartiments;

    Hive> set Hive.enforce.bucketing = true; 

    Hive> insert overwrite table test3 Sélectionnez * dans test;

    bash> hadoop fs -cat/user/Hive/warehouse/test3/000000_0

    4

    8

  • Seau avec tri. Les résultats sont partiellement triés, pas totalement triés

    Ruche> créer la table test4 (x int) Groupée par (x) triée par (x desc) En 4 compartiments;

    Hive> insert remplacez la table test4select * du test;

    bash> hadoop fs -cat/user/Hive/warehouse/test4/000001_0

    1

    5

    9

Vous pouvez voir que les valeurs sont triées par ordre croissant. Ressemble à un bug de la ruche dans CDH3?

  • Obtenir partiellement trié sans cluster par instruction:

    Hive> create table test5 asselect x À partir du test Distribuez par x Sort par x desc;

    bash> hadoop fs -cat/user/Hive/warehouse/test5/000001_0

    9

    5

    1

  • Utilisez mon correctif TotalOrderParitioner:

    Ruche> set Hive.mapred.partitioner = org.Apache.hadoop.mapred.lib.TotalOrderPartitioner;

    Ruche> set total.order.partitioner.natural.order = false

    Ruche> set total.order.partitioner.path =/user/training/out_data2

    Hive> create table test6 (x int) Groupé par (x) trié par (x) dans 4 compartiments;

    Hive> insert overwrite table test6 Sélectionnez * dans test;

    bash> hadoop fs -cat/user/Hive/warehouse/test6/000000_0

    1

    2

    bash> hadoop fs -cat/user/Hive/warehouse/test6/000001_0

    3

    4

    5

    bash> hadoop fs -cat/user/Hive/warehouse/test6/000002_0

    7

    6

    8

    bash> hadoop fs -cat/user/Hive/warehouse/test6/000003_0

    9

13
Yevgen Yampolskiy

Si j'ai bien compris, la réponse courte est Non… .. Vous obtiendrez des plages qui se chevauchent.

De Documentation SortBy : "Le cluster par est un raccourci pour les distributions et le tri par." "Toutes les lignes avec les mêmes colonnes Distribuer par iront au même réducteur." Mais il n'y a pas d'information qui Distribuer par garantie des gammes ne se chevauchent pas.

En outre, à partir de de la documentation DDL BucketedTables : "Comment Hive distribue-t-il les lignes dans les compartiments? En général, le numéro de compartiment est déterminé par l'expression hash_function (bucketing_column) mod num_buckets." Je suppose que Les instructions Cluster by in Select utilisent le même principe pour répartir les lignes entre les réducteurs, car elles servent principalement à remplir des tables à compartiments avec les données.

J'ai créé une table avec 1 colonne entière "a", et y ai inséré des nombres de 0 à 9.

Ensuite, je règle le nombre de réducteurs à 2 set mapred.reduce.tasks = 2;.

Et les données select de cette table avec la clause Cluster byselect * from my_tab cluster by a;

Et reçu le résultat que j'attendais:

0
2
4
6
8
1
3
5
7
9

Ainsi, le premier réducteur (numéro 0) a des nombres pairs (car leur mode 2 donne 0)

et le deuxième réducteur (numéro 1) a des nombres impairs (car leur mode 2 donne 1)

Voilà comment "Distribute By" fonctionne.

Et ensuite, "Trier par" trie les résultats dans chaque réducteur.

4
Anton Zaviriukhin

CLUSTER BY ne produit pas de commande globale.

La réponse acceptée (par Lars Yencken) induit en erreur en indiquant que les réducteurs recevront des gammes ne se chevauchant pas. Comme Anton Zaviriukhin pointe correctement la documentation de BucketedTables, CLUSTER BY est fondamentalement DISTRIBUTE BY (identique au seau) et SORT BY au sein de chaque compartiment/réducteur. Et DISTRIBUTE BY ne fait que hacher et mods dans des compartiments et bien que la fonction de hachage puisse préserver l’ordre (hachage de i> hash de j si i> j), mod de valeur de hachage ne le fait pas.

Voici un meilleur exemple montrant des plages qui se chevauchent

http://myitlearnings.com/bucketing-in-Hive/

4
Edi Bice

Le cluster par est un tri par réducteur pas global. Dans de nombreux livres, il est également mentionné de manière incorrecte ou source de confusion. Cela est particulièrement utile lorsque vous distribuez chaque département à un réducteur spécifique, puis que vous triez par nom d'employé dans chaque département sans vous soucier de l'ordre d'utilisation du cluster et qu'il est plus performant que la charge de travail est répartie entre les réducteurs .

0
user3423890

SortBy: N ou plusieurs fichiers triés avec des plages qui se chevauchent.

OrderBy: Une seule sortie, c’est-à-dire entièrement commandée.

Distribuer par: Distribuer En protégeant chacun des N réducteurs, il obtient des plages non superposées de la colonne mais ne trie pas la sortie de chaque réducteur.

Pour plus d'informations http://commandstech.com/Hive-sortby-vs-orderby-vs-distributeby-vs-clusterby/

ClusterBy: Reportez-vous au même exemple que ci-dessus. Si nous utilisons Cluster By x, les deux réducteurs trieront davantage les lignes sur x:

0
ss sreekanth

Cas d'utilisation: quand il y a un grand ensemble de données, il faut alors trier par, comme dans trier par, tous les réducteurs d'ensembles trient les données en interne avant de les matraquer ensemble et cela améliore les performances. Dans Order by, les performances du jeu de données plus volumineux sont réduites car toutes les données sont transmises via un seul réducteur, ce qui augmente la charge et prend donc plus de temps pour exécuter la requête. Veuillez voir l'exemple ci-dessous sur un cluster à 11 nœuds.  enter image description here 

Celui-ci est la commande par exemple, sortie  enter image description here 

Celui-ci est Sort By example output  enter image description here 

Celui-ci est Cluster Par exemple  enter image description here 

Ce que j’ai observé, les chiffres triés par, groupés par et distribués par estMÊMEMais le mécanisme interne est différent. Dans DISTRIBUTE BY: Les mêmes lignes de colonne iront à un réducteur, par exemple. DISTRIBUER BY (Ville) - Données de Bangalore dans une colonne, données de Delhi dans un réducteur:

 enter image description here 

0
Tutu Kumari