簡體   English   中英

如何通過.map在另一個RDD中傳遞一個RDD

[英]How to pass one RDD in another RDD through .map

我有兩個rdd,我想對rdd1的每個項目的RDD2項目進行一些計算。 所以,我在用戶定義的函數中傳遞RDD2,如下所示,但我得到的錯誤就像rdd1 cannot be passed in another rdd 如果我想在兩個rdd上執行操作,我可以知道如何實現這個目的嗎?

例如:

RDD1.map(line =>function(line,RDD2))

錯誤說明,Spark不支持嵌套RDD。 通常你必須通過重新設計算法來繞過它。

如何做到這取決於實際的用例, function中究竟發生了什么以及它的輸出是什么。

有時RDD1.cartesian(RDD2) ,每個元組執行操作然后按鍵減少將起作用。 有時,如果你有(K,V)類型,兩個RDD之間的連接將起作用。

如果RDD2很小,你總是可以在驅動程序中收集它,使它成為一個廣播變量,並在function使用該變量而不是RDD2

@編輯:

例如,假設您的RDD持有字符串, function將計算RDD中給定RDD記錄的RDD2

def function(line: String, rdd: RDD[String]): (String, Int) = {
   (line, rdd.filter(_ == line).count)
} 

這將返回RDD[(String, Int)]

Idea1

您可以嘗試使用RDD的cartesian方法使用笛卡爾積

val cartesianProduct = RDD1.cartesian(RDD2) // creates RDD[(String, String)]
                           .map( (r1,r2) => (r1, function2) ) // creates RDD[(String, Int)]
                           .reduceByKey( (c1,c2) => c1 + c2 ) // final RDD[(String, Int)]

這里function2r1r2 (它們是字符串),如果相等則返回1否則返回0 最終的映射將產生一個RDD ,它將具有元組,其中鍵將是來自r1的記錄,值將是總計數。

問題1:如果你在RDD1有重復的字符串,這將不起作用。 你必須考慮一下。 如果RDD1記錄有一些完美的唯一ID。

問題2:這確實創造了很多對(對於兩個RDD中的1mln記錄,它將創建大約500bln對),會很慢並且很可能導致大量的混亂

Idea2

我不明白關於RDD2的大小您的評論lacs所以這可能或可能無法正常工作:

val rdd2array = sc.broadcast(RDD2.collect())
val result = RDD1.map(line => function(line, rdd2array))

問題:這可能會炸毀你的記憶。 driver上調用collect()rdd2 all記錄加載到驅動程序節點上的內存中。

Idea3

根據用例,還有其他方法可以解決這個問題,例如,相似性搜索的強力算法與您的用例類似(不是意圖)。 對此的替代解決方案之一是Locality Sensitive Hashing

暫無
暫無

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

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