Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Erfahren Sie, wie Sie Notizbücher koordinieren und Code in Notizbüchern modularisieren. Sehen Sie sich Beispiele an, und erfahren Sie, wann alternative Methoden für die Notebook-Orchestrierung verwendet werden sollten.
Orchestrierungs- und Code-Modularisierungsmethoden
In der folgenden Tabelle werden die methoden verglichen, die zum Orchestrieren von Notizbüchern und zum Modularisieren von Code in Notizbüchern verfügbar sind.
Methode | Anwendungsfall | Hinweise |
---|---|---|
Lakeflow-Aufträge | Notizbuch-Orchestrierung (empfohlen) | Empfohlene Methode für das Orchestrieren von Notizbüchern. Unterstützt komplexe Workflows mit Vorgangsabhängigkeiten, Terminplanungen und Triggern. Bietet einen robusten und skalierbaren Ansatz für Produktionsworkloads, erfordert jedoch Setup und Konfiguration. |
dbutils.notebook.run() | Notebook-Orchestrierung | Verwenden Sie diese Option dbutils.notebook.run() , wenn Aufträge Ihren Anwendungsfall nicht unterstützen können, z. B. das Durchlaufen von Notizbüchern über einen dynamischen Satz von Parametern.Startet einen neuen kurzlebigen Auftrag für jeden Anruf, der den Aufwand erhöhen kann und keine erweiterten Planungsfeatures aufweist. |
Arbeitsbereichsdateien | Code-Modularisierung (empfohlen) | Empfohlene Methode zum Modularisieren von Code. Modularisieren Sie Code in wiederverwendbare Codedateien, die im Arbeitsbereich gespeichert sind. Unterstützt die Versionssteuerung mit Repos und Integration mit IDEs, um das Debuggen und Komponententests zu verbessern. Erfordert zusätzliche Einrichtung zum Verwalten von Dateipfaden und Abhängigkeiten. |
%run | Code-Modularisierung | Verwenden Sie %run , wenn Sie nicht auf Arbeitsbereichsdateien zugreifen können.Importieren Sie einfach Funktionen oder Variablen aus anderen Notizbüchern, indem Sie sie inline ausführen. Nützlich für die Prototyperstellung, kann aber zu eng gekoppelten Code führen, der schwieriger zu verwalten ist. Unterstützt keine Parameterübergabe oder Versionssteuerung. |
%run
Vs. dbutils.notebook.run()
Mit dem Befehl %run
können Sie ein anderes Notebook in ein Notebook einbeziehen. Sie können mit %run
Ihren Code modularisieren, indem Sie unterstützende Funktionen in einem separaten Notizbuch ablegen. Sie können damit auch Notebooks verketten, die die Schritte in einer Analyse implementieren. Wenn Sie %run
verwenden, wird das aufgerufene Notebook sofort ausgeführt, und die darin definierten Funktionen und Variablen werden im aufrufenden Notebook verfügbar.
Die dbutils.notebook
API ergänzt %run
, da Sie Parameter an ein Notizbuch übergeben und diese zurückgeben können. Dadurch können Sie komplexe Workflows und Pipelines mit Abhängigkeiten erstellen. Sie können beispielsweise eine Liste von Dateien in einem Verzeichnis abrufen und die Namen an ein anderes Notizbuch übergeben, was mit %run
nicht möglich ist. Sie können auch if-then-else-Workflows basierend auf Rückgabewerten erstellen.
Im Gegensatz zu %run
startet die dbutils.notebook.run()
-Methode einen neuen Auftrag zum Ausführen des Notebooks.
Wie alle dbutils
APIs sind diese Methoden nur in Python und Scala verfügbar. Sie können jedoch mithilfe von dbutils.notebook.run()
ein R-Notebook aufrufen.
Verwenden von %run
zum Importieren eines Notebooks
In diesem Beispiel wird im ersten Notebook die Funktion reverse
definiert, die im zweiten Notebook verfügbar ist, nachdem Sie den Magic-Befehl %run
zum Ausführen von shared-code-notebook
verwendet haben.
Da sich beide Notizbücher im Arbeitsbereich im gleichen Verzeichnis befinden, verwenden Sie das Präfix ./
./shared-code-notebook
, um anzugeben, dass der Pfad relativ zum aktuell ausgeführten Notizbuch aufgelöst werden soll. Sie können Notebooks in Verzeichnissen organisieren (z. B. %run ./dir/notebook
) oder einen absoluten Pfad wie %run /Users/username@organization.com/directory/notebook
angeben.
Hinweis
-
%run
muss sich in einer eigenen Zelle befinden, da hiermit das gesamte Notebook inline ausgeführt wird. - Sie können
%run
verwenden, um eine Python-Datei auszuführen und einenimport
-Vorgang vorzunehmen, um die in dieser Datei definierten Entitäten in ein Notebook zu importieren. Informationen zum Importieren aus einer Python-Datei finden Sie unter Modularisieren Ihres Codes mithilfe von Dateien. Sie können die Datei auch in einer Python-Bibliothek packen, eine Azure Databricks-Bibliothek aus dieser Python-Bibliothek erstellen und die Bibliothek in dem Cluster installieren, den Sie zum Ausführen Ihres Notebooks verwenden. - Wenn Sie
%run
ein Notizbuch ausführen, das Widgets enthält, wird das angegebene Notizbuch normalerweise mit den voreingestellten Werten des Widgets ausgeführt. Sie können auch Werte an Widgets übergeben; siehe Verwenden von Databricks-Widgets mit %run.
Verwenden Sie dbutils.notebook.run
, um einen neuen Auftrag zu starten
Führt ein Notebook aus und gibt dessen EXIT-Wert zurück. Die Methode startet einen kurzlebigen Auftrag, der sofort ausgeführt wird.
In der dbutils.notebook
-API stehen die Methoden run
und exit
zur Verfügung. Sowohl Parameter als auch Rückgabewerte müssen Zeichenfolgen sein.
run(path: String, timeout_seconds: int, arguments: Map): String
Der timeout_seconds
Parameter steuert das Timeout der Ausführung (0 bedeutet kein Timeout). Der Aufruf an run
löst eine Ausnahme aus, wenn er nicht innerhalb des angegebenen Zeitraums abgeschlossen wird. Wenn Azure Databricks länger als 10 Minuten ausfällt, schlägt die Ausführung des Notebooks unabhängig von timeout_seconds
fehl.
Der Parameter arguments
legt die Widgetwerte des Zielnotebooks fest. Wenn das von Ihnen ausgeführte Notebook über ein Widget mit dem Namen A
verfügt und Sie das Schlüssel-Wert-Paar ("A": "B")
als Teil der Argumente an den Aufruf von run()
übergeben, wird A
beim Abrufen des Werts des Widgets "B"
zurückgegeben. Eine Anleitung zum Erstellen und Verwenden von Widgets finden Sie im Artikel zu Databricks-Widgets.
Hinweis
- Der Parameter
arguments
akzeptiert nur lateinische Zeichen (ASCII-Zeichensatz). Die Verwendung von Nicht-ASCII-Zeichen führt zu einem Fehler. - Aufträge, die unter Verwendung der
dbutils.notebook
-API erstellt werden, müssen innerhalb von maximal 30 Tagen abgeschlossen werden.
run
Verwendung
Python
dbutils.notebook.run("notebook-name", 60, {"argument": "data", "argument2": "data2", ...})
Scala
dbutils.notebook.run("notebook-name", 60, Map("argument" -> "data", "argument2" -> "data2", ...))
Übergeben von strukturierten Daten zwischen Notizbüchern
In diesem Abschnitt wird veranschaulicht, wie strukturierte Daten zwischen Notebooks übergeben werden.
Python
# Example 1 - returning data through temporary views.
# You can only return one string using dbutils.notebook.exit(), but since called notebooks reside in the same JVM, you can
# return a name referencing data stored in a temporary view.
## In callee notebook
spark.range(5).toDF("value").createOrReplaceGlobalTempView("my_data")
dbutils.notebook.exit("my_data")
## In caller notebook
returned_table = dbutils.notebook.run("LOCATION_OF_CALLEE_NOTEBOOK", 60)
global_temp_db = spark.conf.get("spark.sql.globalTempDatabase")
display(table(global_temp_db + "." + returned_table))
# Example 2 - returning data through DBFS.
# For larger datasets, you can write the results to DBFS and then return the DBFS path of the stored data.
## In callee notebook
dbutils.fs.rm("/tmp/results/my_data", recurse=True)
spark.range(5).toDF("value").write.format("parquet").save("dbfs:/tmp/results/my_data")
dbutils.notebook.exit("dbfs:/tmp/results/my_data")
## In caller notebook
returned_table = dbutils.notebook.run("LOCATION_OF_CALLEE_NOTEBOOK", 60)
display(spark.read.format("parquet").load(returned_table))
# Example 3 - returning JSON data.
# To return multiple values, you can use standard JSON libraries to serialize and deserialize results.
## In callee notebook
import json
dbutils.notebook.exit(json.dumps({
"status": "OK",
"table": "my_data"
}))
## In caller notebook
import json
result = dbutils.notebook.run("LOCATION_OF_CALLEE_NOTEBOOK", 60)
print(json.loads(result))
Scala
// Example 1 - returning data through temporary views.
// You can only return one string using dbutils.notebook.exit(), but since called notebooks reside in the same JVM, you can
// return a name referencing data stored in a temporary view.
/** In callee notebook */
sc.parallelize(1 to 5).toDF().createOrReplaceGlobalTempView("my_data")
dbutils.notebook.exit("my_data")
/** In caller notebook */
val returned_table = dbutils.notebook.run("LOCATION_OF_CALLEE_NOTEBOOK", 60)
val global_temp_db = spark.conf.get("spark.sql.globalTempDatabase")
display(table(global_temp_db + "." + returned_table))
// Example 2 - returning data through DBFS.
// For larger datasets, you can write the results to DBFS and then return the DBFS path of the stored data.
/** In callee notebook */
dbutils.fs.rm("/tmp/results/my_data", recurse=true)
sc.parallelize(1 to 5).toDF().write.format("parquet").save("dbfs:/tmp/results/my_data")
dbutils.notebook.exit("dbfs:/tmp/results/my_data")
/** In caller notebook */
val returned_table = dbutils.notebook.run("LOCATION_OF_CALLEE_NOTEBOOK", 60)
display(sqlContext.read.format("parquet").load(returned_table))
// Example 3 - returning JSON data.
// To return multiple values, use standard JSON libraries to serialize and deserialize results.
/** In callee notebook */
// Import jackson json libraries
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
import com.fasterxml.jackson.databind.ObjectMapper
// Create a json serializer
val jsonMapper = new ObjectMapper with ScalaObjectMapper
jsonMapper.registerModule(DefaultScalaModule)
// Exit with json
dbutils.notebook.exit(jsonMapper.writeValueAsString(Map("status" -> "OK", "table" -> "my_data")))
/** In caller notebook */
// Import jackson json libraries
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
import com.fasterxml.jackson.databind.ObjectMapper
// Create a json serializer
val jsonMapper = new ObjectMapper with ScalaObjectMapper
jsonMapper.registerModule(DefaultScalaModule)
val result = dbutils.notebook.run("LOCATION_OF_CALLEE_NOTEBOOK", 60)
println(jsonMapper.readValue[Map[String, String]](result))
Fehlerbehandlung
In diesem Abschnitt wird die Behandlung von Fehlern veranschaulicht.
Python
# Errors throw a WorkflowException.
def run_with_retry(notebook, timeout, args = {}, max_retries = 3):
num_retries = 0
while True:
try:
return dbutils.notebook.run(notebook, timeout, args)
except Exception as e:
if num_retries > max_retries:
raise e
else:
print("Retrying error", e)
num_retries += 1
run_with_retry("LOCATION_OF_CALLEE_NOTEBOOK", 60, max_retries = 5)
Scala
// Errors throw a WorkflowException.
import com.databricks.WorkflowException
// Since dbutils.notebook.run() is just a function call, you can retry failures using standard Scala try-catch
// control flow. Here, we show an example of retrying a notebook a number of times.
def runRetry(notebook: String, timeout: Int, args: Map[String, String] = Map.empty, maxTries: Int = 3): String = {
var numTries = 0
while (true) {
try {
return dbutils.notebook.run(notebook, timeout, args)
} catch {
case e: WorkflowException if numTries < maxTries =>
println("Error, retrying: " + e)
}
numTries += 1
}
"" // not reached
}
runRetry("LOCATION_OF_CALLEE_NOTEBOOK", timeout = 60, maxTries = 5)
Gleichzeitiges Ausführen mehrerer Notebooks
Sie können mehrere Notebooks gleichzeitig ausführen, indem Sie Standardkonstrukte von Scala und Python wie Threads (Scala, Python) und Futures (Scala, Python) verwenden. Die Beispielnotebooks veranschaulichen die Nutzung dieser Konstrukte.
- Laden Sie die folgenden vier Notizbücher herunter. Die Notebooks wurden in Scala geschrieben.
- Importieren Sie die Notebooks in einen einzelnen Ordner im Arbeitsbereich.
- Führen Sie das Notebook gleichzeitig aus.