簡體   English   中英

Pyspark 合並多個零件文件時的性能調整

[英]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 小時以上)。 因為我在共享集群上工作,所以我不知道節點數量和核心數量的確切細節,也不知道我們團隊使用的標准配置……但似乎這還不夠。 上面的細節還不是很方便,但我正在嘗試獲取這些細節,但我更關心是否可以從代碼的角度進行任何調整。 我想到的幾個問題:-

  • 因為我正在使用循環來一個一個地讀取每個部分文件夾,所以我認為讀取是串行發生的,而不是並行操作。 是否可以並行讀取不同的零件文件夾。 我試過 reduce 操作,但不能正常工作。
  • 發布 read-df 與空 df 的聯合,我正在緩存 empty_df,以便在下一個聯合操作中不會重新計算 empty_df。 但這似乎對性能沒有幫助。 我不應該緩存空 df 嗎?

非常感謝與此有關的任何幫助。

我認為有幾個因素會影響您的工作表現:

  • 簡單的 Python for循環並沒有在節點之間平均分配工作——你正在失去運行像 Spark 這樣的分布式引擎的好處,因為它只使一個工作人員超載
  • 您的文件夾結構似乎已經很好地分區,因此即使使用不同的模式讀取數據也不應該是一個大問題
  • 只有在您閱讀了所有必需的文件之后,選擇和投射列才最有意義 - 在此之前,您冒着構建大型if-else意大利面條來處理所有可能情況的風險

一個簡單的解決方案:您是否嘗試通過將整個目錄傳遞給 Spark 來讀取所有所需的文件夾?

通常,當您有不同的架構時,理智的解決方案是為具有不同架構的文件組設置一個單獨的 DataFrame,然后使用 function 像unionByName來組合它們。 您可以將allowMissingColumn傳遞給True ,這樣當例如 DataFrame A沒有 DataFrame B的某些列時,聯合后,它將在那里分配 NULL 值,而不是拋出異常。

嘗試任何解決方案,讓我知道哪個最有效 - 總是對對人們有用的方法感興趣:)

暫無
暫無

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

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