Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 调用rdd.join(rdd)时发生了什么_Java_Apache Spark_Join_Apache Spark Sql_Spark Dataframe - Fatal编程技术网

Java 调用rdd.join(rdd)时发生了什么

Java 调用rdd.join(rdd)时发生了什么,java,apache-spark,join,apache-spark-sql,spark-dataframe,Java,Apache Spark,Join,Apache Spark Sql,Spark Dataframe,我正在开发一个应用程序,其中我需要使用RDD中的相同键对每两行执行计算,以下是RDD结构: List<Tuple2<String, Tuple2<Integer, Integer>>> dat2 = new ArrayList<>(); dat2.add(new Tuple2<String, Tuple2<Integer, Integer>>("Alice", new Tuple2<Integer, Integer&g

我正在开发一个应用程序,其中我需要使用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);
List dat2=new ArrayList();
dat2.add(新的Tuple2(“Alice”,新的Tuple2(1,1)));
dat2.add(新的Tuple2(“Alice”,新的Tuple2(2,5)));
dat2.add(新Tuple2(“Alice”,新Tuple2(3,78));
dat2.add(新的Tuple2(“Bob”,新的Tuple2(1,6)));
dat2.add(新的Tuple2(“Bob”,新的Tuple2(2,11));
javarddy2=sc.parallelize(dat2);
现在,每个人的数据都可以像这样查看:(时间戳,值)。我希望知道每行+-1时间戳中发生的值的数量。(我知道这看起来像滑动窗口,但我需要事件级粒度

y2.join(y2);
resultOfJoin.filter(t->t.\u 2().\u 1().\u 1()-t.\u 2().\u 2().\u 1()=-1)
在本例中,我寻求的最佳解决方案是将RDD本身连接起来,为每个人创建
k^2
行,其中k是与此人关联的行数

现在,我知道这是一场彻底的灾难。我知道这会导致洗牌(洗牌是坏的m'key),但我没有更好的了

我有3个问题:

  • 由于我在连接之后立即进行过滤,它会影响连接造成的压力吗(换句话说,会有任何优化)
  • 网络上传递的行数是多少?(我知道,在最坏的情况下,结果RDD将有n^2行)在网络上发送的行是#workersn(只发送一份副本并在worker上复制)还是#workersn^2(在结果worker上每两行组合发送一行)
  • 如果我愿意使用
    Dataset
    ,我可以加入filter。我知道数据集对计算图有额外的优化。如果我转换到数据集,我应该期望有多大的改进(如果有的话)
  • 由于我在连接之后立即进行过滤,它会影响连接造成的压力吗(换句话说,会有任何优化)

    不,不会有优化

    网络上传递的行数是多少

    O(N)(特别是每个记录将被洗牌两次,每个父项一次)您通过键加入,所以每个项都会进入一个分区,并且只有一个分区

    如果我愿意使用Dataset,我可以使用filter。我知道数据集对计算图有额外的优化。如果我转换到数据集,我应该期望有多大的改进(如果有的话)

    洗牌过程得到了更好的优化,但除此之外,您不能期望任何特定于案例的优化

    希望知道每行+-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))
    

    首先,谢谢你的回答。我接受了你的回答,但有一点需要注意(我的OP中没有特别提到,这就是我接受的原因)。Window、lag和lead允许您查看有序列表中的下一个元素,这意味着此计算对于以下情况是错误的:1。并非所有时间戳都有数据2。窗口内可能存在多行(例如,希望在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))