[英]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、 pickle
、 cloudpickle
和 cythonized 模塊對嵌套函數進行酸洗(web 和 SO)的困難。 但是,答案似乎並不是一個blanket
的答案,可以解釋為什么它在一種情況下有效,而在我上面試驗過的其他情況下無效。
任何關於為什么我得到這些觀察結果的進一步解釋將不勝感激。
我的 Spark 環境設置如下。
我對 Spark 不是很熟悉,但我希望“客戶端”模式在相同的 Python 進程中運行,因此不需要序列化任何內容(可以簡單地創建和使用對象)。 “集群”模式大概是為在一堆不同的計算機上運行而設計的,因此需要將傳遞給單獨進程的數據進行 pickle 和 unpickled 處理,以便分發它。
我相信cloudpickle
和dill
可以查看常規 Python 函數和 lambda 內部,提取字節碼,然后重構函數。 這對於 Cython 顯然是不可能的。 在當前版本的 Cython 中,函數是按名稱腌制的(因此 lambda 不可腌制,也不可腌制任何內部函數)。
您的選擇是:
重寫根據可腌制類(使用__call__
函數)捕獲變量的任何函數或 lambda; 用 function 或 class scope 中定義的def
函數替換其他 lambda。
試試這個實驗分支,它使大部分 Cython 函數都可以 pickleable。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.