我正在开发一些 Python 代码,这些代码将用作 Databricks 上各种“基于轮子的工作流程”的入口点。鉴于它正在开发中,在我更改代码来测试它之后,我需要构建一个轮子并部署在 Databricks 集群上来运行它(我使用了一些仅在 Databricks 运行时中可用的功能,因此无法在本地运行)。 这就是我所做的:
REMOTE_ROOT='dbfs:/user/[email protected]/wheels'
cd /home/kash/workspaces/project
rm -rf dist
poetry build
whl_file=$(ls -1tr dist/project-*-py3-none-any.whl | tail -1 | xargs basename)
echo 'copying..' && databricks fs cp --overwrite dist/$whl_file $REMOTE_ROOT
echo 'installing..' && databricks libraries install --cluster-id 111-222-abcd \
--whl $REMOTE_ROOT/$whl_file
# ---- I WANT TO AVOID THIS as it takes time ----
echo 'restarting' && databricks clusters restart --cluster-id 111-222-abcd
# Run the job that uses some modules from the wheel we deployed
echo 'running job..' && dbk jobs run-now --job-id 1234567
问题是每次我进行一行更改时,我都需要重新启动集群,这需要 3-4 分钟。除非我重新启动集群
databricks libraries install
,否则不会重新安装轮子。
我尝试更新轮子的版本号,但随后它显示集群在 GUI 上安装了同一轮子的两个版本(计算 -> 选择集群 -> 库选项卡),但在集群本身上实际上未安装较新的版本(使用ls -l .../site-packages/
验证)。
当然,您可以在 Github 上查看他们的源代码,并尝试在您的代码中模仿相同的内容,但是当 databricks-dbx(他们的执行命令)已经为您完成此操作时,这工作量太大了。
在那里你可以继续更改你的Python代码并运行
dbx execute -task=<the task that you define as a config while still developing in local IDE> --cluster-name=<your all purpose cluster name>
这将负责为它创建一个whl并将其部署到集群并启动作业供您测试;同时仍在本地 IDE 中。
因此,您基本上可以在开发中不断更改您的whl,并继续在同一个正在运行的集群上进行测试(如果不运行,它将启动它),而无需重新启动,因为它在单独的上下文中执行此操作 - >请参阅下面的文档中的屏幕截图.
dbx 的主页是
这里 编辑-基于OP关于提供链接上下文的评论(在星号之间的部分下)
这里,我有一个正在开发的whl,我称之为使用dbx中的deployment.yml文件中的whl任务然后我在我的即席交互式集群上使用 dbx execute 对其进行测试。正如您在第一个屏幕截图中看到的,我的集群已终止,因此 dbx 执行,自动启动它,上传 whl 并启动作业
然后我对 python 包进行更多更改,然后再次使用 dbxexecute 测试 whl。正如你在下面看到的,使用了相同的集群(这次集群正在运行,所以它只是使用它,而不需要重新启动),上传相同版本的whl(OP在他最初的能够工作的问题中有这个)开发中具有相同的whl,无需更新版本或重新启动集群)
OP 在他最初的问题中担心能够使用相同版本的 whl,而无需每次重新启动已经运行的集群,就像 2 个屏幕截图所示,dbx 地址。
关于工具集,虽然我尝试过使用 dbx 的默认工具集,但至少从 dbx 的文档来看,支持诗歌(评论中提到了诗歌)->
诗歌支持TL;博士;
库可以安装在
module-runner.py
module-runner.py
module-runner.py
main()
方法。
workspace
中,轮文件位于
dbfs
中。不是最好的选择。
要运行的模块:import some_other_module, sys
def main(*args):
print(args)
module-runner.py
/Users/kash/
):
import argparse, importlib, logging, os, pip, sys, traceback
from datetime import datetime
def main(argv=None):
logging.getLogger('py4j').setLevel(logging.ERROR)
parser = argparse.ArgumentParser(description='Module runner')
parser.add_argument('-m', '--module', help='an importable module, present in installed libraries or in specified --wheel-file.', required=True)
parser.add_argument('-w', '--wheel-file', help='path (or glob pattern) to wheel file to install', required=False)
args, parameters = parser.parse_known_args(argv)
# If --wheel-file is specified then we install wheel at Notebook scope.
# If --wheel-file is NOT specified then we assume it's a cluster library and importable.
if args.wheel_file:
lstat = os.lstat(args.wheel_file)
print(f'lstat(args.wheel_file): {lstat}, mtime: {datetime.fromtimestamp(lstat.st_mtime).isoformat()}')
pip.main(['install', args.wheel_file])
try:
importlib.import_module(args.module).main(*parameters)
# main could be defined as:
# def main() OR def main(*kwargs) OR def main(arg1: <type1>, arg2: <type2>, ...)
except Exception as ex:
print(f'Execution of {args.module}.main() failed with exception. e: {ex}, parameters: {parameters}')
traceback.print_exception(type(ex), ex, ex.__traceback__)
raise ex
if __name__ == '__main__':
main(sys.argv[1:])
com.kash.module1
并将轮子文件上传到
/dbfs/Users/kash/my-module1-wheel.whl
。
["-m", "com.kash.module1", "-w", "/dbfs/Users/kash/my-module1-wheel.whl"]
。
my-module1-wheel.whl
及其所有依赖项