【问题标题】:Managing Scala dependencies in Databricks notebooks在 Databricks 笔记本中管理 Scala 依赖项
【发布时间】:2020-03-31 13:16:42
【问题描述】:

我是一个大型 Scala 项目的新开发人员,所有代码都存储为笔记本并在 Databricks 集群中运行...

每个笔记本都定义了类和方法,我们有“主”笔记本,它们的代码行数很少,但在 %run ./myPackage/Foo 等单元格中执行所有需要的 Scala 笔记本(即该项目中的几乎所有笔记本)。然后这些“主要”笔记本有一个小的 Scala 代码单元,如下所示:

import com.bar.foo.Main
Main.main()

此外,每个笔记本都会导入它需要的包,如 Scala 指令import com.bar.foo.MyClass

我觉得这真的很烦人:

  • 如果我移动一个笔记本,我必须更新所有主笔记本/测试笔记本中的所有 %run path/Notebook 命令
  • 我觉得在主笔记本中运行笔记本并在所有其他笔记本中导入包是多余的。

您知道另一个工作流程吗?有没有更简单的方法来处理 Databricks 中的多个 Scala 笔记本?

【问题讨论】:

  • 在我工作的地方,我们通过将笔记本按它们所做的事情分组到另一个笔记本(想象一个包)中来避免这种情况,该笔记本会调用所有其他笔记本,然后在需要时我们称之为“包”笔记本。这样,如果您更改了一个笔记本的位置,您只能在调用它的笔记本上更改它。

标签: scala databricks


【解决方案1】:

我认为当用户和公司认为笔记本可以替代软件工程原则时,就会出现这些问题。为了解决这些问题,软件世界创建并广泛使用了design patterns,这很难(如果不是不可能的话)将它们应用于笔记本电脑。因此,我认为用户不应该将笔记本作为开发最终用户解决方案的工具。笔记本的主要作用曾经是原型设计ML测试,因此根据定义,它们不适合模块化和可扩展性是重要因素的情况。

至于您的情况并假设笔记本的使用是不可避免的,我建议尽量减少笔记本的使用并开始将您的代码组织到 JAR 库中。如果笔记本在它们之间共享大部分代码,那将很有用。

让我们考虑例如笔记本N1N2 都使用笔记本N3N4 的情况。然后,您可以将N3N4 的实现放入一个JAR 中,我们称之为common_lib.jar,然后通过将common_lib.jar 附加到它们运行的​​集群上,使common_lib.jarN1N2 都可用(假设您运行notebook job)。通过遵循这种方法,您可以实现:

  • 更好的模块化,因为您完全分离了笔记本的功能。此外,对于每个作业/笔记本,您可以将确切的依赖项附加到集群,避免由于难以将笔记本应用程序分成模块而发生的冗余依赖项。

  • 更易于维护的代码。最终,每个模块都应该有一个最终笔记本,它可以像在通用 scala 应用程序中那样导入依赖项,从而避免调用多个笔记本所需的复杂层次结构。

  • 更具可扩展性的代码。笔记本提供的界面很差dbutils.widget.text(...)dbutils.widget.get(...) 绝对比你可以用 scala/java 实现的要少得多。

  • 更多可测试的代码。您现在应该知道,使用笔记本很难实施适当的单元或集成测试。通过将主要实现放入 jar 中,您可以像处理任何 scala/java 应用程序一样执行单元测试。

更新

针对您的情况的一种解决方案(无法重构为 JAR 库)是将笔记本组织成模块,其中每个模块都将使用一个 _includes_ 文件来负责模块的所有依赖项。 _includes_ 文件可能看起来像下一个 sn-p:

%run "myproject/lib/notebook_1"
%run "myproject/lib/notebook_3"

...

现在让我们假设笔记本 X1 和 X2 它们共享相同的依赖项 myproject/lib/notebook_1myproject/lib/notebook_3 为了使用提到的依赖项,您只需将 _includes_ 文件放在同一文件夹下并执行:

%run "_includes_"

在 X1 和/或 X2 笔记本的第一个单元格中。通过这种方式,您可以使用一种通用方法来包含项目的所有依赖项,并且可以避免需要重复复制/粘贴所有包含项的情况。

这并没有提供一种自动化的方式来检查和包含项目中依赖项的正确路径,尽管它可能是一项重大改进。顺便说一句,我不知道这种自动浏览文件和动态更改导入的方式。一种方法是编写外部自定义脚本。虽然这个脚本不应该通过你的工作来调用。

注意:您必须确保依赖关系的层次结构定义明确,并且您没有任何循环依赖关系。

【讨论】:

  • 非常感谢,我知道我们的团队需要从笔记本和浏览器内开发切换到使用 IDE 的实际项目。但我不确定你是否在回答我的问题。我问“如何在笔记本中管理 Scala 依赖项”,而你告诉我“你不应该这样做”。
  • 这是真的,那是因为我想澄清我对问题和理想解决方案的看法。尽管在我的回答中我也包含了一项重大改进,但我指的是 JAR 库的使用。我将尝试再添加一个示例,尝试直接解决您的问题
  • 感谢您的留言和更新!我们会努力改进我们的工作流程
  • 好的,如果您遇到任何挑战,请告诉我
猜你喜欢
  • 2022-01-20
  • 2019-04-18
  • 1970-01-01
  • 2020-04-09
  • 1970-01-01
  • 1970-01-01
  • 2011-09-04
  • 1970-01-01
  • 2013-01-24
相关资源
最近更新 更多