spark core学习
1 RDD为什么会出现?
- MapReduce 执行迭代计算任务
多个 MapReduce 任务之间没有基于内存的数据共享方式, 只能通过磁盘来进行共享,这种方式明显比较低效
- RDD执行迭代计算任务
在 Spark 中, 最终 Job3 从逻辑上的计算过程是: Job3 = (Job1.map).filter
, 整个过程是共享内存的, 而不需要将中间结果存放在可靠的分布式文件系统中。这种方式可以在保证容错的前提下, 提供更多的灵活, 更快的执行速度, RDD 在执行迭代型任务时候的表现可以通过下面代码体现
在这个例子中, 进行了大致 10000 次迭代, 如果在 MapReduce 中实现, 可能需要运行很多 Job, 每个 Job 之间都要通过 HDFS 共享结果, 熟快熟慢一窥便知
2 RDD特点
2.1 RDD 不仅是数据集, 也是编程模型
2.2 RDD 可以分区
2.3 RDD 是只读的
2.4 RDD 是可以容错的
3 什么叫弹性分布式数据集
3.1 分布式
RDD 支持分区, 可以运行在集群中
3.2 弹性
-
RDD 支持高效的容错
-
RDD 中的数据即可以缓存在内存中, 也可以缓存在磁盘中, 也可以缓存在外部存储中
3.3 数据集
-
RDD 可以不保存具体数据, 只保留创建自己的必备信息, 例如依赖和计算函数
-
RDD 也可以缓存起来, 相当于存储具体数据
4 RDD的算子
4.1 分类
RDD 中的算子从功能上分为两大类
-
Transformation(转换) 它会在一个已经存在的 RDD 上创建一个新的 RDD, 将旧的 RDD 的数据转换为另外一种形式后放入新的 RDD
-
Action(动作) 执行各个分区的计算任务, 将的到的结果返回到 Driver 中
RDD 中可以存放各种类型的数据, 那么对于不同类型的数据, RDD 又可以分为三类
-
针对基础类型(例如 String)处理的普通算子
-
针对
Key-Value
数据处理的byKey
算子 -
针对数字类型数据处理的计算算子
4.2 特点
-
Spark 中所有的 Transformations 是 Lazy(惰性) 的, 它们不会立即执行获得结果. 相反, 它们只会记录在数据集上要应用的操作. 只有当需要返回结果给 Driver 时, 才会执行这些操作, 通过 DAGScheduler 和 TaskScheduler 分发到集群中运行, 这个特性叫做 惰性求值
-
默认情况下, 每一个 Action 运行的时候, 其所关联的所有 Transformation RDD 都会重新计算, 但是也可以使用
presist
方法将 RDD 持久化到磁盘或者内存中. 这个时候为了下次可以更快的访问, 会把数据保存到集群上
4.3 Transformations (转换)算子
map(T ⇒ U)
作用:把 RDD 中的数据 一对一 的转为另一种形式
调用:def map[U: ClassTag](f: T ⇒ U): RDD[U]
参数:f
→ Map 算子是 原RDD → 新RDD
的过程, 传入函数的参数是原 RDD 数据, 返回值是经过函数转换的新 RDD 的数据
flatMap(T ⇒ List[U])
作用:FlatMap 算子和 Map 算子类似, 但是 FlatMap 是一对多
调用:def flatMap[U: ClassTag](f: T ⇒ List[U]): RDD[U]
参数:f
→ 参数是原 RDD 数据, 返回值是经过函数转换的新 RDD 的数据, 需要注意的是返回值是一个集合, 集合中的数据会被展平后再放入新的 RDD
filter(T ⇒ Boolean)
作用:Filter
算子的主要作用是过滤掉不需要的内容
mapPartitions(List[T] ⇒ List[U])
作用:和 map 类似, 但是针对整个分区的数据转换
mapPartitionsWithIndex
作用:和 mapPartitions 类似, 只是在函数中增加了分区的 Index
mapValues
作用:MapValues 只能作用于 Key-Value 型数据, 和 Map 类似, 也是使用函数按照转换数据, 不同点是 MapValues 只转换 Key-Value 中的 Value
sample(withReplacement, fraction, seed)
作用:Sample 算子可以从一个数据集中抽样出来一部分, 常用作于减小数据集以保证运行速度, 并且尽可能少规律的损失
参数:
-
withReplacement, 意为取样后是否放回原数据集供下次使用
-
fraction, 意为抽样的比例
-
seed, 随机数种子, 用于 Sample 内部随机生成下标, 一般不指定, 使用默认值
union(other) 并集
intersection(other) 交集
subtract(other, numPartitions) 差集
distinct(numPartitions)
作用:去重
reduceByKey((V, V) ⇒ V, numPartition)
作用:按照 Key 分组生成一个 Tuple, 然后针对每个组执行 reduce
算子
参数:执行数据处理的函数, 传入两个参数, 一个是当前值, 一个是局部汇总, 这个函数需要有一个输出, 输出就是这个 Key 的汇总结果
groupByKey()
作用:按照 Key 分组, 和 ReduceByKey 有点类似, 但是 GroupByKey 并不求聚合, 只是列举 Key 对应的所有 Value
combineByKey()
作用:对数据集按照 Key 进行聚合
调用:combineByKey(createCombiner, mergeValue, mergeCombiners, [partitioner], [mapSideCombiner], [serializer])
参数:
-
createCombiner
将 Value 进行初步转换 -
mergeValue
在每个分区把上一步转换的结果聚合 -
mergeCombiners
在所有分区上把每个分区的聚合结果聚合 -
partitioner
可选, 分区函数 -
mapSideCombiner
可选, 是否在 Map 端 Combine -
serializer
序列化器
aggregateByKey()
作用:聚合所有 Key 相同的 Value, 换句话说, 按照 Key 聚合 Value
调用:aggregateByKey(zeroValue)(seqOp, combOp)
参数:
-
zeroValue
初始值 -
seqOp
转换每一个值的函数 -
comboOp
将转换过的值聚合的函数
foldByKey(zeroValue)((V, V) ⇒ V)
作用:和 ReduceByKey 是一样的, 都是按照 Key 做分组去求聚合, 但是 FoldByKey 的不同点在于可以指定初始值
调用:foldByKey(zeroValue)(func)
参数:
-
zeroValue
初始值 -
func
seqOp 和 combOp 相同, 都是这个参数
join(other, numPartitions)
作用:将两个 RDD 按照相同的 Key 进行连接
调用:join(other, [partitioner or numPartitions])
参数:
-
other
其它 RDD -
partitioner or numPartitions
可选, 可以通过传递分区函数或者分区数量来改变分区
cogroup(other, numPartitions)
作用:多个 RDD 协同分组, 将多个 RDD 中 Key 相同的 Value 分组
调用:cogroup(rdd1, rdd2, rdd3, [partitioner or numPartitions])
参数:
-
rdd…
最多可以传三个 RDD 进去, 加上调用者, 可以为四个 RDD 协同分组 -
partitioner or numPartitions
可选, 可以通过传递分区函数或者分区数来改变分区
sortBy(ascending, numPartitions)
作用:排序相关相关的算子有两个, 一个是`sortBy`, 另外一个是`sortByKey`
调用:sortBy(func, ascending, numPartitions)
参数:
-
`func`通过这个函数返回要排序的字段
-
`ascending`是否升序
-
`numPartitions`分区数
partitionBy(partitioner) coalesce(numPartitions)
作用:一般涉及到分区操作的算子常见的有两个, repartitioin
和 coalesce
, 两个算子都可以调大或者调小分区数量
调用:
-
repartitioin(numPartitions)
-
coalesce(numPartitions, shuffle)
参数:
-
numPartitions
新的分区数 -
shuffle
是否 shuffle, 如果新的分区数量比原分区数大, 必须 Shuffled, 否则重分区无效