赞
踩
Spark Core是Spark的核心部分,是Spark SQL,Spark Streaming,Spark MLlib等等其他模块的基础, Spark Core提供了开发分布式应用的脚手架,使得其他模块或应用的开发者不必关心复杂的分布式计算如何实现,只需使用Spark Core提供的分布式数据结构RDD及丰富的算子API,以类似开发单机应用的方式来进行开发。
图中最下面那个就是Spark Core啦,日常使用的RDD相关的API就属于Spark Core,而Dataset、DataFrame则属于Spark SQL。
RDD是Spark Core的用户级API,了解RDD是了解Spark Core的第一步,本文基于Spark 2.x,主要对RDD的特点和组成进行分析。
RDD (Resilient Distributed Dataset,弹性分布式数据集):
In-Memory:RDD会优先使用内存Immutable(Read-Only):一旦创建不可修改Lazy evaluated:惰性执行Cacheable:可缓存,可复用Parallel:可并行处理Typed:强类型,单一类型数据Partitioned:分区的Location-Stickiness:可指定分区优先使用的节点
是Spark中最核心的数据抽象,数据处理和计算基本都是基于RDD。
一个RDD通常由5个要素组成:
与传统数据结构对比,只关心访问,不关心存储。通过迭代器访问数据,只要数据能被不重复地访问即可。后面会详细分析各要素。
算子,即对RDD进行变换的操作,按照是否触发Job提交可以分为两大类:
下面对RDD的组成要素进行分析
为什么要把数据分区?把数据分成若干partition是为了将数据分散到不同节点不同线程,从而能进行分布式的多线程的并行计算。
按什么规则分区?RDD从数据源生成的时候,数据通常是随机分配到不同的partition或者保持数据源的分区,如sc.parallelize(…),sc.textFile(…)。
这对于某些RDD操作来说是没有问题的,比如filter(),map(),flatMap(),rdd.union(otherRDD),rdd.intersection(otherRDD),rdd.subtract(otherRDD)。
但是对于reduceByKey(),foldByKey(),combineByKey(),groupByKey(),sortByKey(),cogroup(), join() ,leftOuterJoin(), rightOuterJoin()这些操作,随机分配分区就非常不友好,会带来很多额外的网络传输。影响一个分布式计算系统性能的最大敌人就是网络传输,所以必须尽量最小化网络传输。
为了减少网络传输,怎么分区才合理?对于reduceByKey操作应该把相同key的数据放到同一分区;对于sortByKey操作应该把同一范围的数据放到同一分区。
可见不同的操作适合不同的数据分区规则,Spark将划分规则抽象为Partitioner(分区器) ,分区器的核心作用是决定数据应归属的分区,本质就是计算数据对应的分区ID。
在Spark Core中内置了2个Partitioner来支持常用的分区规则(Spark MLlib,Spark SQL中有其他的)。
哈希分区器是默认的分区器,也是使用最广泛的一个,作用是将数据按照key的hash值进行分区。
分区ID计算公式非常简单:key的hash值 % 分区个数
, 如果key为null,则返回0.
也就是将key的hash值(Java中每个对象都有hash code,对象相等则hash code相同),除以分区个数,取余数为分区ID,这样能够保证相同Key的数据被分到同一个分区,但是每个分区的数据量可能会相差很大,出现数据
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。