package com.bjsxt.scala.spark.operator
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import scala.collection.mutable.ListBuffer
/**
* repartition这个算子能够改变RDD的分区数据,就能提高并行度
*/
object RepartitionOperator {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("RepartitionOperator")
.setMaster("local[1]")
val sc = new SparkContext(conf)
val rdd = sc.textFile("cs", 3)
println("rdd.partitions.size:" + rdd.getNumPartitions)
/**
* mapPartitions:遍历算子,遍历的单位是一个partition,也就是在遍历之前他会将一个partition的数据加载到内存中
* map:这个遍历算子,能够遍历RDD中每一个元素,遍历的单位是每条记录
* 使用map、mapPartition算子遍历一个RDD,谁的效率高?
* mapPartitions
* mapPartitionsWithIndex:在遍历每一个partition的时候会将这个partition的Id拿到,主要用于测试
* mapPartitions算子占用内存多,如果一个partition的计算结果非常非常大,那么可能会造成OOM
* 如果使用mapPartitions这个算子发生了OOM,怎么去解决?
* repartition来增加这个RDD的分区数,那么每一个partition的计算结果就减少了很多
* mapPartitions的使用场景?
* 一般在将一个RDD的计算结果写入到数据库redis mysql oracle,会使用mapPartition这个算子
*/
rdd.mapPartitions((iterator)=>{
//创建一个数据库连接
while(iterator.hasNext){
val value = iterator.next()
//拼接SQL语句
}
//批量插入
iterator
}, false)
rdd.mapPartitionsWithIndex((index,itertor)=>{
println("partitionId:"+index)
while(itertor.hasNext){
val v = itertor.next
println(v)
}
itertor
}, false).count()
val repartitionRDD = rdd.repartition(5)
//repartition(numpartitions) = coalesce(numpartitions,true)
val coaesceRDD = rdd.coalesce(2, false)
// println("coaesceRDD.partitions.size:" + coaesceRDD.partitions.size)
println("repartitionRDD.partitions.size:"+repartitionRDD.partitions.size)
sc.stop()
}
}