Spark六 数据分区

分区

1) Spark分布式程序中网络传输的通信代价很大,所以为了较少传输开销,需要控制RDD分区,和单节点的程序需要选择使用合适的数据结构一样,Spark程序需要选择合适的分区方式

2) 只有数据集是基于键时,分区才会有用,Spark可以确保同一个组的键出现在同一个节点上,比如使用键的哈希值做模运算

3) 如果不使用分区partitionBy(),则每次调用Join()等函数都对从来不会变化的数据重新进行哈希值计算和跨节点数据清洗,效率低。

4) sortByKey()可以使用RangePartitioner分区,groupByKey()可以使用HashPartitioner分区


获取RDD分区方式


1) 驱动器程序中创建(Int, Int)Pair RDD

2) 查看分区,返回Option对象

3) 没有分区方式,进行哈希分区,创建新的RDD,使用persist()使得后续RDD操作不会对partitioned谱系图重新求值

4) 查看是否定义分区

5) 获取分区方式,获取分区


从分区中获益的操作

cogroup()/groupWith()/join()/leftOuterJoin()/rightOuterJoin()/groupByKey()/reduceByKey()/combineByKey()/lookup()

根据键跨节点进行数据混洗的操作,都会从分区获益。尤其时对于 join()和cogroup()这种操作两个数据集的操作,如果事先分区,则其中一个分区不发生混洗。


影响分区方式的操作

1) Spark提供mapValues()和flatMapValues()两种操作保证每个二元组的键保持不变,使得转化操作的结果可以按照已知的方式分区,只是使用map()或者flatMap()可能会改变键

2) 为结果RDD设好分区方式


3) > 对于二元操作,输出数据的分区方式取决于父RDD的分区方式。

    > 默认使用哈希分区,分区的数量和操作的并行度数量一样

    > 如果两个父RDD都设置过分区方式,结果RDD采用第一个父RDD的分区方式


PageRank

1 PageRank可以从RDD分区中获益,根据外部文档指向一个文档的链接,对集合中文档赋重要性度量值,该算法可以用于网页排序

2 PageRank中使用了多次join,是个迭代算法,所以使分区操作的很好用例。

3 算法

1) 维护两个数据集,(pageID, linkList)包含每个页面的相邻页面的列表,(pageID, rank)每个页面的当前rank

2) > 每个页面的rank为1.0

    > 每次迭代中,对页面p,向每个相邻页面发送一个值为rank(p)/numNeighbors(p)的贡献值

    > 将每个页面的排序值设置为0.15 + 0.85 * contributionsReceived

    > 循环上面两步,则会逐渐收敛于每个页面实际的PageRank值,实际操作中大约有10次迭代


自定义分区方式

猜你喜欢

转载自blog.csdn.net/weixin_42129080/article/details/80913859