apache spark - 从groupByKey结果中创建Iterable的RDD

时间:2015-06-16 02:14:37

标签: apache-spark spark-streaming rdd

我正在尝试基于给定的PairRDD创建新的RDD。我有一个PairRDD,键很少,但每个键都有大(约100k)值。我想以某种方式重新分区,使每个Iterable<v>成为RDD [v],以便我可以进一步有效地对这些值应用map,reduce,sortBy等。我感觉flatMapValues是我的朋友,但想与其他sparkens一起检查。这是实时火花应用程序。我已经尝试过collect()并计算app server内存中的所有度量,但试图改进它。 这是我尝试的(伪造)

class ComputeMetrices{

    transient JavaSparkContext sparkContext;

    /**
     * This method compute 3 measures: 2 percentiles of different values and 1 histogram 
     * @param javaPairRdd
     * @return
     */
    public Map<String, MetricsSummary> computeMetrices(JavaPairRDD<String, InputData> javaPairRdd) {

      JavaPairRDD<String, MetricsSummary> rdd = javaPairRdd.groupByKey(10).mapValues(itr => {

      MetricsSummary ms = new MetricsSummary();

      List<Double> list1 
      List<Double> list2

      itr.foreach{ list1.add(itr._2.height); list2.add(itr._2.weight)}
       //Here I want to convert above lists into RDD 
      JavaRDD<V> javaRdd1 = sparContext.parallelize(list1) //null pointer ; probably at sparkContext
      JavaRDD<V> javaRdd2 = sparContext.parallelize(list2)
      JavaPairRDD1 javaPairRdd1 = javaRdd1.sortBy.zipWithIndex()
      JavaPairRDD2 javaPairRdd2 = javaRdd2.sortBy.zipWithIndex()
      //Above two PairRDD will be used further to find Percentile values for range of (0..100)
      //Not writing percentile algo for sake of brevity
      double[] percentile1 = //computed from javaPairRdd1
      double[] percentile2 = //computed from javaPairRdd2
      ms.percentile1(percentile1)
      ms.percentile2(percentile2)
      //compute histogram
      JavaDoubleRDD dRdd = sparkContext.parallelizeDoubles(list1)
      long[] hist = dRdd.histogram(10)
      ms.histo(hist)
      return ms
      })
      return rdd.collectAsMap
    }
}

我想从groupByKey结果中创建出Iterable的RDD,以便我可以进一步使用spark变换。

1 个答案:

答案 0 :(得分:0)

sparContext为null的原因是mapValues中的代码是在worker上执行的 - worker上没有sparContext,它只在驱动程序上可用。

如果我理解您的代码,我可以告诉您,如果您希望mapValues生成排序和索引对,则无需创建。

请记住该代码的结果如下:

RDD(String, V) ->groupByKey-> RDD(String, List(V)) 
->mapValues-> RDD(String, List(Int,V))

key1, List((0,V1), (0,V2)
key1, List((0,V1), (0,V2)

mapValues独立应用于分组列表中的每个V。因此,计数器将始终为0。

如果要使用K将单个RDD中的多个RDD转换出来,List(V)比flatMapValues可以帮助您。还有一个问题 - 流媒体操作对新rdd有多高效 - map和reduce肯定会有效,但sortBy将取决于你窗口的大小。

RDD(K, List(V)) -> flatMapValues(x=>x) -> RDD((K, V1), (K, V2) ... )