it-swarm.com.de

Hive-Cluster nach vs sortieren nach vs sortieren nach

So weit ich das verstehe;

  • sortiere nur Sortiert mit im Reduzierer

  • order by ordnet die Dinge global an, schiebt aber alles in einen Reduzierer

  • cluster by verteilt auf intelligente Weise Inhalte durch den Schlüsselhash in Reduktionen und führt eine Sortierung durch

Meine Frage ist also, ob Cluster eine globale Ordnung garantiert? verteilen, indem Sie dieselben Schlüssel in dieselben Reduzierungen stecken, aber was ist mit den benachbarten Schlüsseln? 

Das einzige Dokument, das ich dazu finden kann, ist hier und aus dem Beispiel scheint es, als würde es sie global anordnen. Aber von der Definition habe ich das Gefühl, dass es das nicht immer tut.

50
cashmere

Eine kürzere Antwort: Ja, CLUSTER BY garantiert eine globale Reihenfolge, sofern Sie die mehreren Ausgabedateien selbst beitreten möchten.

Die längere Version:

  • ORDER BY x: garantiert eine globale Reihenfolge, tut dies aber, indem alle Daten durch nur einen Reduzierer gedrückt werden. Dies ist grundsätzlich für große Datensätze nicht akzeptabel. Sie erhalten eine sortierte Datei als Ausgabe.
  • SORT BY x: ordnet Daten bei jedem von N Reduzierern an, aber jeder Reduzierer kann überlappende Datenbereiche empfangen. Sie erhalten N oder mehr sortierte Dateien mit überlappenden Bereichen.
  • DISTRIBUTE BY x: Stellt sicher, dass jeder der N Reduzierer nicht überlappende Bereiche von x erhält, aber die Ausgabe jedes Reduzierers nicht sortiert wird. Sie erhalten am Ende N oder mehr unsortierte Dateien mit nicht überlappenden Bereichen.
  • CLUSTER BY x: Stellt sicher, dass jeder der N Reduzierungen nicht überlappende Bereiche erhält und dann nach diesen Bereichen an den Reduzierern sortiert wird. Dies gibt Ihnen eine globale Reihenfolge und entspricht der Vorgehensweise (DISTRIBUTE BY x und SORT BY x). Sie erhalten N oder mehr sortierte Dateien mit nicht überlappenden Bereichen.

Sinn ergeben? CLUSTER BY ist also im Grunde die besser skalierbare Version von ORDER BY.

138
Lars Yencken

Lassen Sie mich zunächst klarstellen: clustered by verteilt Ihre Schlüssel nur in verschiedene Buckets, clustered by ... sorted by erhalten Buckets sortiert. 

Mit einem einfachen Experiment (siehe unten) können Sie sehen, dass Sie standardmäßig keine globale Reihenfolge erhalten. Der Grund ist, dass der Standard-Partitionierer Schlüssel unabhängig von der tatsächlichen Schlüsselreihenfolge mithilfe von Hashcodes aufteilt. 

Sie können jedoch Ihre Daten vollständig bestellen lassen. 

Motivation ist "Hadoop: The Definitive Guide" von Tom White (3. Ausgabe, Kapitel 8, S. 274, Total Sort), in dem er über TotalOrderPartitioner spricht. 

Ich werde zuerst Ihre TotalOrdering-Frage beantworten und dann einige sortierte Hive-Experimente beschreiben, die ich gemacht habe. 

Denken Sie daran: Was ich hier beschreibe, ist ein "Proof of Concept". Ich konnte ein einziges Beispiel mit Clauderas CDH3-Distribution behandeln. 

Ursprünglich hoffte ich, dass org.Apache.hadoop.mapred.lib.TotalOrderPartitioner den Trick ausführen wird. Leider nicht, weil es aussieht wie Hive-Partitionen nach Wert und nicht nach Schlüssel. Also patche ich es (sollte Unterklasse haben, aber ich habe keine Zeit dafür):

Ersetzen

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

mit

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

Jetzt können Sie (gepatcht) TotalOrderPartitioner als Hive-Partitionierer festlegen:

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

Ich habe auch benutzt

Hive> set Hive.enforce.bucketing = true; 

Hive> set mapred.reduce.tasks=4;

in meinen Tests.

Die Datei out_data2 teilt TotalOrderPartitioner mit, wie die Werte zu sammeln sind. Sie generieren out_data2, indem Sie Ihre Daten abtasten. In meinen Tests habe ich 4 Buckets und Schlüssel von 0 bis 10 verwendet. Ich habe out_data2 mithilfe eines Ad-hoc-Ansatzes generiert:

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

}

Dann habe ich das Ergebnis out_data2 nach HDFS kopiert (in/user/yevgen/out_data2)

Mit diesen Einstellungen wurden meine Daten sortiert (siehe letzter Eintrag in meiner Experimentierliste).

Hier sind meine Experimente.

  • Erstellen Sie Beispieldaten

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

  • Erstellen Sie grundlegende Testtabelle:

    Hive> Erstellen Sie einen Tabellentest (x int); Hive> Laden Sie den lokalen lokalen Pfad "data.txt" in den Tabellentest;

Grundsätzlich enthält diese Tabelle Werte von 0 bis 9 ohne Reihenfolge.

  • Demonstrieren, wie das Kopieren von Tabellen funktioniert (Parameter "wirklich mapred.reduce.tasks", der die MAXIMAL-Anzahl der zu verwendenden reduzierten Aufgaben festlegt)

    Hive> create table test2 (x int);

    Bienenstock> set mapred.reduce.tasks = 4;

    Struktur> Einfügetabelle überschreiben test2wähle a.x aus Test a Join test b Auf a.x = b.x; - stupied join um nicht-triviale Kartenreduzierung zu erzwingen

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

    1

    5

    9

  • Bucketing demonstrieren. Sie können sehen, dass die Schlüssel ohne Sortierreihenfolge zufällig ausgewählt werden:

    Hive> create table test3 (x int) Gruppiert nach (x) in 4 Buckets;

    Hive> set Hive.enforce.bucketing = true; 

    Hive> Überschreibe Tabelle einfügen test3 * Aus dem Test auswählen;

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

    4

    8

  • Eimer mit Sortierung. Die Ergebnisse sind teilweise sortiert, nicht vollständig sortiert

    Hive> create table test4 (x int) Gruppiert nach (x) sortiert nach (x desc) In 4 Buckets;

    Hive> Überschreibe Tabelle einfügen test4select * from test;

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

    1

    5

    9

Sie sehen, dass die Werte aufsteigend sortiert sind. Sieht aus wie Hive-Fehler in CDH3?

  • Teilweise ohne Cluster nach Anweisung sortiert werden:

    Hive> Erzeuge die Tabelle test5 alswähle x Aus dem Test Verteile nach x Sortiere nach x desc;

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

    9

    5

    1

  • Verwenden Sie meinen gepatchten TotalOrderParitioner:

    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/training/out_data2

    Hive> create table test6 (x int) Gruppiert nach (x) sortiert nach (x) in 4 Buckets;

    Struktur> Einfügungstabelle überschreiben test6 Select * from 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

Wie ich es verstehe, lautet die kurze Antwort Nein .. Sie erhalten überlappende Bereiche.

Aus SortBy-Dokumentation : "Cluster By ist eine Abkürzung für sowohl" Verteilen nach "als auch" Sortieren nach "." "Alle Zeilen mit derselben Spalte" Verteilen nach "werden zu demselben Reduzierer geführt." .__ Es gibt jedoch keine Informationen, die durch nicht überlappende Bereiche verteilen.

Aus DDL BucketedTables-Dokumentation : "Wie verteilt Hive die Zeilen über die Buckets? Im Allgemeinen wird die Bucket-Nummer durch den Ausdruck hash_function (bucketing_column) mod num_buckets bestimmt." .__ Die Anweisung "Cluster by in Select" verwendet dasselbe Prinzip zum Verteilen von Zeilen zwischen Reduzierern, da sie hauptsächlich zum Auffüllen von Bucketed-Tabellen mit den Daten verwendet wird.

Ich habe eine Tabelle mit einer ganzzahligen Spalte "a" erstellt und dort Zahlen von 0 bis 9 eingefügt.

Dann setze ich die Anzahl der Reduzierstücke auf 2 set mapred.reduce.tasks = 2;.

Und select-Daten aus dieser Tabelle mit Cluster by-Klausel select * from my_tab cluster by a;

Und erhielt ein Ergebnis, das ich erwartet hatte:

0
2
4
6
8
1
3
5
7
9

So erhielt der erste Reduzierer (Nummer 0) gerade Zahlen (weil ihr Modus 2 0 ergibt)

und der zweite Reduzierer (Nummer 1) erhielt ungerade Zahlen (weil ihr Modus 2 1 ergibt)

So funktioniert "Verteilen nach".

Anschließend sortiert "Sortieren nach" die Ergebnisse in jedem Reduzierer.

4

CLUSTER BY erzeugt keine globale Reihenfolge.

Die akzeptierte Antwort (von Lars Yencken) führt in die Irre, indem angegeben wird, dass die Untersetzungsgetriebe nicht überlappende Bereiche erhalten. Da Anton Zaviriukhin korrekt auf die Dokumentation zu BucketedTables hinweist, ist CLUSTER BY im Grunde DISTRIBUTE BY (wie Bucketing) plus SORT BY innerhalb jedes Buckets/Reduktors. Und DISTRIBUTE BY hasht und mods einfach in Buckets und während die Hash-Funktion may order (Hash von i> Hash von j, wenn i> j), gilt, mod von Hashwert nicht.

Hier ist ein besseres Beispiel für überlappende Bereiche

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

4
Edi Bice

Cluster by ist pro Reducer Sortierung nicht global. In vielen Büchern wird es auch falsch oder verwirrend erwähnt. Es ist besonders nützlich, wenn Sie sagen, Sie verteilen jede Abteilung auf bestimmte Reduzierer und sortieren dann nach dem Namen des Mitarbeiters in jeder Abteilung. Dabei ist es egal, in welcher Reihenfolge der Cluster verwendet wird, und er ist leistungsfähiger, da die Arbeitslast auf die Reduzierer verteilt wird .

0
user3423890

SortBy: N oder mehr sortierte Dateien mit überlappenden Bereichen.

OrderBy: Einzelausgabe, dh vollständig bestellt.

Verteilen nach: Verteilen Durch das Schützen jedes N Reduzierers werden nicht überlappende Bereiche der Spalte erhalten, die Ausgabe jedes Reduzierers wird jedoch nicht sortiert.

Weitere Informationen http://commandstech.com/Hive-sortby-vs-orderby-vs-distributeby-vs-clusterby/

ClusterBy: Verweisen Sie auf dasselbe Beispiel wie oben. Wenn Sie Cluster By x verwenden, werden die beiden Reduzierstücke die Zeilen in x weiter sortieren:

0
ss sreekanth

Anwendungsfall: Wenn es einen großen Datensatz gibt, sollte man sortieren nach wie in sortieren nach, alle Mengenreduzierer sortieren die Daten intern, bevor sie zusammengelegt werden, und das verbessert die Leistung. Während des Vorgangs "Sortieren nach" verringert sich die Leistung für den größeren Datensatz, da alle Daten durch einen einzelnen Reduzierer geleitet werden, wodurch die Last erhöht wird und die Ausführung der Abfrage länger dauert. Das folgende Beispiel zeigt einen Cluster mit 11 Knoten.  enter image description here 

Dies ist Order By Beispiel Ausgabe  enter image description here 

Dies ist Sort By example output  enter image description here 

Dieser ist Cluster By Example  enter image description here 

Was ich beobachtet habe, sind die Zahlen von sortieren nach, gruppieren nach und verteilen nachDASSELBEAber der interne Mechanismus ist anders. In DISTRIBUTE BY: Dieselben Spaltenzeilen werden zu einem Reduzierer geleitet, z. VERTEILEN NACH (Stadt) - Bangalore-Daten in einer Spalte, Delhi-Daten in einem Reduzierer:

 enter image description here 

0
Tutu Kumari