[英]Pyspark Performance Tuning while merging multiple part files
我是 spark 的新手,我有一個要求,我需要從不同的部分文件夾中讀取,然后將它們合並在一起,以根據傳遞的模式創建一個 df。 是這樣的
/feed=abc -> contains multiple part folders based on date like below
/feed=abc/date=20221220
/feed=abc/date=20221221
.....
/feed=abc/date=20221231
每個零件文件夾可以有多個零件文件。 所有文件都是鑲木地板格式,但跨兩個不同部分文件夾的架構可能在列數或數據類型方面有所不同。 所以我的方法是
1 - 根據傳遞的模式創建一個空的 final_df 2 - 使用以下代碼遍歷零件文件夾列表
hadoop = sc._jvm.org.apache.hadoop
fs = hadoop.fs.FileSystem
conf = hadoop.conf.Configuration()
path = hadoop.fs.Path(inp_fl_loc)
for f in fs.get(conf).listStatus(path):
path2 = str(hadoop.fs.Path(str(f.getPath())))
if(f.isDirectory()):
path2= path2 + "/"
print("the inp_path is ",str(path2))
#splitting the individual name to get the corresponding partition col name and value
temp_path = path2.split("/")[-2]
part_col,part_val = temp_path.split("=")[0],temp_path.split("=")[1]
elif('_' in path2.split("/")[-1]):
continue
#reading the file
df =
spark.read.format(inp_fl_frmt).option("mergeSchema","true").load(str(path2))
#other operation follows :-
3 - 讀取特定零件文件夾后,將 read_df 的模式與 final_df 的模式進行比較,僅選擇 req cols,如果需要,根據 final_df 模式對 read_df 的 req col 進行類型轉換。 請注意,在此過程中,我可能還必須在結構類型變量中鍵入一個子列。 為此,我實際上將結構變量擴展到新的列中,對它們進行類型轉換,然后再次將它們轉換回原始結構。 4 - 將類型轉換的 read_df 與 final_df 合並。 5 - 對所有零件文件夾重復步驟 3-4,最終得到最終的 final_df
事情是在存在大數據的情況下(在我的一個提要中,我正在閱讀 340 個部分文件夾,總共約 13000 個文件,總共接近 7GB 左右)作業運行了很長時間(在上述情況下為 7 小時以上)。 因為我在共享集群上工作,所以我不知道節點數量和核心數量的確切細節,也不知道我們團隊使用的標准配置……但似乎這還不夠。 上面的細節還不是很方便,但我正在嘗試獲取這些細節,但我更關心是否可以從代碼的角度進行任何調整。 我想到的幾個問題:-
非常感謝與此有關的任何幫助。
我認為有幾個因素會影響您的工作表現:
for
循環並沒有在節點之間平均分配工作——你正在失去運行像 Spark 這樣的分布式引擎的好處,因為它只使一個工作人員超載if-else
意大利面條來處理所有可能情況的風險一個簡單的解決方案:您是否嘗試通過將整個目錄傳遞給 Spark 來讀取所有所需的文件夾?
通常,當您有不同的架構時,理智的解決方案是為具有不同架構的文件組設置一個單獨的 DataFrame,然后使用 function 像unionByName
來組合它們。 您可以將allowMissingColumn
傳遞給True
,這樣當例如 DataFrame A
沒有 DataFrame B
的某些列時,聯合后,它將在那里分配 NULL 值,而不是拋出異常。
嘗試任何解決方案,讓我知道哪個最有效 - 總是對對人們有用的方法感興趣:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.