2017-05-12 5 views
1

Ich verarbeite Daten in U-SQL, aber nicht zu erwarteten Ergebnissen. Hier ist, was ich tue:ADLA-Job produziert keine erwarteten Ergebnisse

1- Select data from ADL table partitions and assign it to @data1 

2- Aggregate data using Group BY and assign it to @data2 

3- Truncate partitions 

4- Insert data(produced in step 2) into the same table 

5- Use @data2 and generate a unique GUID for every record using user 
defined function and assign it to @data2 
     //UDF Code 
     public static Guid GetNewGuid() 
     { 
     return Guid.NewGuid(); 
     } 

6- Select few columns from @data2 and assign it to @data3 

Seltsamer GUIDs in @ Daten2 und @ data3 sind völlig verschieden.

Wenn ich einige Joins mit anderen Datasets durchführen und Schema in Schritt 5 ändern und dann eindeutige GUIDs generieren, dann bekomme ich die gleichen GUIDS im letzten Schritt. Es sieht so aus, als ob im Backend, das dieses Problem verursacht, eine Skriptoptimierung stattfindet.

Könnten Sie mir bitte mitteilen, was im obigen Workflow passiert? Oder wenn im Backend eine Art von Optimierung stattfindet, dann erfahren Sie, wie die Skriptoptimierung funktioniert.

Update: In dieser Frage, mein Fokus ist zu lernen, warum etwas auf einem Schritt berechnet wird automatisch im nächsten Schritt geändert.

+0

Siehe [hier] (http://stackoverflow.com/questions/38964160/guid-newguid-always-return-same-guid-for-all-rows) für eine Antwort von Azure Data Lake Team. Guid ist nicht etwas, das Sie mit U-SQL verwenden sollten, um Datensätze eindeutig zu identifizieren, da sie möglicherweise "neu berechnet werden - zu fälligen Vertex-Wiederholungen, Leistungsoptimierungen usw.". – wBob

+0

Mögliches Duplikat von [Guid.NewGuid() gibt immer dasselbe Guid für alle Zeilen zurück] (http://stackoverflow.com/questions/38964160/guid-newguid-always-return-same-guid-for-all-rows) – wBob

+0

Danke für diesen Link. Ich werde dies für die eindeutige ID-Generierung berücksichtigen, aber für diese Frage habe ich einen anderen Fokus, den ich oben aktualisiert habe. – Jamil

Antwort

2

die aktualisierte Fokus Answering - warum auf einen Schritt berechnet etwas automatisch

im nächsten Schritt geändert wird, um die Frage

wBob der Auszug vollständig IMO beantwortet, aber vielleicht wird einem breiteren Kontext helfen.

Semantisch, ist die Antwort einfach

  • Weil Sie eine Nutzungsanforderung der Sprache (Determinismus) verletzt haben, das resultierende Verhalten ist undefined.
  • Undefiniert bedeutet, dass alles passieren kann, so dass Sie keine Erwartungen haben können - an konsistente Werte oder anders. Jede Diskussion über das tatsächliche Verhalten (verschiedene Guids) ist ein Implementierungsdetail.

    Semantic tiefer Tauchgang
    Schritte sind eine Illusion.

  • Anweisungen in einer imperativen Sprache wie C# sind eine Folge exakter Anweisungen (wie).

  • Statements in einer funktionalen Sprache wie U-SQL- sind eine Liste von Anforderungen, beschreibt Ausgänge in Bezug auf die Eingänge (was). Der U-Sql-Optimierer verfügt über umfassende Implementierungsflexibilität, um diese Anforderungen zu erfüllen. Rowsets sind logische Konstrukte zum Organisieren von Benutzeranforderungen, die zum Zeitpunkt der Implementierung nicht wirklich existieren müssen; während die Logik, die einem Rowset entspricht, in der Implementierung aufgeteilt, zusammengeführt, übersprungen, wiederholt usw. werden kann.

So zum Beispiel einer völlig legale Implementierung der Schritte 5, 6 unter der deterministischen Anforderung:

@data3 = SELECT <FewCols>, GetNewGuid() AS NewGuid FROM @data2; 
@data2 = SELECT *, GetNewGuid() AS NewGuid FROM @data2; 
+0

Könnten Sie bitte erklären, wie und was verletzt wird? Ich beziehe mich darauf: "Weil Sie eine Benutzungsanforderung der Sprache verletzt haben (Determinismus), ist das resultierende Verhalten undefiniert." – Jamil

+0

** Regel **: Nicht-_deterministische_ Logik ist in U-Sql nicht erlaubt. _ ** Deterministisch ** _: gleiche _Eingänge_ => gleiche _Ausgaben_ (d. H. Wiederholbar) _ ** Eingaben ** _ - Für UDFs Funktionsargumente, falls vorhanden. _ ** Ausgänge ** _ - Für UDFs, Funktionsausgabe. Funktionen wie Guid.NewGuid erfüllen diese Anforderung nicht (keine Eingabe, andere Ausgaben bei Wiederholung) - daher ist ihr Verhalten nicht definiert. Es gibt einige Nuancen (per @ Michael's Antwort - obwohl ich nicht sicher bin, ob Snapshotting eine Sprachgarantie oder eine bequeme aktuelle Implementierung ist), aber das beste mentale Modell, um damit anzufangen: verwende keinen nicht-deterministischen Laufzeitcode. – Nabeel

0

Willkommen zum See Nabeel. Ich freue mich auf mehr Ihrer Antworten!

Darüber hinaus ist das Verhalten mit nichtdeterministischen Funktionen ein wenig kompliziert durch die Tatsache, dass wir sie für einige Funktionen deterministisch machen (zB DateTime.Now()), wenn sie in U-SQL aber außerhalb von a erscheinen C# -Codeblock (z. B. eine benutzerdefinierte Funktion), aber sie bleiben innerhalb des C# -Codeblocks nicht deterministisch.

Die empfohlene Methode zum Erstellen von Schlüsseln ist eine Technik namens Skolemization, bei der Sie eine deterministische Schlüsselgenerierung basierend auf den identifizierenden Eigenschaften verwenden. So bleibst du deterministisch.

+0

Das ist kompliziert. :) Ich bin verwirrt, weil wenn ich einige Schritte von meinem Workflow ändere oder entferne, dann funktioniert es vollkommen in Ordnung. Zum Beispiel, wenn ich Schritt 3 und 4 entferne, dann funktioniert es gut. Wenn ich einige mit anderen Datensätzen verbinde, bevor ich IDs erzeuge, funktioniert es gut. Ich versuche zu lernen, wie die Dinge im See funktionieren. – Jamil

Verwandte Themen