簡體   English   中英

如何將 JAR 捆綁到 python package 中並使其可用於 Z77BB59DCD895659748EZDB590?

[英]How can I bundle a JAR inside a python package and make it available to pyspark?

我已經編寫了一些在 Spark DataFrame上運行的 Scala 代碼。 I want my company's data scientists to be able to call it from PySpark (which they primarily use within Jupyter notebooks) hence I have written a thin Python wrapper around it that calls the Scala code (via py4j) which has been compiled into a JAR ( foo.jar)。 我已將 jar 和包裝器 ( foo.py ) 打包到 Python 輪 (foo.whl) 中。

當車輪安裝pip時,它位於/path/to/site-packages/foo並且 JAR 位於/path/to/site-packages/foo/jars/foo.jar

在 foo.py 我有以下代碼將 JAR 安裝到 ${SPARK_HOME}/jars 目錄中

package_dir = os.path.dirname(os.path.realpath(__file__))
jar_file_path = os.path.join(package_dir, f"foo/jars/foo.jar")
tgt = f"{os.environ.get('SPARK_HOME')}/jars/foo.jar"
if os.path.islink(tgt):
    print(f"Removing existing symlink {tgt}")
    os.unlink(tgt)
os.symlink(jar_file_path, tgt)

當我或任何希望使用它的人運行import foo時,JAR 被移動到 spark 期望的正確位置,然后可以從 pyspark 代碼中調用它。 一切都很好。

不幸的是,我們的生產環境受到限制,最終用戶(正確地)沒有足夠的權限來允許他們影響文件系統,因此當上面的代碼嘗試創建符號鏈接時,它會因權限錯誤而失敗。

這可以解決嗎? 我想要:

  • 讓我們的數據科學家非常容易pip install foo並擁有 package 的功能供他們使用
  • 但也可以使 JAR 可用於觸發,而無需將其移動到${SPARK_HOME}

任何人都可以建議修復嗎?


評論者要求的一些額外信息。 我們的 Spark 集群實際上是 GCP DataProc 集群(即 Google 的 hadoop/spark 托管服務)。 數據存儲在 Google 存儲桶(GCS - Google 相當於 S3)中,最終用戶(在 Jupyter 中使用 pyspark)確實可以訪問這些存儲桶。

我相信這就是您正在尋找的。

使用 Python setuptools 安裝后腳本

看起來您正在嘗試做的是有一個安裝腳本,當用戶運行 foo.py 時,該腳本將 jar 文件符號鏈接到 sparks 路徑中。 問題是,如果 jvm 已經啟動,這將不起作用,而且用戶無論如何都沒有權限執行此操作。

您應該做的是在 setup.py 文件中添加一個安裝后掛鈎,以便當用戶運行 pip install 時,它會自動進行符號鏈接。

from setuptools.command.install import install
from setuptools import setup

class PostInstallCommand(install):
    """Post-installation for installation mode."""
    def run(self):
        install.run(self)
        package_dir = os.path.dirname(os.path.realpath(__file__))
        jar_file_path = os.path.join(package_dir, f"foo/jars/foo.jar")
        tgt = f"{os.environ.get('SPARK_HOME')}/jars/foo.jar"
        if os.path.islink(tgt):
        print(f"Removing existing symlink {tgt}")
        os.unlink(tgt)
        os.symlink(jar_file_path, tgt)

然后在 setup.py 中將 cmdclass 參數插入 setup() function:

setup(
    ...

    cmdclass={
        'develop': PostDevelopCommand,
        'install': PostInstallCommand,
    },

    ...
)

如果您有管理員為數據科學家設置 python 環境,這應該可以解決權限問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM