簡體   English   中英

Scala Spark isin 廣播列表

[英]Scala Spark isin broadcast list

我正在嘗試盡可能優化地執行 isin 過濾器。 有沒有辦法使用 Scala API 廣播 collList?

編輯:我不是在尋找替代方案,我知道他們,但我需要 isin 所以我的 RelationProviders 會下推這些值。

  val collList = collectedDf.map(_.getAs[String]("col1")).sortWith(_ < _)
  //collList.size == 200.000
  val retTable = df.filter(col("col1").isin(collList: _*))

我傳遞給“isin”方法的列表最多有 200.000 個唯一元素。

我知道這看起來不是最好的選擇,並且 join 聽起來更好,但是我需要將這些元素推入過濾器中,這在閱讀時會產生巨大的影響(我的存儲是 Kudu,但它也適用於 HDFS+Parquet,base數據太大,查詢只能處理大約 1% 的數據) ,我已經測量了所有內容,它為我節省了大約 30 分鍾的執行時間:)。 另外,如果 isin 大於 200.000,我的方法已經很小心了。

我的問題是,我收到一些 Spark“任務太大”(每個任務約 8mb)警告,一切正常,所以沒什么大不了的,但我希望刪除它們並進行優化。

我試過了,它什么也沒做,因為我仍然收到警告(因為廣播的 var 在 Scala 中得到解決並傳遞給我猜的 vargargs):

  val collList = collectedDf.map(_.getAs[String]("col1")).sortWith(_ < _)
  val retTable = df.filter(col("col1").isin(sc.broadcast(collList).value: _*))

而這個不編譯:

  val collList = collectedDf.map(_.getAs[String]("col1")).sortWith(_ < _)
  val retTable = df.filter(col("col1").isin(sc.broadcast(collList: _*).value))

而這個不起作用(任務太大仍然出現)

  val broadcastedList=df.sparkSession.sparkContext.broadcast(collList.map(lit(_).expr))
  val filterBroadcasted=In(col("col1").expr, collList.value)
  val retTable = df.filter(new Column(filterBroadcasted))

關於如何廣播這個變量的任何想法? (允許黑客攻擊)。 允許過濾器下推的 isin 的任何替代方法也是有效的我見過有人在 PySpark 上這樣做,但 API 不一樣。

PS:不可能對存儲進行更改,我知道分區(已經分區,但不是按該字段)等可能會有所幫助,但是用戶輸入是完全隨機的,並且數據被訪問並更改了我的許多客戶端。

在這種情況下,我會選擇 dataframe 廣播 hash 加入而不是廣播變量。

准備一個 dataframe 和您想要使用isin過濾的collectedDf("col1")集合列表,然后使用兩個數據幀之間的連接來過濾匹配的行。

在此處輸入圖像描述

我認為它會比isin更有效,因為您有 200k 條目要過濾。 spark.sql.autobroadcastjointhreshhold是您需要設置適當大小的屬性(默認為 10mb)。 AFAIK 您可以根據您的要求使用到 200mb 或 3oomb。

看到這個 BHJ 解釋它是如何工作的

進一步閱讀Spark 有效地過濾來自小型 dataframe 中的大型 dataframe 的條目

我只會帶着大任務離開,因為我在我的程序中只使用了兩次(但節省了很多時間),而且我負擔得起,但如果其他人非常需要它......好吧,這似乎是路徑。

我發現有大陣列下推的最佳替代方案:

  1. 更改您的關系提供程序,以便在按下過濾器時廣播大列表,這可能會留下一些廣播垃圾,但是...,只要您的應用程序沒有流式傳輸,這應該不是問題,或者您可以保存在全局列表中並在一段時間后清理它們
  2. 在 Spark 中添加一個過濾器(我在https://issues.apache.org/jira/browse/SPARK-31417中寫了一些東西),它允許廣播下推到您的關系提供者 您必須添加您的自定義謂詞,然后實現您的自定義“下推”(您可以通過添加新規則來做到這一點),然后重寫您的 RDD/Relation 提供程序,以便它可以利用變量被廣播的事實。
  3. 閱讀后使用 coalesce(X) 減少任務數量,有時可以工作,取決於 RelationProvider/RDD 的實現方式

暫無
暫無

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

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