val result = sc.textFile("hdfs://sxjdb01:8020/home/mk/chongfu")
val links= result.map(x=>{
x.split(",")
(x(0),x(1))
}).partitionBy(new HashPartitioner(100)).persist(StorageLevel.MEMORY_ONLY_2)
Var ranks = links.mapValues(v=>1.0)
For(i<- o until 10){
Val contributions = links.join(ranks).flatMap{
Case(pagId,(links,rank))=>
Links.map(dest=>(dest,rank/links.size))
}
ranks=contributions.reduceByKey((x,y)=>x+y).mapValues(v=>0.15+0.15*v)
}
ranks.saveAsTestFile(“”)
解说:
1、linksRDD每次迭代都会和ranks进行join。由于links该RDD值只会被扫描一次,所以我对其进行了分区和持久化,这样可以减少各节点之间的通信(也叫数据混洗)
2、当我们第一次创建ranks的时候,我们使用了mapValues而不是map为的就是保留父RDD(links)的分区,这样对他进行连接操作的时候通信开销就会减小
3、在循环体中,我们使用完reduceByKey后使用mapValues的原因是,因为reduceByKey的操作结果是一个哈希分区,使用mapValues后同样的操作结果也会是一个哈希分区,下一次迭代的时候再join就会更加高效
因此为了最大化分区的优化作用,应该在无需改变元素的健时尽量使用mapValues和flatMapValues