partitionBy 函数 自定义 Partitioner
partitioner 是在map阶段用来分区的,跟mapreduce的分区对应。可以用partitoner 来把数据分成多个区,每个区中包含特定key的数据。如果没有指定partitioner 默认使用 HashPartitioner。
注意:对spark RDD, partitioner 只有在key-value类型的RDD中可以设置partitioner信息。
数据格式:3 http://tinyurl.com/3jcvsm
自定义一个partitoner。这个partitoner的分区方式为,以传入的一个String 类型array来分区,本例是用来把相同的域名放在同一个分区(接上一个URL的例子)
//继承Partitioner 传入一个String类型的array(用于确定分区信息)
class HOSTpartitioner(ins: Array[String]) extends Partitioner{
//初始化一个hashMap对象
val parMap = new mutable.HashMap[String,Int]()
var count = 0
//遍历array 把它的每个位置上的值作为key,每个位置的下标作为vale存入hashMap中
for ( i <- ins ){
parMap += (i->count)
count += 1
}
//必须实现的方法,指定分为几个区。
override def numPartitions : Int = count
//获取分区号,传入的是key-value类型中的可以。
override def getPartition(key: Any) :Int = {
val urls = new URL(key.toString)
val host = urls.getHost
return parMap.getOrElse(host.toString,0)
}
}
partition使用:(接上一个URL的例子)
//获取所有有URL的域名,去重
val rdd6 = rdd1.map(xc =>{
val url = xc._1;
val urls = new URL(url)
val host = urls.getHost
host
}).distinct().collect()
// rdd6.foreach(println)
//设置partition
rdd1.partitionBy(new HOSTpartitioner(rdd6))