簡體   English   中英

在 Spark 獨立和 YARN 客戶端部署模式下運行時,cythonize 代碼如何工作,而不是在 YARN 集群部署上?

[英]How come cythonize code works when running on Spark standalone and YARN client deployment mode, but not on YARN cluster deployment?

我有一個cythonized庫,我使用這種方法對其進行了 cython 化。 在我所有的 Spark 集群節點上,我都安裝了whl文件,如下所示。

pip install myapi-0.0.1-cp38-cp38-linux_x86_64.whl

當我如下向 Spark 獨立提交作業時,代碼運行良好。

spark-submit \
    --master spark://172.18.0.32:7077 \
    test.py

當我使用客戶端部署模式通過 YARN 提交作業時,代碼也運行良好。

spark-submit \
    --master yarn \
    --deploy-mode client \
    test.py

但是,當我通過 YARN 集群部署模式提交作業時,代碼會中斷。

spark-submit \
    --master yarn \
    --deploy-mode cluster \
    test.py

特別是,我收到此錯誤。

pickle.PicklingError: 無法 pickle <cyfunction Data.compute.. at 0x7f51874d72b0>: myapi 上的屬性查找 lambda。

代碼myapi.utils.Data沒什么特別的,看起來像這樣。

class Data:
    def __init__(self, rdd):
        self.rdd = rdd

    def compute(self):
        return self.rdd.map(change_it).reduce(lambda a, b: a + b)

def change_it(n):
    a = lambda v: v
    b = lambda v: v
    c = lambda v: v
    d = lambda v: v
    e = lambda v: v
    f = lambda v: a(b(c(d(e(v)))))
    
    return f(n)

幾個地方討論了使用 PySpark、 picklecloudpickle和 cythonized 模塊對嵌套函數進行酸洗(web 和 SO)的困難。 但是,答案似乎並不是一個blanket的答案,可以解釋為什么它在一種情況下有效,而在我上面試驗過的其他情況下無效。

任何關於為什么我得到這些觀察結果的進一步解釋將不勝感激。

我的 Spark 環境設置如下。

  • 星火 v3.3.1
  • Hadoop v3.2.1
  • Python v3.8

我對 Spark 不是很熟悉,但我希望“客戶端”模式在相同的 Python 進程中運行,因此不需要序列化任何內容(可以簡單地創建和使用對象)。 “集群”模式大概是為在一堆不同的計算機上運行而設計的,因此需要將傳遞給單獨進程的數據進行 pickle 和 unpickled 處理,以便分發它。

我相信cloudpickledill可以查看常規 Python 函數和 lambda 內部,提取字節碼,然后重構函數。 這對於 Cython 顯然是不可能的。 在當前版本的 Cython 中,函數是按名稱腌制的(因此 lambda 不可腌制,也不可腌制任何內部函數)。

您的選擇是:

  1. 重寫根據可腌制類(使用__call__函數)捕獲變量的任何函數或 lambda; 用 function 或 class scope 中定義的def函數替換其他 lambda。

  2. 試試這個實驗分支,它使大部分 Cython 函數都可以 pickleable。

暫無
暫無

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

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