[英]What is happening when I call rdd.join(rdd)
我正在開發一個應用程序,我需要對 RDD 中具有相同鍵的每一對行執行計算,這里是 RDD 結構:
List<Tuple2<String, Tuple2<Integer, Integer>>> dat2 = new ArrayList<>();
dat2.add(new Tuple2<String, Tuple2<Integer, Integer>>("Alice", new Tuple2<Integer, Integer>(1, 1)));
dat2.add(new Tuple2<String, Tuple2<Integer, Integer>>("Alice", new Tuple2<Integer, Integer>(2, 5)));
dat2.add(new Tuple2<String, Tuple2<Integer, Integer>>("Alice", new Tuple2<Integer, Integer>(3, 78)));
dat2.add(new Tuple2<String, Tuple2<Integer, Integer>>("Bob", new Tuple2<Integer, Integer>(1, 6)));
dat2.add(new Tuple2<String, Tuple2<Integer, Integer>>("Bob", new Tuple2<Integer, Integer>(2, 11)));
JavaRDD<Tuple2<String, Tuple2<Integer, Integer>>> y2 = sc.parallelize(dat2);
現在,每個人的數據都可以這樣查看:(時間戳,值)。 我想知道每行 +-1 時間戳中發生的值的數量。 (我知道這看起來像滑動窗口,但我想要事件級粒度)
y2.join(y2);
resultOfJoin.filter(t -> t._2()._1()._1() - t._2()._2()._1() <= 1 && t._2()._1()._1() - t._2()._2()._1() >= -1)
在這種情況下,我找到的最佳解決方案是將 RDD 與其自身連接起來,為每個人創建k^2
行,其中 k 是與此人關聯的行數。
現在,我知道這是一場徹頭徹尾的災難。 我知道這會導致洗牌(並且洗牌不好 m'key),但我不能帶來更好的東西。
我有3個問題:
Dataset
我可以加入過濾器。 我知道數據集對計算圖有額外的優化。 如果我過渡到數據集,我應該期待多少改進(如果有)?由於我是在join后立即過濾,是否會影響join造成的壓力(換句話說,會不會有任何優化)?
不,不會有優化。
網絡上傳遞的行數是多少?
O(N) (特別是每條記錄將被洗牌兩次,每個父級一次)您通過鍵加入,因此每個項目都進入一個,並且只有一個分區。
如果我願意使用 Dataset,我可以加入過濾器。 我知道數據集對計算圖有額外的優化。 如果我過渡到數據集,我應該期待多少改進(如果有)?
Shuffle 過程得到了更好的優化,但除此之外,您不能期望任何特定於案例的優化。
希望知道每行 +-1 時間戳中發生的值的數量。
嘗試窗口函數:
import org.apache.spark.sql.functions._
import org.apache.spark.sql.expressions._
val w = Window.partitionBy("id").ordetBy("timestamp")
rdd.toDF("id", "data")
.select($"id", $"data._1" as "timestamp", $"data._2" as "value"))
.withColumn("lead", lead($"value", 1).over(w))
.withColumn("lag", lag($"value", 1).over(w))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.