大数据 之 SparkCore

一、Spark 特点
 快
与 Hadoop 的 MapReduce 相比,Spark 基于内存的运算要快 100 倍以上,基于
硬盘的运算也要快 10 倍以上。Spark 实现了高效的 DAG 执行引擎,可以通过基
于内存来高效处理数据流。
 易用
Spark 支持 Java、Python、R 和 Scala 的 API,还支持超过 80 种高级算法,使
用户可以快速构建不同的应用。而且 Spark 支持交互式的 Python 和 Scala 的
shell,可以非常方便地在这些 shell 中使用 Spark 集群来验证解决问题的方
法。
 通用
Spark 提供了统一的解决方案。Spark 可以用于批处理、交互式查询(Spark SQL)、
实时流处理(Spark Streaming)、机器学习(Spark MLlib)和图计算(GraphX)。这些
不同类型的处理都可以在同一个应用中无缝使用。Spark 统一的解决方案非常具
有吸引力,毕竟任何公司都想用统一的平台去处理遇到的问题,减少开发和维护
的人力成本和部署平台的物力成本。
 兼容性
Spark 可以非常方便地与其他的开源产品进行融合。比如,Spark 可以使用
Hadoop 的 YARN 和 Apache Mesos 作为它的资源管理和调度器,并且可以处理
所有 Hadoop 支持的数据,包括 HDFS、HBase 和 Cassandra 等。这对于已经部
署 Hadoop 集群的用户特别重要,因为不需要做任何数据迁移就可以使用 Spark
的强大处理能力。Spark 也可以不依赖于第三方的资源管理和调度器,它实现了
Standalone 作为其内置的资源管理和调度框架,这样进一步降低了 Spark 的使


用门槛,使得所有人都可以非常容易地部署和使用 Spark。此外,Spark 还提供
了在 EC2 上部署 Standalone 的 Spark 集群的工具。
4. Spark 运行模式
1. local 本地模式(单机)--学习测试使用
分为 local 单线程和 local-cluster 多线程。
2. standalone 独立集群模式--学习测试使用
典型的 Mater/slave 模式。
3. standalone-HA 高可用模式--生产环境使用
基于 standalone 模式,使用 zk 搭建高可用,避免 Master 是有单点故
障的。
4. on yarn 集群模式--生产环境使用
运行在 yarn 集群之上,由 yarn 负责资源管理,Spark 负责任务调度和
计算。
好处:计算资源按需伸缩,集群利用率高,共享底层存储,避免数据跨集
群迁移。
5. on mesos 集群模式--国内使用较少
运行在 mesos 资源管理器框架之上,由 mesos 负责资源管理,Spark 负
责任务调度和计算。
6. on cloud 集群模式--中小公司未来会更多的使用云服务
比如 AWS 的 EC2,使用这个模式能很方便的访问 Amazon 的 S3。


二、Spark Core
1. RDD 详解
1) 为什么要有 RDD?
在许多迭代式算法(比如机器学习、图算法等)和交互式数据挖掘中,不同计算阶
段之间会重用中间结果,即一个阶段的输出结果会作为下一个阶段的输入。但是,
之前的 MapReduce 框架采用非循环式的数据流模型,把中间结果写入到 HDFS
中,带来了大量的数据复制、磁盘 IO 和序列化开销。且这些框架只能支持一些
特定的计算模式(map/reduce),并没有提供一种通用的数据抽象。


AMP 实验室发表的一篇关于 RDD 的论文:《Resilient Distributed Datasets: A
Fault-Tolerant Abstraction for In-Memory Cluster Computing》就是为了解
决这些问题的。
RDD 提供了一个抽象的数据模型,让我们不必担心底层数据的分布式特性,只需
将具体的应用逻辑表达为一系列转换操作(函数),不同 RDD 之间的转换操作之
间还可以形成依赖关系,进而实现管道化,从而避免了中间结果的存储,大大降
低了数据复制、磁盘 IO 和序列化开销,并且还提供了更多的
API(map/reduec/filter/groupBy...)。
2) RDD 是什么?
RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是 Spark 中最
基本的数据抽象,代表一个不可变、可分区、里面的元素可并行计算的集合。 单
词拆解:
 Resilient :它是弹性的,RDD 里面的中的数据可以保存在内存中或者磁
盘里面;
 Distributed :它里面的元素是分布式存储的,可以用于分布式计算;
 Dataset: 它是一个集合,可以存放很多元素。
3) RDD 主要属性
进入 RDD 的源码中看下:
RDD 源码
在源码中可以看到有对 RDD 介绍的注释,我们来翻译下:


1. A list of partitions : 一组分片(Partition)/一个分区(Partition)
列表,即数据集的基本组成单位。 对于 RDD 来说,每个分片都会被一个
计算任务处理,分片数决定并行度。用户可以在创建 RDD 时指定 RDD 的
分片个数,如果没有指定,那么就会采用默认值。
2. A function for computing each split : 一个函数会被作用在每一个
分区。 Spark 中 RDD 的计算是以分片为单位的,compute 函数会被作用
到每个分区上。
3. A list of dependencies on other RDDs : 一个 RDD 会依赖于其他多
个 RDD。 RDD 的每次转换都会生成一个新的 RDD,所以 RDD 之间就会形
成类似于流水线一样的前后依赖关系。在部分分区数据丢失时,Spark 可
以通过这个依赖关系重新计算丢失的分区数据,而不是对 RDD 的所有分
区进行重新计算。(Spark 的容错机制)
4. Optionally, a Partitioner for key-value RDDs (e.g. to say that the
RDD is hash-partitioned): 可选项,对于 KV 类型的 RDD 会有一个
Partitioner,即 RDD 的分区函数,默认为 HashPartitioner。
5. Optionally, a list of preferred locations to compute each split on
(e.g. block locations for an HDFS file): 可选项,一个列表,存储
存取每个 Partition 的优先位置(preferred location)。 对于一个
HDFS 文件来说,这个列表保存的就是每个 Partition 所在的块的位置。
按照"移动数据不如移动计算"的理念,Spark 在进行任务调度的时候,会
尽可能选择那些存有数据的 worker 节点来进行任务计算。
总结
RDD 是一个数据集的表示,不仅表示了数据集,还表示了这个数据集从哪来,如
何计算,主要属性包括:
1. 分区列表
2. 计算函数
3. 依赖关系
4. 分区函数(默认是 hash)
5. 最佳位置
分区列表、分区函数、最佳位置,这三个属性其实说的就是数据集在哪,在哪计
算更合适,如何分区;
计算函数、依赖关系,这两个属性其实说的是数据集怎么来的。


2. RDD-API
1) RDD 的创建方式
1. 由外部存储系统的数据集创建,包括本地的文件系统,还有所有 Hadoop
支持的数据集,比如 HDFS、Cassandra、HBase 等:
val rdd1 =
sc.textFile("hdfs://node1:8020/wordcount/input/words.txt")
2. 通过已有的 RDD 经过算子转换生成新的 RDD:
val rdd2=rdd1.flatMap(_.split(" "))
3. 由一个已经存在的 Scala 集合创建:
val rdd3 = sc.parallelize(Array(1,2,3,4,5,6,7,8)) 或者
val rdd4 = sc.makeRDD(List(1,2,3,4,5,6,7,8))
makeRDD 方法底层调用了 parallelize 方法:
RDD 源码
2) RDD 的算子分类
RDD 的算子分为两类:
1. Transformation 转换操作:返回一个新的 RDD
2. Action 动作操作:返回值不是 RDD(无返回值或返回其他的)
注意:
1、RDD 不实际存储真正要计算的数据,而是记录了数据的位置在哪里,数据的转换
关系(调用了什么方法,传入什么函数)。
2、RDD 中的所有转换都是惰性求值/延迟执行的,也就是说并不会直接计算。只有
当发生一个要求返回结果给 Driver 的 Action 动作时,这些转换才会真正运行。
3、之所以使用惰性求值/延迟执行,是因为这样可以在 Action 时对 RDD 操作形成


DAG 有向无环图进行 Stage 的划分和并行优化,这种设计让 Spark 更加有效率地
运行。
3) Transformation 转换算子
转换算子 含义
map(func) 返回一个新的 RDD,该 RDD 由每一个输入元素
经过 func 函数转换后组成
filter(func) 返回一个新的 RDD,该 RDD 由经过 func 函数
计算后返回值为 true 的输入元素组成
flatMap(func)
类似于 map,但是每一个输入元素可以被映射为
0 或多个输出元素(所以 func 应该返回一个序
列,而不是单一元素)
mapPartitions(func)
类似于 map,但独立地在 RDD 的每一个分片上
运行,因此在类型为 T 的 RDD 上运行时,func
的函数类型必须是 Iterator[T] =>
Iterator[U]
mapPartitionsWithIndex(func)
类似于 mapPartitions,但 func 带有一个整数
参数表示分片的索引值,因此在类型为 T 的
RDD 上运行时,func 的函数类型必须是(Int,
Interator[T]) => Iterator[U]
sample(withReplacement, fraction,
seed)
根据 fraction 指定的比例对数据进行采样,可
以选择是否使用随机数进行替换,seed 用于指
定随机数生成器种子
union(otherDataset) 对源 RDD 和参数 RDD 求并集后返回一个新的
RDD
intersection(otherDataset) 对源 RDD 和参数 RDD 求交集后返回一个新的
RDD
distinct([numTasks])) 对源 RDD 进行去重后返回一个新的 RDD
groupByKey([numTasks]) 在一个(K,V)的 RDD 上调用,返回一个(K,
Iterator[V])的 RDD
reduceByKey(func, [numTasks])
在一个(K,V)的 RDD 上调用,返回一个(K,V)的
RDD,使用指定的 reduce 函数,将相同 key 的
值聚合到一起,与 groupByKey 类似,reduce 任


转换算子 含义
务的个数可以通过第二个可选的参数来设置
aggregateByKey(zeroValue)(seqOp,
combOp, [numTasks])
对 PairRDD 中相同的 Key 值进行聚合操作,在
聚合过程中同样使用了一个中立的初始值。和
aggregate 函数类似,aggregateByKey 返回值
的类型不需要和 RDD 中 value 的类型一致
sortByKey([ascending], [numTasks])
在一个(K,V)的 RDD 上调用,K 必须实现
Ordered 接口,返回一个按照 key 进行排序的
(K,V)的 RDD
sortBy(func,[ascending],
[numTasks]) 与 sortByKey 类似,但是更灵活
join(otherDataset, [numTasks])
在类型为(K,V)和(K,W)的 RDD 上调用,返回一
个相同 key 对应的所有元素对在一起的
(K,(V,W))的 RDD
cogroup(otherDataset, [numTasks]) 在类型为(K,V)和(K,W)的 RDD 上调用,返回一
个(K,(Iterable,Iterable))类型的 RDD
cartesian(otherDataset) 笛卡尔积
pipe(command, [envVars]) 对 rdd 进行管道操作
coalesce(numPartitions) 减少 RDD 的分区数到指定值。在过滤大量数据
之后,可以执行此操作
repartition(numPartitions) 重新给 RDD 分区
4) Action 动作算子
动作算子 含义
reduce(func) 通过 func 函数聚集 RDD 中的所有元素,这个功
能必须是可交换且可并联的
collect() 在驱动程序中,以数组的形式返回数据集的所有
元素
count() 返回 RDD 的元素个数
first() 返回 RDD 的第一个元素(类似于 take(1))


动作算子 含义
take(n) 返回一个由数据集的前 n 个元素组成的数组
takeSample(withReplacement,num,
[seed])
返回一个数组,该数组由从数据集中随机采样的
num 个元素组成,可以选择是否用随机数替换不
足的部分,seed 用于指定随机数生成器种子
takeOrdered(n, [ordering]) 返回自然顺序或者自定义顺序的前 n 个元素
saveAsTextFile(path)
将数据集的元素以 textfile 的形式保存到
HDFS 文件系统或者其他支持的文件系统,对于每
个元素,Spark 将会调用 toString 方法,将它
装换为文件中的文本
saveAsSequenceFile(path)
将数据集中的元素以 Hadoop sequencefile 的格
式保存到指定的目录下,可以使 HDFS 或者其他
Hadoop 支持的文件系统
saveAsObjectFile(path) 将数据集的元素,以 Java 序列化的方式保存到
指定的目录下
countByKey() 针对(K,V)类型的 RDD,返回一个(K,Int)的 map,
表示每一个 key 对应的元素个数
foreach(func) 在数据集的每一个元素上,运行函数 func 进行
更新
foreachPartition(func) 在数据集的每一个分区上,运行函数 func
统计操作:
算子 含义
count 个数
mean 均值
sum 求和
max 最大值
min 最小值
variance 方差
sampleVariance 从采样中计算方差
stdev 标准差:衡量数据的离散程度


算子 含义
sampleStdev 采样的标准差
stats 查看统计结果

RDD 依赖关系

1)宽窄依赖

两种数据类型

如何区分宽窄依赖

窄依赖:父 RDD 的一个分区只会被子 RDD 的一个分区依赖;
宽依赖:父 RDD 的一个分区会被子 RDD 的多个分区依赖(涉及到 shuffle)。

2)为什么要设计宽窄依赖

1. 对于窄依赖:

窄依赖的多个分区可以并行计算;
窄依赖的一个分区的数据如果丢失只需要重新计算对应的分区的数据就可以了。

2. 对于宽依赖:

划分 Stage(阶段)的依据:对于宽依赖,必须等到上一阶段计算完成才能计算下
一阶段。

RDD 累加器和广播变量

在默认情况下,当 Spark 在集群的多个不同节点的多个任务上并行运行一个函
数时,它会把函数中涉及到的每个变量,在每个任务上都生成一个副本。但是,
有时候需要在多个任务之间共享变量,或者在任务(Task)和任务控制节点
(Driver Program)之间共享变量。
为了满足这种需求,Spark 提供了两种类型的变量:
1. 累加器 accumulators:累加器支持在所有不同节点之间进行累加计算(比
如计数或者求和)。


2. 广播变量 broadcast variables:广播变量用来把变量在所有节点的内存
之间进行共享,在每个机器上缓存一个只读的变量,而不是为机器上的每
个任务都生成一个副本。

Spark CoreSpark的核心组件,主要负责任务调度、内存管理、错误恢复、与存储系统的交互等。以下是大数据常见面试题之Spark Core: 1. 什么是Spark CoreSpark CoreSpark的核心组件,它提供了分布式任务调度、内存管理、错误恢复、与存储系统的交互等功能。 2. Spark Core的作用是什么? Spark Core的作用是管理Spark应用程序的整个生命周期,包括任务调度、内存管理、错误恢复、与存储系统的交互等。 3. Spark Core的优点是什么? Spark Core的优点包括高效的内存管理、快速的任务调度、灵活的错误恢复、与多种存储系统的兼容性等。 4. Spark Core如何实现任务调度? Spark Core通过DAG(有向无环图)来实现任务调度,将任务分解成多个阶段,每个阶段包含多个任务,然后按照依赖关系依次执行。 5. Spark Core如何实现内存管理? Spark Core通过RDD(弹性分布式数据集)来实现内存管理,将数据分成多个分区,每个分区可以在不同的节点上进行计算,从而实现高效的内存管理。 6. Spark Core如何实现错误恢复? Spark Core通过RDD的容错机制来实现错误恢复,当某个节点出现故障时,Spark会自动将该节点上的任务重新分配到其他节点上执行。 7. Spark Core如何与存储系统交互? Spark Core通过支持多种存储系统的API来与存储系统交互,包括HDFS、S3、Cassandra等。同时,Spark还提供了自己的内存存储系统——Tachyon。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值