如何从迭代器创建Spark RDD?

时间:2015-06-26 12:12:00

标签: apache-spark spark-streaming

为了说清楚,我不是从像

这样的数组/列表中寻找RDD
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7); // sample
JavaRDD<Integer> rdd = new JavaSparkContext().parallelize(list);

如何在没有在内存中完全缓冲的情况下从java迭代器创建一个spark RDD?

Iterator<Integer> iterator = Arrays.asList(1, 2, 3, 4).iterator(); //sample iterator for illustration
JavaRDD<Integer> rdd = new JavaSparkContext().what("?", iterator); //the Question

附加问题:

是否要求源可重新读取(或能够多次读取)以提供RDD的弹性?换句话说,由于迭代器基本上只读一次,甚至可以从迭代器创建弹性分布式数据集(RDD)吗?

2 个答案:

答案 0 :(得分:9)

正如其他人所说,你可以用火花流做一些事情,但至于纯粹的火花,你不能,原因是你要求的东西违背了火花的模型。让我解释。 为了分配和并行化工作,spark必须将它分成块。从HDFS读取时,由HDFS对Spark进行'分块',因为HDFS文件是按块组织的。 Spark通常会为每个块生成一个任务。 现在,迭代器只提供对数据的顺序访问,因此spark不可能在块中组织它而不在内存中读取它

有可能构建一个具有单个可迭代分区的RDD,但即便如此,也不可能说Iterable的实现是否可以发送给工作者。使用sc.parallelize()时,spark会创建实现serializable的分区,这样每个分区都可以发送给不同的工作者。可迭代可以通过网络连接或本地FS中的文件,因此除非它们被缓冲在内存中,否则它们不能发送给工作者。

答案 1 :(得分:0)

超级老问题,但我只会在序列化后在 flatMap 中创建迭代器。

var ranges = Arrays.asList(Pair.of(1,7), Pair.of(0,5));
JavaRDD<Integer> data = sparkContext.parallelize(ranges).flatMap(pair -> Flux.range(pair.left(), pair.right()).toStream().iterator());