dbx,由 Databricks Labs 提供

重要

本文档已过时,将来可能不会更新。

Databricks 建议使用声明性自动化捆绑包,而不是由 Databricks Labs 提供的 dbx。 请参阅 什么是声明性自动化捆绑包? 以及如何 从 dbx 迁移到捆绑包

注意

本文介绍 Databricks Labs 的 dbx,它按原样提供,Databricks 不会通过客户技术支持渠道为它提供支持。 可以通过 GitHub 上的 databrickslabs/dbx 存储库的 Issues 页传达问题和功能请求。

Databricks Labs 提供的 dbx 是一个open source工具,旨在扩展旧版 Databricks 命令行接口(Databricks CLI),并为Azure Databricks平台上的快速开发生命周期和持续集成和持续交付/部署(CI/CD)提供功能。

dbx 简化了跨多个环境的作业启动和部署过程。 它还有助于打包项目,并以版本化的方式将其传送到Azure Databricks环境。 它以 CLI 优先方式设计,旨在同时在 CI/CD 管道内部和本地工具(如本地 IDE(包括Visual Studio Code和 PyCharm)中主动使用。

使用 dbx 的典型开发工作流为:

  1. 如果还没有可用的远程存储库,则使用 Databricks 支持的 Git 提供程序创建一个远程存储库。

  2. 将远程存储库克隆到Azure Databricks工作区。

  3. 在Azure Databricks工作区中创建或移动Azure Databricks笔记本到克隆的存储库中。 使用此笔记本开始对要运行 Azure Databricks clusters 的代码进行原型制作。

  4. 若要通过添加单独的帮助器类和函数、配置文件和测试来增强和模块化笔记本代码,请改用装有 dbx、首选 IDE 和 Git 的本地开发计算机。

  5. 将远程存储库克隆到本地开发计算机。

  6. 将笔记本中的代码移入一个或多个本地代码文件。

  7. 在本地编写代码时,将工作从本地存储库推送到远程存储库。 此外,sync远程存储库与Azure Databricks工作区。

    提示

    或者,可以使用 dbx sync 自动将本地文件更改与工作区中的相应文件实时同步。

  8. 继续使用Azure Databricks工作区中的笔记本进行快速原型制作,并将验证的代码从笔记本移动到本地计算机。 继续使用本地 IDE 来执行诸如代码模块化、代码补全、代码检查、单元测试和代码及对象的单步调试等任务,这些任务不要求与 Azure Databricks 实时连接。

  9. 根据需要使用 dbx 在目标群集上批量运行本地代码。 (这类似于在 Spark 的 目录中运行 bin 脚本,以在 Spark 群集上启动应用程序。)

  10. 准备好生产后,请使用 CI/CD 平台(如 GitHub Actions)或 GitLab在群集上自动运行远程存储库的代码。

要求

若要使用 dbx,必须在本地开发计算机上安装以下各项,无论代码使用的是 Python、Scala 还是 Java:

  • Python 3.8 或更高版本。

    如果您的代码使用Python,则应使用与目标群集上安装的Python版本相匹配的Python版本。 若要获取安装在现有群集上的Python版本,可以使用群集的 web 终端运行 python --version 命令。 另请参阅 Databricks Runtime 发行说明版本和兼容性中的“系统环境”部分,了解适用于你的目标群集的 Databricks Runtime 版本。

  • pip

  • 如果代码使用Python,则创建Python虚拟环境的方法,以确保在 dbx 项目中使用正确的Python和包依赖项版本。 本文将介绍 pipenv

  • dbx 版本 0.8.0 或更高版本。 可以通过运行 pip install dbx,从Python包索引(PyPI)安装此包。

    若要确认是否已安装 dbx,请运行以下命令:

    dbx --version
    

    如果返回版本号,则已安装 dbx

    如果版本号低于 0.8.0,请运行以下命令来升级 dbx,然后再次查看版本号:

    pip install dbx --upgrade
    dbx --version
    
    # Or ...
    python -m pip install dbx --upgrade
    dbx --version
    
  • Databricks CLI 0.18 或更低版本,通过身份验证安装。 安装 dbx 时,系统会自动安装旧版 Databricks CLI(Databricks CLI 版本 0.17)。 可以在本地开发计算机上的以下一个或两个位置设置此身份验证:

    • DATABRICKS_HOSTDATABRICKS_TOKEN 环境变量中(从旧版 Databricks CLI 版本 0.8.0 开始)。
    • 在 Azure Databricks 配置文件中.databrickscfg 文件中。

    dbx 分别在这两个位置查找身份验证凭据。 dbx 仅使用它找到的第一组匹配的凭据。

    注意

    从旧版 Databricks CLI 0.17.2 开始,dbx 不支持使用 .netrc 文件进行身份验证。 若要检查已安装的旧版 Databricks CLI,请运行命令 databricks --version

  • 用于推送和同步本地与远程代码更改的 git

继续按照适用于以下 IDE 之一的说明操作:

注意

Databricks 已验证了将上述 IDE 与 dbx 配合使用;但是,dbx 应该可与任何 IDE 配合使用。 也可以不使用 IDE(仅限终端)

dbx经过优化,可以处理单文件Python代码文件和编译的 Scala 和 Java JAR 文件。 dbx 无法处理单文件 R 代码文件或已编译的 R 代码包。 这是因为 dbx 使用作业 API 2.02.1,而这些 API 无法将单文件 R 代码文件或已编译的 R 代码包作为作业运行。

Visual Studio Code

请完成以下说明,以开始使用 Visual Studio Codedbx Python。

在本地开发计算机上,除了满足一般要求以外,还必须安装以下组件:

按照以下步骤开始设置 dbx 项目结构:

  1. 在终端中创建一个空白文件夹。 这些说明使用名为 dbx-demo 的文件夹。 可以为 dbx 项目的根文件夹指定所需的任何名称。 如果使用其他名称,请在所有这些步骤中替换该名称。 创建文件夹后,切换到该文件夹,然后从该文件夹中开始Visual Studio Code。

    对于 Linux 和 macOS:

    mkdir dbx-demo
    cd dbx-demo
    code .
    

    提示

    如果在运行 command not found: code 后显示 code .,请参阅 Microsoft 网站上的命令行中的 Launching

    对于Windows:

    md dbx-demo
    cd dbx-demo
    code .
    
  2. 在Visual Studio Code中,为此项目创建Python虚拟环境:

    1. 在菜单栏上,单击“视图”>“终端”

    2. dbx-demo 文件夹的根目录中,使用以下选项运行 pipenv 命令,其中 <version> 是本地安装的目标版本Python(理想情况下是与目标群集版本Python匹配的版本),例如 3.8.14

      pipenv --python <version>
      

      记下 Virtualenv location 命令输出中的 pipenv 值,因为在下一步骤中需要用到。

  3. 选择目标Python解释器,然后激活Python虚拟环境:

    1. 在菜单栏上,单击View >命令面板,键入 Python: Select,然后单击Python:选择解释器
    2. 在刚创建的Python虚拟环境的路径中选择Python解释器。 (此路径在 Virtualenv location 命令的输出中作为 pipenv 值列出。)
    3. 在菜单栏上,单击“视图”>“命令面板”,键入 ,然后单击“终端: 创建新终端”Terminal: Create

    有关详细信息,请参阅 Visual Studio Code 文档中的 在 VS Code 中使用Python环境

  4. 继续创建 dbx 项目

PyCharm

完成以下说明,开始将 PyCharm 和 Python 与 dbx 配合使用。

在本地开发计算机上,除了满足一般要求以外,还必须安装 PyCharm

按照以下步骤开始设置 dbx 项目结构:

  1. 在 PyCharm 的菜单栏上,单击“File >新建Project

  2. 在“创建Project对话框中,选择新project的位置。

  3. 展开 Python 解释器:新的 Pipenv 环境

  4. 选择“新建环境的方式”(如果尚未选择),然后从下拉列表中选择“Pipenv”

  5. 对于 Base 解释器,请选择包含已在本地安装的Python目标版本的Python解释器的位置(理想情况下是与目标群集的 Python 版本匹配的版本)。

  6. 对于“Pipenv 可执行文件”,请选择包含本地安装的 的位置(如果尚未自动检测到)pipenv

  7. 如果你要创建一个极简的 dbx 项目,并想要将 main.py 文件用于该极简 dbx 项目,请选中“创建 main.py 欢迎脚本”框。 否则清除此框。

  8. 单击“创建”。

  9. Project 工具窗口中,右键单击项目的根文件夹,然后点击 在 > 终端中打开

  10. 继续创建 dbx 项目

IntelliJ 理念

按照以下说明完成操作,以便开始将 IntelliJ IDEA 和 Scala 与 dbx 配合使用。 按照这些说明执行操作可以创建一个基于 sbt 的极简 Scala 项目,该项目可用于启动 dbx 项目。

在本地开发计算机上,除了满足一般要求以外,还必须安装以下组件:

  • IntelliJ IDEA
  • 适用于 IntelliJ IDEA 的 Scala 插件。 有关详细信息,请参阅 IntelliJ IDEA 文档中的发现适用于 Scala 的 IntelliJ IDEA
  • Java运行时环境 (JRE) 8。 尽管 JRE 8 的任何版本都应适用,但 Databricks 迄今为止仅验证了将 dbx 和 IntelliJ IDEA 与 OpenJDK 8 JRE 配合使用。 Databricks 尚未使用 IntelliJ IDEA 和 Java 11 验证 dbx的使用。 有关详细信息,请参阅 IntelliJ IDEA 文档中的 Java 开发工具包(JDK)

按照以下步骤开始设置 dbx 项目结构:

步骤 1:创建基于 sbt 的 Scala 项目

  1. 在 IntelliJ IDEA 中,根据视图,单击 Projects > New ProjectFile > New > Project

  2. 在“”新建Project对话框中,单击Scala,单击sbt,然后单击Next

  3. 输入项目的项目名称和位置。

  4. 对于 JDK,请选择 OpenJDK 8 JRE 的安装。

  5. 对于 sbt,请选择列出的 sbt 的最高可用版本。

  6. 对于 Scala,最好选择与目标集群的 Scala 版本相匹配的版本。 请参阅 Databricks Runtime 发行说明版本和兼容性中的“系统环境”部分,了解适用于你的目标群集的 Databricks Runtime 版本。

  7. 在“Scala”旁边,选中“源代码”框(如果尚未选中)。

  8. 将包前缀添加到 Package Prefix。 这些步骤使用包前缀 com.example.demo。 如果指定其他包前缀,请在所有这些步骤中替换该包前缀。

  9. 单击“完成”。

步骤 2:将对象添加到包

可以将任何必需的对象添加到包。 此包中包含一个名为 SampleApp 的对象。

  1. Project 工具窗口中(View > 工具 Windows > Project),右键单击 project-name> src > main > scala 文件夹,然后单击 新建 > Scala 类

  2. 选择“对象”并键入对象的名称,然后按 Enter。 例如,键入 SampleApp。 如果在此处输入其他对象名称,请确保在所有这些步骤中替换该名称。

  3. SampleApp.scala 文件的内容替换为以下代码:

    package com.example.demo
    
    object SampleApp {
      def main(args: Array[String]) {
      }
    }
    

步骤 3:生成项目

将任何必需的项目生成设置和依赖项添加到项目。 此步骤假定你要生成已在前面的步骤中设置的项目,并且它只依赖于以下库。

  1. 将项目的 build.sbt 文件内容替换为以下内容:

    ThisBuild / version := "0.1.0-SNAPSHOT"
    
    ThisBuild / scalaVersion := "2.12.14"
    
    val sparkVersion = "3.2.1"
    
    lazy val root = (project in file("."))
      .settings(
        name := "dbx-demo",
        idePackagePrefix := Some("com.example.demo"),
        libraryDependencies += "org.apache.spark" %% "spark-core" % sparkVersion withSources(),
        libraryDependencies += "org.apache.spark" %% "spark-sql" % sparkVersion withSources(),
        libraryDependencies += "org.apache.spark" %% "spark-hive" % sparkVersion withSources()
      )
    

    在前面的文件中,替换:

    • 2.12.14 替换为之前为此项目选择的 Scala 版本。
    • 3.2.1 替换为之前为此项目选择的 Spark 版本。
    • dbx-demo 替换为你的项目的名称。
    • com.example.demo 替换为包前缀的名称。
  2. 在菜单栏上,单击View >工具 Windows > sbt

  3. sbt 工具窗口中,右键单击project的名称,然后单击 重新加载 sbt Project。 等到 sbt 完成从 Internet 工件库(如默认的 Coursier 或 Ivy,具体取决于你的 sbt 版本)下载项目的依赖项。 可以在状态栏中查看下载进度。 如果在此项目中添加或更改任何其他依赖项,则必须对添加或更改的每组依赖项重复此项目重新加载步骤。

  4. 在菜单栏上,单击“IntelliJ IDEA”>“首选项”。

  5. 在“首选项”对话框中,单击“生成、执行、部署”,随后单击“生成工具”和“sbt”>>

  6. 在“JVM”中,对于“JRE”,请选择 OpenJDK 8 JRE 的安装。

  7. 在“sbt 项目”中,选择项目的名称。

  8. 在“sbt shell”中,选择“生成”。

  9. 单击“确定”。

  10. 在菜单栏上,单击生成>生成项目。 生成的结果显示在 sbt shell 工具窗口中(View > Tool Windows > sbt shell)。

步骤 4 - 将代码添加到项目中

将任何所需的代码添加到项目中。 此步骤假定你只想将代码添加到 SampleApp.scala 包中的 example 文件。

在项目的 src>main>scala>SampleApp.scala 文件中,添加 dbx 要在目标群集上成批运行的代码。 对于基本测试,请使用代码示例部分中的示例 Scala 代码。

步骤 5:运行项目

  1. 在菜单栏上,单击“运行” > “编辑配置”

  2. 在“运行/调试配置”对话框中,单击 (“添加新配置”)图标或“新增”或或“添加新运行配置”。

  3. 在下拉菜单中,点击“sbt Task”。

  4. 对于名称,请输入配置的名称,例如运行程序

  5. 对于任务,请输入~run

  6. 选择“使用 sbt shell”。

  7. 单击“确定”。

  8. 在菜单栏上,单击“运行”>“运行‘运行程序’”。 运行结果显示在“sbt shell”工具窗口中。

步骤 6:打包项目为 JAR 文件

可以将任何 JAR 生成设置添加到所需的项目。 此步骤假定你只想生成基于前面步骤中设置的项目的 JAR。

  1. 在菜单栏上,单击File > 项目结构

  2. 在“项目结构”对话框中,单击项目设置> 制品

  3. 单击 +(“添加”)图标。

  4. 在下拉列表中,选择“JAR”>“从具有依赖项的模块”。

  5. 在“从模块创建 JAR”对话框中,对于“模块”,请选择你的项目的名称。

  6. 对于“主类”,请单击文件夹图标。

  7. 在“选择主类”对话框中的“按名称搜索”选项卡上,选择“SampleApp”,然后单击“确定”。

  8. 对于“来自库的 JAR 文件”,选择“复制到输出目录并通过清单链接”。

  9. 单击“确定”以关闭“从模块创建 JAR”对话框。

  10. 单击OK关闭Project结构对话框。

  11. 在菜单栏上,单击“生成”>“生成项目”。

  12. 在显示的上下文菜单中,选择 project-name:jar > 构建。 在 sbt 生成 JAR 时等待。 生成的结果显示在 Build Output 工具窗口中(View >工具 Windows > Build)。

JAR 将生成到项目的 out>artifacts><project-name>_jar 文件夹中。 JAR 的名称为 <project-name>.jar

步骤 7:在 IDE 中显示终端

现在 dbx 项目结构已到位,可以创建 dbx 项目了。

通过单击菜单栏上的 View > 工具Windows >终端显示 IntelliJ IDEA 终端,然后继续创建 dbx 项目

Eclipse

完成以下说明,开始将 Eclipse 和 Java 与 dbx 配合使用。 这些说明创建一个基于 Maven 的最小Java项目,可用于启动 dbx 项目。

在本地开发计算机上,除了满足一般要求以外,还必须安装以下组件:

  • Eclipse 的一个版本。 这些说明使用适用于 Java 开发者的 Eclipse IDE 版本。
  • Java运行时环境(JRE)或Java开发工具包(JDK)11 版本,具体取决于本地计算机的操作系统。 尽管任何版本的 JRE 或 JDK 11 都应有效,但 Databricks 迄今仅验证了 dbx 的使用,以及适用于具有 Eclipse 2022-03 R 的 Java 开发人员的 Eclipse IDE,其中包括 AdoptOpenJDK 11。

按照以下步骤开始设置 dbx 项目结构:

步骤 1:创建基于 Maven 的Java项目

  1. 在 Eclipse 中,单击 File > New > Project

  2. New Project 对话框中,展开 Maven,选择 Maven Project,然后单击 Next

  3. 在“New Maven Project 对话框中,选择”创建简单的project(跳过原型选择),然后单击Next

  4. 对于 Group Id,请输入符合Java包名称规则的组 ID。 这些步骤使用包名称 com.example.demo。 如果输入不同的组 ID,请在以下步骤中替换该组 ID。

  5. 对于“工件 ID”,请输入不带版本号的 JAR 文件的名称。 这些步骤使用 JAR 名称 dbx-demo。 如果为 JAR 文件输入其他名称,请在所有这些步骤中替换该 JAR 名称。

  6. 单击“完成”。

步骤 2:将类添加到包

您可以将任何您想要的类添加到包中。 此包将包含一个名为 SampleApp 的类。

  1. 项目资源管理器视图(窗口 > 显示视图 > 项目资源管理器)中,选择项目名称项目图标,然后单击 文件 > 新建 > 类

  2. New Java Class 对话框中,对于 Package,请输入 com.example.demo

  3. 输入 作为“名称”SampleApp

  4. 对于“修饰符”,选择“公共”。

  5. 将 Superclass 留空

  6. 对于“想要创建哪种方法存根”,选择“public static void Main(String[] args)”。

  7. 单击“完成”。

步骤 3 - 将依赖项添加到项目中

  1. Project Explorer 视图中,双击 project-name> pom.xml

  2. 将以下依赖项添加为 <project> 元素的子元素,然后保存文件:

    <dependencies>
      <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-sql_2.12</artifactId>
        <version>3.2.1</version>
        <scope>provided</scope>
      </dependency>
      <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-core_2.12</artifactId>
        <version>3.2.1</version>
      </dependency>
      <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-hive_2.12</artifactId>
        <version>3.2.1</version>
        <scope>provided</scope>
      </dependency>
    </dependencies>
    

    进行以下替换:

    • 2.12 替换为目标群集的 Scala 版本。
    • 3.2.1 替换为目标群集的 Spark 版本。

    请参阅 Databricks Runtime 发行说明版本和兼容性中的“系统环境”部分,了解适用于你的目标群集的 Databricks Runtime 版本。

步骤 4:编译项目

  1. 在项目的 pom.xml 文件中,将以下 Maven 编译器属性添加为 <project> 元素的子元素,然后保存该文件:

    <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <maven.compiler.source>1.6</maven.compiler.source>
      <maven.compiler.target>1.6</maven.compiler.target>
    </properties>
    
  2. Project Explorer视图中,右键单击project-name项目图标,然后点击以>运行配置

  3. 在“运行配置”对话框中,单击“Maven 生成”。

  4. 单击“新建启动配置”图标。

  5. 输入此启动配置的名称,例如“清理编译”。

  6. 对于“基目录”,请单击“工作区”,选择项目的目录,然后单击“确定”。

  7. 对于“目标”,请输入 clean compile

  8. 单击 “运行” 。 该运行的输出显示在“控制台”视图(“窗口”“显示视图”>“控制台”)中。>

步骤 5 - 将代码添加到项目中

可以将任何你想要的代码添加到你的项目中。 此步骤假定你只想将代码添加到名为 SampleApp.java 的包中的一个名为 com.example.demo 的文件。

在项目的 src/main/java>com.example.demo>SampleApp.java 文件中,添加 dbx 要在目标群集上成批运行的代码。 (如果没有方便的代码,可以在本文末尾列出的 Code 示例中使用 Java 代码

步骤 6:运行项目

  1. Project Explorer视图中,右键单击project-name项目图标,然后点击以>运行配置

  2. 在“运行配置对话框中,展开Java应用程序,然后单击App

  3. 单击 “运行” 。 该运行的输出显示在“控制台”视图中。

步骤 7:将项目构建为 JAR

  1. Project Explorer视图中,右键单击project-name项目图标,然后点击以>运行配置

  2. 在“运行配置”对话框中,单击“Maven 生成”。

  3. 单击“新建启动配置”图标。

  4. 输入此启动配置的名称,例如“清理包”。

  5. 对于“基目录”,请单击“工作区”,选择项目的目录,然后单击“确定”。

  6. 对于“目标”,请输入 clean package

  7. 单击 “运行” 。 该运行的输出显示在“控制台”视图中。

JAR 将生成到 <project-name>>target 文件夹中。 JAR 的名称为 <project-name>-0.0.1-SNAPSHOT.jar

注意

如果 JAR 在target窗口中的 文件夹中未显示, 可以通过右键单击 project-name project 图标来尝试显示它,然后单击 Refresh

步骤 8:在 IDE 中显示终端

现在 dbx 项目结构已到位,可以创建 dbx 项目了。 要开始,请将 Project Explorer 视图设置为显示隐藏文件(以点号(./)开头的文件),这些文件由 dbx 生成,如下所示:

  1. Project资源管理器视图中,单击省略号(View 菜单)筛选器图标,然后单击筛选和自定义

  2. “筛选器和自定义 ”对话框中的 “预设置筛选器 ”选项卡上,清除 .* 资源 框。

  3. 单击“确定”。

接下来,按下面所示显示 Eclipse 终端:

  1. 单击菜单栏上的“窗口”>“显示视图”>“终端”。

  2. 如果未显示终端的命令提示符,请在“终端”视图中单击“打开终端”图标。

  3. 使用 cd 命令可切换到项目的根目录。

  4. 继续创建 dbx 项目

无 IDE(仅终端)

完成以下说明以开始使用终端,并使用 dbxPython。

按照以下步骤使用终端开始设置 dbx 项目结构:

  1. 在终端中创建一个空白文件夹。 以下说明使用名为 dbx-demo 的文件夹(但你可为 dbx 项目的根文件夹指定任意名称)。 创建文件夹后,切换到该文件夹。

    对于 Linux 和 macOS:

    mkdir dbx-demo
    cd dbx-demo
    

    对于Windows:

    md dbx-demo
    cd dbx-demo
    
  2. 通过运行 pipenv 命令, 从 dbx-demo 文件夹的根目录创建 Python 虚拟环境,其中 <version> 是您本地已安装的 Python 目标版本,例如 3.8.14

    pipenv --python <version>
    
  3. 通过运行 pipenv shell 来激活Python虚拟环境。

    pipenv shell
    
  4. 继续创建 dbx 项目

创建 dbx 项目

有了前面部分中介绍的 dbx 项目结构后,现在可以创建以下类型的项目:

为Python创建最小 dbx 项目

以下最小 dbx 项目是开始使用 Python 和 dbx 的最简单、最快的方法。 它演示了在Azure Databricks工作区中现有Azure Databricks 通用群集上运行单个Python代码文件的批处理。

注意

若要创建一个 Python 模板化项目,以演示批量运行代码在通用群集和作业群集上的情况,进行远程代码工件部署以及设置 CI/CD 平台,请跳到 dbx

若要完成此过程,你的工作区中必须有一个现有的通用群集。 (请参阅 View computeCompute 配置参考.)理想情况下(但不需要),Python虚拟环境中Python的版本应与此群集上安装的版本匹配。 若要标识群集上的Python版本,请使用群集的 web 终端运行命令 python --version

python --version
  1. 在终端中,从 dbx 项目的根文件夹结合以下选项运行 dbx configure 命令。 此命令在 .dbx 项目的根文件夹中创建一个隐藏的 dbx 文件夹。 此 .dbx 文件夹包含 lock.jsonproject.json 文件。

    dbx configure --profile DEFAULT --environment default
    

    注意

    project.json 文件定义名为 default 的环境,并在你的 DEFAULT 文件中引用了 .databrickscfg 配置文件。 如果你希望 dbx 使用其他配置文件,请在命令 --profile DEFAULT 中将 --profile 替换为 dbx configure,后面跟上目标配置文件的名称。

    例如,如果 DEV 文件中有一个名为 .databrickscfg 的配置文件,并且你希望 dbx 使用该文件而不是 DEFAULT 配置文件,则 project.json 文件可能如下所示,在这种情况下,你也可以在 --environment default 命令中将 --environment dev 替换为 dbx configure

    {
      "environments": {
        "default": {
          "profile": "DEFAULT",
          "storage_type": "mlflow",
          "properties": {
            "workspace_directory": "/Workspace/Shared/dbx/projects/<current-folder-name>",
            "artifact_location": "dbfs:/dbx/<current-folder-name>"
          }
        },
        "dev": {
          "profile": "DEV",
          "storage_type": "mlflow",
          "properties": {
            "workspace_directory": "/Workspace/Shared/dbx/projects/<some-other-folder-name>",
            "artifact_location": "dbfs:/dbx/<some-other-folder-name>"
          }
        }
      }
    }
    

    如果你希望 dbx 使用 DATABRICKS_HOSTDATABRICKS_TOKEN 环境变量(而不是 .databrickscfg 文件中的配置文件),则可在 --profile 命令中完全忽略 dbx configure 选项。

  2. conf 项目的根文件夹中创建一个名为 dbx 的文件夹。

    对于 Linux 和 macOS:

    mkdir conf
    

    对于Windows:

    md conf
    
  3. deployment.yaml 目录中添加包含以下内容的名为 conf 的文件:

    build:
      no_build: true
    environments:
      default:
        workflows:
          - name: 'dbx-demo-job'
            spark_python_task:
              python_file: 'file://dbx-demo-job.py'
    

    注意

    deployment.yaml 文件包含小写单词 default,即对 DEFAULT 文件中大写 .databrickscfg 配置文件的引用。 如果你希望 dbx 使用其他配置文件,请将 default 替换为目标配置文件的名称。

    例如,如果在 DEV 文件中有一个名为 .databrickscfg 的配置文件,并且你希望 dbx 使用该配置文件而不是 DEFAULT 配置文件,则 deployment.yaml 文件可能如下所示:

    environments:
      default:
        workflows:
          - name: 'dbx-demo-job'
            spark_python_task:
              python_file: 'file://dbx-demo-job.py'
      dev:
        workflows:
          - name: '<some-other-job-name>'
            spark_python_task:
              python_file: 'file://<some-other-filename>.py'
    

    如果你希望 dbx 使用 DATABRICKS_HOSTDATABRICKS_TOKEN 环境变量而不是 .databrickscfg 文件中的配置文件,请将 default 中的 deployment.yaml 保留原样。 dbx 默认使用此引用。

    提示

    要将 Spark 配置键值对添加到作业,请使用 spark_conf 字段,例如:

    environments:
      default:
        workflows:
          - name: 'dbx-demo-job'
            spark_conf:
              spark.speculation: true
              spark.streaming.ui.retainedBatches: 5
              spark.driver.extraJavaOptions: '-verbose:gc -XX:+PrintGCDetails'
            # ...
    

    要向作业添加权限,请使用 access_control_list 字段,例如:

    environments:
      default:
        workflows:
          - name: 'dbx-demo-job'
            access_control_list:
              - user_name: 'someone@example.com'
                permission_level: 'IS_OWNER'
              - group_name: 'some-group'
                permission_level: 'CAN_VIEW'
            # ...
    

    请注意,access_control_list 字段必须详尽,因此应将作业的所有者添加到列表中,以及添加其他用户和组权限。

  4. 在名为 dbx-demo-job.py 的文件中添加要在群集上运行的代码,然后将该文件添加到 dbx 项目的根文件夹。 (如果没有方便的代码,可以在本文末尾列出的 Code 示例中使用Python代码。

    注意

    不必将此文件命名为 dbx-demo-job.py。 如果选择了不同的文件名,请务必更新 python_file 文件中的 conf/deployment.yaml 字段,使文件名匹配。

  5. 使用以下选项运行命令 dbx execute。 在此命令中,请将 <existing-cluster-id> 替换为您工作区中经典计算的 ID。 (若要获取 ID,请参阅 计算资源 URL 和 ID。)

    dbx execute --cluster-id=<existing-cluster-id> dbx-demo-job --no-package
    
  6. 若要查看本地运行结果,请查看终端的输出。 若要查看群集上的运行结果,请转到群集的“驱动程序日志”选项卡中的“标准输出”窗格。 (见计算驱动程序和工作器日志。)

  7. 继续执行后续步骤。

为 Scala 或 Java 创建最小 dbx 项目

以下最小 dbx 项目是开始使用 dbx 和 Scala 或 Java的最简单且最快的方法。 它演示如何将单个 Scala 或 Java JAR 部署到Azure Databricks工作区,然后在Azure Databricks工作区中Azure Databricks jobs 群集上运行该 JAR

注意

Azure Databricks限制如何在群集上运行 Scala 和Java代码:

  • 您不能像使用单个 Python 文件那样,将单个 Scala 或 Java 文件作为作业在群集上运行。 若要运行 Scala 或Java代码,必须先将其构建到 JAR 中。
  • 可以在现有的通用群集上以作业的形式运行 JAR。 但是,不能在同一通用群集上重新安装该 JAR 的任何更新。 在这种情况下,必须改用作业群集。 本部分使用作业群集方法。
  • 必须先将 JAR 部署到Azure Databricks工作区,然后才能在该工作区中的任何用途群集或作业群集上运行该部署的 JAR。
  1. 在终端中,从项目的根文件夹运行带有以下选项的 dbx configure 命令。 此命令在项目的根文件夹中创建一个隐藏的 .dbx 文件夹。 此 .dbx 文件夹包含 lock.jsonproject.json 文件。

    dbx configure --profile DEFAULT --environment default
    

    注意

    project.json 文件定义名为 default 的环境,并在你的 DEFAULT 文件中引用了 .databrickscfg 配置文件。 如果你希望 dbx 使用其他配置文件,请在命令 --profile DEFAULT 中将 --profile 替换为 dbx configure,后面跟上目标配置文件的名称。

    例如,如果 DEV 文件中有一个名为 .databrickscfg 的配置文件,并且你希望 dbx 使用该文件而不是 DEFAULT 配置文件,则 project.json 文件可能如下所示,在这种情况下,你也可以在 --environment default 命令中将 --environment dev 替换为 dbx configure

    {
      "environments": {
        "default": {
          "profile": "DEFAULT",
          "storage_type": "mlflow",
          "properties": {
            "workspace_directory": "/Workspace/Shared/dbx/projects/<current-folder-name>",
            "artifact_location": "dbfs:/dbx/<current-folder-name>"
          }
        },
        "dev": {
          "profile": "DEV",
          "storage_type": "mlflow",
          "properties": {
            "workspace_directory": "/Workspace/Shared/dbx/projects/<some-other-folder-name>",
            "artifact_location": "dbfs:/dbx/<some-other-folder-name>"
          }
        }
      }
    }
    

    如果你希望 dbx 使用 DATABRICKS_HOSTDATABRICKS_TOKEN 环境变量(而不是 .databrickscfg 文件中的配置文件),则可在 --profile 命令中完全忽略 dbx configure 选项。

  2. 在项目的根文件夹中创建一个名为 conf 的文件夹。

    对于 Linux 和 macOS:

    mkdir conf
    

    对于Windows:

    md conf
    
  3. deployment.yaml 目录中添加包含以下极简文件内容的名为 conf 的文件:

    build:
      no_build: true
    environments:
      default:
        workflows:
          - name: 'dbx-demo-job'
            new_cluster:
              spark_version: '10.4.x-scala2.12'
              node_type_id: 'Standard_DS3_v2'
              num_workers: 2
              instance_pool_id: 'my-instance-pool'
            libraries:
              - jar: 'file://out/artifacts/dbx_demo_jar/dbx-demo.jar'
            spark_jar_task:
              main_class_name: 'com.example.demo.SampleApp'
    

    进行以下替换:

    • spark_version 的值替换为适用于目标作业群集的运行时版本
    • 具有目标作业群集的相应node_type_id值。
    • instance_pool_id 的值,具有你的工作区中现有实例的 ID,以便更快地运行作业。 如果没有现有实例池可用,或者不想使用实例池,请完全删除此行。
    • jar 的值,具有项目到 JAR 的路径。 对于支持 Scala 的 IntelliJ IDEA,该路径可能是 file://out/artifacts/dbx_demo_jar/dbx-demo.jar。 配有 Java 的 Eclipse IDE 可能是file://target/dbx-demo-0.0.1-SNAPSHOT.jar
    • main_class_name 的值以及 JAR 中主类的名称,例如 com.example.demo.SampleApp

    注意

    deployment.yaml 文件包含单词 default,它是对 default 文件中 .dbx/project.json 环境的引用,而该环境又是对 DEFAULT 文件中的 .databrickscfg 配置文件的引用。 如果希望 dbx 使用其他配置文件,请将此 default 文件中的 deployment.yaml 替换为 .dbx/project.json 文件中的相应引用,该引用又引用 .databrickscfg 文件中的相应配置文件。

    例如,如果在 DEV 文件中有一个名为 .databrickscfg 的配置文件,并且你希望 dbx 使用该配置文件而不是 DEFAULT 配置文件,则 deployment.yaml 文件可能如下所示:

    environments:
      default:
        workflows:
          - name: 'dbx-demo-job'
            # ...
      dev:
        workflows:
          - name: '<some-other-job-name>'
            # ...
    

    如果你希望 dbx 使用 DATABRICKS_HOSTDATABRICKS_TOKEN 环境变量而不是 .databrickscfg 文件中的配置文件,请将 default 中的 deployment.yaml 保留原样。 默认情况下,dbx 将使用 default 文件中的 profile 环境设置(.dbx/project.json 值除外)。

    提示

    要将 Spark 配置键值对添加到作业,请使用 spark_conf 字段,例如:

    environments:
      default:
        workflows:
          - name: 'dbx-demo-job'
            spark_conf:
              spark.speculation: true
              spark.streaming.ui.retainedBatches: 5
              spark.driver.extraJavaOptions: '-verbose:gc -XX:+PrintGCDetails'
            # ...
    

    要向作业添加权限,请使用 access_control_list 字段,例如:

    environments:
      default:
        workflows:
          - name: 'dbx-demo-job'
            access_control_list:
              - user_name: 'someone@example.com'
                permission_level: 'IS_OWNER'
              - group_name: 'some-group'
                permission_level: 'CAN_VIEW'
            # ...
    

    请注意,access_control_list 字段必须详尽,因此应将作业的所有者添加到列表中,以及添加其他用户和组权限。

  4. 运行 dbx deploy 命令。 dbx 将 JAR 部署到 .dbx/project.json 文件适用于匹配环境的 artifact_location 路径中的位置。 dbx 还将项目的文件作为 MLflow 试验的一部分部署到 .dbx/project.json 文件的适用于匹配环境的 workspace_directory 路径中列出的位置。

    dbx deploy --no-package
    
  5. 运行带有以下选项的 dbx launch 命令。 此命令运行 conf/deployment.yaml 中具有匹配名称的作业。 为了查找要作为作业的一部分运行的已部署 JAR,dbx 引用了 .dbx/project.json 文件的适用于匹配环境的 artifact_location 路径中的位置。 为了确定要运行哪个特定的 JAR,dbx 会引用 .dbx/project.json 文件中匹配环境的 workspace_directory 路径中列出的 MLflow 实验所在位置。

    dbx launch dbx-demo-job
    
  6. 若要查看作业群集上的作业运行结果,请参阅 “查看作业和管道”。

  7. 若要查看作业引用的实验,请参阅使用 MLflow 实验管理训练任务

  8. 继续执行后续步骤。

使用 CI/CD 支持创建用于Python的 dbx 模板化项目

以下 Python 的dbx 模板化项目展示了在 Azure Databricks 通用群集作业群集中批量运行 Python 代码的支持、远程代码工件部署,以及 CI/CD 平台设置支持。 (若要为 Python 创建最小化项目,该项目仅展示如何在现有通用群集上批量运行单个 Python 代码文件,请跳回到 dbx。)

  1. 在终端中,在 dbx 项目的根文件夹中运行 dbx init 命令。

    dbx init
    
  2. 对于“project_name”,请输入项目的名称,或按 Enter 接受默认项目名称。

  3. 对于“version”,请输入项目的起始版本号,或按 Enter 接受默认项目版本。

  4. 对于 cloud,请选择与希望项目使用的Azure Databricks云版本对应的数字,或按 Enter 接受默认值。

  5. 对于“cicd_tool”,请选择与项目要使用的受支持 CI/CD 工具对应的编号,或按 Enter 接受默认值。

  6. 对于“project_slug”,请输入要用于项目中的资源的前缀,或按 Enter 接受默认值。

  7. 对于“workspace_directory”,请输入项目的工作区目录的本地路径,或按 Enter 接受默认值。

  8. 对于 artifact_location,请在 Azure Databricks 工作区中输入项目工件要写入的路径,或按 Enter 接受默认值。

  9. 对于“profile”,请输入项目要使用的 CLI 身份验证配置文件的名称,或按 Enter 接受默认值。

提示

可以通过使用硬编码的模板参数来运行 dbx init,以跳过上述步骤,例如:

dbx init --template="python_basic" \
-p "project_name=cicd-sample-project" \
-p "cloud=Azure" \
-p "cicd_tool=Azure DevOps" \
-p "profile=DEFAULT" \
--no-input

dbx 自动计算参数 project_slugworkspace_directoryartifact_location。 这三个参数是可选的,它们仅对更高级的用例有用。

请参阅 init 文档的 CLI 参考中的 dbx 命令。

另请参阅后续步骤

代码示例

如果你未准备好可以通过 dbx 批量运行的任何代码,可以试着让 dbx 批量运行以下代码。 此代码在工作区中创建一个小型表,查询该表,然后删除该表。

提示

若要将该表保留在工作区中而不删除它,请先注释掉此示例中的最后一行代码,然后再通过 dbx 批量运行它。

Python

# For testing and debugging of local objects, run
# "pip install pyspark=X.Y.Z", where "X.Y.Z"
# matches the version of PySpark
# on your target clusters.
from pyspark.sql import SparkSession

from pyspark.sql.types import *
from datetime import date

spark = SparkSession.builder.appName("dbx-demo").getOrCreate()

# Create a DataFrame consisting of high and low temperatures
# by airport code and date.
schema = StructType([
   StructField('AirportCode', StringType(), False),
   StructField('Date', DateType(), False),
   StructField('TempHighF', IntegerType(), False),
   StructField('TempLowF', IntegerType(), False)
])

data = [
   [ 'BLI', date(2021, 4, 3), 52, 43],
   [ 'BLI', date(2021, 4, 2), 50, 38],
   [ 'BLI', date(2021, 4, 1), 52, 41],
   [ 'PDX', date(2021, 4, 3), 64, 45],
   [ 'PDX', date(2021, 4, 2), 61, 41],
   [ 'PDX', date(2021, 4, 1), 66, 39],
   [ 'SEA', date(2021, 4, 3), 57, 43],
   [ 'SEA', date(2021, 4, 2), 54, 39],
   [ 'SEA', date(2021, 4, 1), 56, 41]
]

temps = spark.createDataFrame(data, schema)

# Create a table on the cluster and then fill
# the table with the DataFrame's contents.
# If the table already exists from a previous run,
# delete it first.
spark.sql('USE default')
spark.sql('DROP TABLE IF EXISTS demo_temps_table')
temps.write.saveAsTable('demo_temps_table')

# Query the table on the cluster, returning rows
# where the airport code is not BLI and the date is later
# than 2021-04-01. Group the results and order by high
# temperature in descending order.
df_temps = spark.sql("SELECT * FROM demo_temps_table " \
   "WHERE AirportCode != 'BLI' AND Date > '2021-04-01' " \
   "GROUP BY AirportCode, Date, TempHighF, TempLowF " \
   "ORDER BY TempHighF DESC")
df_temps.show()

# Results:
#
# +-----------+----------+---------+--------+
# |AirportCode|      Date|TempHighF|TempLowF|
# +-----------+----------+---------+--------+
# |        PDX|2021-04-03|       64|      45|
# |        PDX|2021-04-02|       61|      41|
# |        SEA|2021-04-03|       57|      43|
# |        SEA|2021-04-02|       54|      39|
# +-----------+----------+---------+--------+

# Clean up by deleting the table from the cluster.
spark.sql('DROP TABLE demo_temps_table')

Scala(编程语言)

package com.example.demo

import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.types._
import org.apache.spark.sql.Row
import java.sql.Date

object SampleApp {
  def main(args: Array[String]) {
    val spark = SparkSession.builder().master("local").getOrCreate()

    val schema = StructType(Array(
      StructField("AirportCode", StringType, false),
      StructField("Date", DateType, false),
      StructField("TempHighF", IntegerType, false),
      StructField("TempLowF", IntegerType, false)
    ))

    val data = List(
      Row("BLI", Date.valueOf("2021-04-03"), 52, 43),
      Row("BLI", Date.valueOf("2021-04-02"), 50, 38),
      Row("BLI", Date.valueOf("2021-04-01"), 52, 41),
      Row("PDX", Date.valueOf("2021-04-03"), 64, 45),
      Row("PDX", Date.valueOf("2021-04-02"), 61, 41),
      Row("PDX", Date.valueOf("2021-04-01"), 66, 39),
      Row("SEA", Date.valueOf("2021-04-03"), 57, 43),
      Row("SEA", Date.valueOf("2021-04-02"), 54, 39),
      Row("SEA", Date.valueOf("2021-04-01"), 56, 41)
    )

    val rdd = spark.sparkContext.makeRDD(data)
    val temps = spark.createDataFrame(rdd, schema)

    // Create a table on the Databricks cluster and then fill
    // the table with the DataFrame's contents.
    // If the table already exists from a previous run,
    // delete it first.
    spark.sql("USE default")
    spark.sql("DROP TABLE IF EXISTS demo_temps_table")
    temps.write.saveAsTable("demo_temps_table")

    // Query the table on the Databricks cluster, returning rows
    // where the airport code is not BLI and the date is later
    // than 2021-04-01. Group the results and order by high
    // temperature in descending order.
    val df_temps = spark.sql("SELECT * FROM demo_temps_table " +
      "WHERE AirportCode != 'BLI' AND Date > '2021-04-01' " +
      "GROUP BY AirportCode, Date, TempHighF, TempLowF " +
      "ORDER BY TempHighF DESC")
    df_temps.show()

    // Results:
    //
    // +-----------+----------+---------+--------+
    // |AirportCode|      Date|TempHighF|TempLowF|
    // +-----------+----------+---------+--------+
    // |        PDX|2021-04-03|       64|      45|
    // |        PDX|2021-04-02|       61|      41|
    // |        SEA|2021-04-03|       57|      43|
    // |        SEA|2021-04-02|       54|      39|
    // +-----------+----------+---------+--------+

    // Clean up by deleting the table from the Databricks cluster.
    spark.sql("DROP TABLE demo_temps_table")
  }
}

Java

package com.example.demo;

import java.util.ArrayList;
import java.util.List;
import java.sql.Date;
import org.apache.spark.sql.SparkSession;
import org.apache.spark.sql.types.*;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.RowFactory;
import org.apache.spark.sql.Dataset;

public class SampleApp {
  public static void main(String[] args) {
    SparkSession spark = SparkSession
      .builder()
      .appName("Temps Demo")
      .config("spark.master", "local")
      .getOrCreate();

    // Create a Spark DataFrame consisting of high and low temperatures
    // by airport code and date.
    StructType schema = new StructType(new StructField[] {
      new StructField("AirportCode", DataTypes.StringType, false, Metadata.empty()),
      new StructField("Date", DataTypes.DateType, false, Metadata.empty()),
      new StructField("TempHighF", DataTypes.IntegerType, false, Metadata.empty()),
      new StructField("TempLowF", DataTypes.IntegerType, false, Metadata.empty()),
    });

    List<Row> dataList = new ArrayList<Row>();
    dataList.add(RowFactory.create("BLI", Date.valueOf("2021-04-03"), 52, 43));
    dataList.add(RowFactory.create("BLI", Date.valueOf("2021-04-02"), 50, 38));
    dataList.add(RowFactory.create("BLI", Date.valueOf("2021-04-01"), 52, 41));
    dataList.add(RowFactory.create("PDX", Date.valueOf("2021-04-03"), 64, 45));
    dataList.add(RowFactory.create("PDX", Date.valueOf("2021-04-02"), 61, 41));
    dataList.add(RowFactory.create("PDX", Date.valueOf("2021-04-01"), 66, 39));
    dataList.add(RowFactory.create("SEA", Date.valueOf("2021-04-03"), 57, 43));
    dataList.add(RowFactory.create("SEA", Date.valueOf("2021-04-02"), 54, 39));
    dataList.add(RowFactory.create("SEA", Date.valueOf("2021-04-01"), 56, 41));

    Dataset<Row> temps = spark.createDataFrame(dataList, schema);

    // Create a table on the Databricks cluster and then fill
    // the table with the DataFrame's contents.
    // If the table already exists from a previous run,
    // delete it first.
    spark.sql("USE default");
    spark.sql("DROP TABLE IF EXISTS demo_temps_table");
    temps.write().saveAsTable("demo_temps_table");

    // Query the table on the Databricks cluster, returning rows
    // where the airport code is not BLI and the date is later
    // than 2021-04-01. Group the results and order by high
    // temperature in descending order.
    Dataset<Row> df_temps = spark.sql("SELECT * FROM demo_temps_table " +
      "WHERE AirportCode != 'BLI' AND Date > '2021-04-01' " +
      "GROUP BY AirportCode, Date, TempHighF, TempLowF " +
      "ORDER BY TempHighF DESC");
    df_temps.show();

    // Results:
    //
    // +-----------+----------+---------+--------+
    // |AirportCode|      Date|TempHighF|TempLowF|
    // +-----------+----------+---------+--------+
    // |        PDX|2021-04-03|       64|      45|
    // |        PDX|2021-04-02|       61|      41|
    // |        SEA|2021-04-03|       57|      43|
    // |        SEA|2021-04-02|       54|      39|
    // +-----------+----------+---------+--------+

    // Clean up by deleting the table from the Databricks cluster.
    spark.sql("DROP TABLE demo_temps_table");
  }
}

后续步骤

其他资源