一、mapPartitions
mapPartition可以倒过来理解。先partition,再把每个partition进行map函数
适用场景:
如果再映射的过程中需要频繁创建额外的对象,使用mapPartitions要比map高效的多
比如,将RDD中的所有数据通过JDBC连接写入数据库,如果使用map函数,可能要为每一个元素都创建一个connection,这样开销很大,如果使用mapPartitions,那么只需要针对每一个分区建立一个connection。
案例:把每一个元素平方
Java版本
public class mapPartitionsJava {
public static void main(String[] args) {
SparkConf conf = new SparkConf().setMaster("local").setAppName("mapPartitions");
JavaSparkContext sc = new JavaSparkContext(conf);
JavaRDD<Integer> rdd = sc.parallelize(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
JavaRDD<Integer> mapPartitionsRDD = rdd.mapPartitions(new FlatMapFunction<Iterator<Integer>, Integer>() {
@Override
public Iterator<Integer> call(Iterator<Integer> it) throws Exception {
ArrayList<Integer> results = new ArrayList<>();
while (it.hasNext()) {
int i = it.next();
results.add(i * i);
}
return results.iterator();
}
});
mapPartitionsRDD.foreach(new VoidFunction<Integer>() {
@Override
public void call(Integer integer) throws Exception {
System.out.println(integer);
}
});
}
}
案例:把每一个数字i变成一个map(i,i*i)的形式
Scala版本
object mapPartitionsScala {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local").setAppName("mapPartitions")
val sc = new SparkContext(conf)
//把每一个元素变成map(i,i*i)
val rdd = sc.parallelize(List(1,2,3,4,5,6,7),3)
def mapPartFunc(iter:Iterator[Int]):Iterator[(Int,Int)]={
var res=List[(Int,Int)]()
while (iter.hasNext){
val next = iter.next()
res=res.::(next,next*next)
}
res.iterator
}
val mapPartitionsRDD = rdd.mapPartitions(mapPartFunc)
mapPartitionsRDD.foreach(println)
}
}
Java版本
JavaRDD<Integer> rdd = sc.parallelize(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
JavaRDD<Tuple2