[Spark--基础]--解密Spark的分区

来源:互联网 发布:怎么申请阿里云客服 编辑:程序博客网 时间:2024/06/02 06:45

原文: https://www.edureka.co/blog/demystifying-partitioning-in-spark

供稿人:Prithviraj Bose

Spark的  弹性分布式数据集  (编程抽象)被懒惰地评估,Transform被存储为有向无环图(DAG)。因此,RDD上的每个操作都将使Spark重新计算DAG。这就是Spark如何实现弹性,因为如果任何工作节点失败,那么DAG只需要重新计算。

 对RDD 进行缓存(坚持适当的存储级别)也是  强制性的,这样RDD上的频繁操作不会强制Spark重新计算DAG。


为什么使用分区?

在集群计算中,核心挑战是尽量减少网络流量当数据是以键值为导向时,分区变得势在必行,因为随后在RDD上进行transform,整个网络上的数据都有相当数量的shuffer。如果在相同的分区中存储相似的键或范围的键,则shuffer被最小化并且处理变得非常快。

需要在工作节点间进行数据混洗的转换极大地受益于分区。这样的转换是  cogroup,groupWith,join,leftOuterJoin,rightOuterJoin,groupByKey,reduceByKey,combineByKey lookup

分区是可配置的,只要RDD是基于键值对的即可。

分区的属性

  1. 同一分区中的元组保证在同一台机器上。
  2. 群集中的每个节点可以包含多个分区。
  3. 分区的总数是可配置的,默认情况下它被设置为所有执行器节点上的核心总数。


Spark中的分区类型

Spark支持两种类型的分区,

  • 散列分区:使用Java的  Object.hashCode方法确定分区为  partition = key.hashCode()%numPartitions。
                           

  • 范围分区:使用范围向各个分区分配属于范围内的键。这种方法适用于按键有自然排序而且按键非负的情况。下面的代码片段显示了范围分区器的用法。
                           

代码示例

我们来看一个关于如何在工作节点之间分配数据的例子。完整的Scala代码可以  在这里找到

     

这里有12个坐标(作为元组)的一些测试数据,

                         

创建一个 大小为2 的  org.apache.spark.HashPartitioner,其中key将根据key的hashCode跨这两个分区进行分区。

                         

然后,我们可以检查这些对,并执行各种基于键的转换,如  foldByKey  和 reduceByKey。

总而言之,划分极大地提高了基于key转换的执行速度。



参考:

https://medium.com/@corentinanjuna/apache-spark-rdd-partitioning-preservation-2187a93bc33e

https://acadgild.com/blog/partitioning-in-spark/



原创粉丝点击