mappartition的妙用
下面的例子都是1-20这20个数字,经过map或者MapPartition然后返回a*3
map的使用
val a = sc.parallelize(1 to 20, 2)
def mapTerFunc(a : Int) : Int = {
a*3
}
val mapResult = a.map(mapTerFunc)
println(mapResult.collect().mkString(","))
结果
3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60
mappartition低效用法
val a = sc.parallelize(1 to 20, 2)
def terFunc(iter: Iterator[Int]) : Iterator[Int] = {
var res = List[Int]()
while (iter.hasNext)
{
val cur = iter.next;
res.::= (cur*3) ;
}
res.iterator
}
val result = a.mapPartitions(terFunc)
println(result.collect().mkString(","))
结果
30,27,24,21,18,15,12,9,6,3,60,57,54,51,48,45,42,39,36,33
mappartition的高效用法
注意,3中的例子,会在mappartition执行期间,在内存中定义一个数组并且将缓存所有的数据。假如数据集比较大,内存不足,会导致内存溢出,任务失败。 对于这样的案例,Spark的RDD不支持像mapreduce那些有上下文的写方法。下面有个方法是无需缓存数据的,那就是自定义一个迭代器类。
class CustomIterator(iter: Iterator[Int]) extends Iterator[Int] {
def hasNext : Boolean = {
iter.hasNext
}
def next : Int= {
val cur = iter.next
cur*3
}
}
val result = a.mapPartitions(v => new CustomIterator(v))
println(result.collect().mkString(","))
结果:
3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60