[英]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 和您想要使用isin
過濾的collectedDf("col1")
集合列表,然后使用兩個數據幀之間的連接來過濾匹配的行。
我認為它會比isin
更有效,因為您有 200k 條目要過濾。 spark.sql.autobroadcastjointhreshhold
是您需要設置適當大小的屬性(默認為 10mb)。 AFAIK 您可以根據您的要求使用到 200mb 或 3oomb。
我只會帶着大任務離開,因為我在我的程序中只使用了兩次(但節省了很多時間),而且我負擔得起,但如果其他人非常需要它......好吧,這似乎是路徑。
我發現有大陣列下推的最佳替代方案:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.