Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.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
从apache spark RDD操作(Java)向hashmap添加数据_Java_Apache Spark_Mapreduce_Rdd - Fatal编程技术网

从apache spark RDD操作(Java)向hashmap添加数据

从apache spark RDD操作(Java)向hashmap添加数据,java,apache-spark,mapreduce,rdd,Java,Apache Spark,Mapreduce,Rdd,我使用映射步骤创建了一个JavaRDD对象,其中包含一些我需要的对象。基于这些对象,我想创建一个包含一些统计信息的全局hashmap,但我不知道应该使用哪个RDD操作。起初我认为reduce是解决方案,但后来我发现必须返回相同类型的对象。我对减少项目不感兴趣,而是收集所有机器的所有统计数据(它们可以单独计算,然后相加) 例如: 我有一个RDD对象,其中包含一个整数数组,我想通过将它们放入哈希表来计算每个整数在数组中出现的次数。每台机器都应该计算它自己的哈希表,然后将它们全部放在驱动程序中的一个位

我使用映射步骤创建了一个JavaRDD对象,其中包含一些我需要的对象。基于这些对象,我想创建一个包含一些统计信息的全局hashmap,但我不知道应该使用哪个RDD操作。起初我认为reduce是解决方案,但后来我发现必须返回相同类型的对象。我对减少项目不感兴趣,而是收集所有机器的所有统计数据(它们可以单独计算,然后相加)

例如:
我有一个RDD对象,其中包含一个整数数组,我想通过将它们放入哈希表来计算每个整数在数组中出现的次数。每台机器都应该计算它自己的哈希表,然后将它们全部放在驱动程序中的一个位置。

通常,当你想得到一个映射时,你会需要将RDD中的记录转换为键值对,并使用
reduceByKey

您的特定示例听起来与著名的wordcount示例(参见第一个示例)完全相同,只是您希望从对象内的数组中计算整数,而不是从句子(字符串)中计算单词。在Scala中,这将转换为:

import org.apache.spark.rdd.RDD
import scala.collection.Map

class Example {

  case class MyObj(ints: Array[Int], otherStuff: String)

  def countInts(input: RDD[MyObj]): Map[Int, Int] = {
    input
      .flatMap(_.ints)    // flatMap maps each record into several records - in this case, each int becomes a record 
      .map(i => (i, 1))   // turn into key-value map, with preliminary value 1 for each key
      .reduceByKey(_ + _) // aggregate values by key
      .collectAsMap()     // collects data into a Map
  }
}
通常,您应该让Spark以分布式方式执行尽可能多的操作,并尽可能延迟收集到内存中-如果在减少之前收集值,通常会耗尽内存,除非您的数据集足够小(在这种情况下,您实际上不需要Spark)

编辑:以下是Java中的相同代码(更长,但相同…):

静态类MyObj实现可序列化{
整数[]整数;
串其他东西;
}
映射计数(JavaRDD输入){
返回输入
.flatMap(新的flatMap函数(){
@凌驾
公共Iterable调用(MyObj MyObj)引发异常{
返回array.asList(myObj.ints);
}
})//flatMap将每个记录映射到多个记录中-在本例中,每个int成为一个记录
.mapToPair(新的PairFunction(){
@凌驾
公共Tuple2调用(整数)引发异常{
返回新的Tuple2(整数,1);
}
})//变成键值图,初始值为1
.reduceByKey(新功能2(){
@凌驾
公共整数调用(整数v1、整数v2)引发异常{
返回v1+v2;
}
})//按键聚合值
.collectAsMap();//将数据收集到映射中
}

我最终使用了聚合操作。这正是我想要的。我将提供另一个答案。
    static class MyObj implements Serializable {
        Integer[] ints;
        String otherStuff;
    }

    Map<Integer, Integer> countInts(JavaRDD<MyObj> input) {
        return input
                .flatMap(new FlatMapFunction<MyObj, Integer>() {
                    @Override
                    public Iterable<Integer> call(MyObj myObj) throws Exception {
                        return Arrays.asList(myObj.ints);
                    }
                })    // flatMap maps each record into several records - in this case, each int becomes a record
                .mapToPair(new PairFunction<Integer, Integer, Integer>() {
                    @Override
                    public Tuple2<Integer, Integer> call(Integer integer) throws Exception {
                        return new Tuple2<>(integer, 1);
                    }
                })   // turn into key-value map, with preliminary value 1
                .reduceByKey(new Function2<Integer, Integer, Integer>() {
                    @Override
                    public Integer call(Integer v1, Integer v2) throws Exception {
                        return v1 + v2;
                    }
                }) // aggregate values by key
                .collectAsMap();     // collects data into a Map
    }