spark讲义总结

二十天左右的时间分别学习了:spark的安装与运行模式,RDD编程、SparKSql编程以及部分spark原理。复习一下过去一段时间学习的内容,也对前一段时间的学习做个总结,顺便规划一下后面的学习。

spark的安装与运行

  1. spark的下载:根据自己的需求去官网下载即可。网址:[https://archive.apache.org/dist/spark/](https://archive.apache.org/dist/spark/)
  2. spark支持三种运行模式:本地模式、伪分布模式、集群模式
  3. 集群模式有三种部署模式:standalongYarnMesos
  1. standalong模式
    • 独立模式,自带完整的服务。可单独部署到一个集群中,无需依赖其他资源管理系统
    • Cluster Manager:Master
    • Worker Node: Worker
    • 仅支持局粗粒度的资源分配方式
  2. Spark on Yarn模式
    • spark on yarn支持两种模式
      • Yarn-cluster:适用于生产环境
      • Yarn-client: 适用于交互、调试,希望立即看到app的输出
    • Cluster Manager :ResurceManager
    • Worker Node:NodeManager
    • 仅支持粗力度的资源分配方式
  3. spark on mesos模式
    • spark运行在Mesos上会比运行在Yarn上更加灵活,更加自然
    • Cluster Manager:Mesos Manager
    • Worker Node:Mesos Slave
    • 支持粗粒度、细粒度的资源分配方式

粗粒度模式(Coarse-grained Mode):每个应用程序的运行环境由一个Dirver和
若干个Executor组成,其中,每个Executor占用若干资源,内部可运行多个Task。
应用程序的各个任务正式运行之前,需要将运行环境中的资源全部申请好,且运行过
程中要一直占用这些资源,即使不用,最后程序运行结束后,回收这些资源。
细粒度模式(Fine-grained Mode):鉴于粗粒度模式会造成大量资源浪费,Spark
On Mesos还提供了另外一种调度模式:细粒度模式,这种模式类似于现在的云计
算,核心思想是按需分配。

运行模式(cluster/client)

最大的区别:Driver运行在哪:client是缺省的模式,能看见返回结果,适合调试;cluster与其相反

RDD编程

RDD(Resilient Distributed Dataset)是 Spark 中的核心概念,它是一个容错、可以并行执行的分布式数据集

RDD的五个特征
  • 一个分区的列表
  • 一个计算函数compute,对每个分区进行计算
  • 对其他RDDs的依赖列表
  • 对key-valueRDDs来说,存在一个分区器(partitioner)[可选]
  • 对每一个分区有一个优先位置的列表【可选】

RDD的特点:
  • 分区:RDD逻辑上是分区的,每个分区的数据是抽象存在的,计算的时候会通过一个compute 函数得到每个分区的数据
  • 只读:RDD是只读的,要想改变RDD中的数据,只能在现有的RDD基础上创建新的RDD
  • 依赖:RDDs之间的血缘关系的信息,称为依赖。依赖包括两种:
    • 宽依赖:发生shuffle的
    • 窄依赖:没有shuffle发生
  • 缓存:可以控制存储级别来进行缓存
  • checkpoint:RDD支持 checkpoint 将数据保存到持久化的存储中,这样就可以切断之前的血缘关系,因为checkpoint后的RDD不需要知道它的父RDDs了,它可以从 checkpoint 处拿到数据

RDD常见算子

RDD操作的算子分为两类:

  • Transaction:用来对RDD进行转化。这个操作是延迟执行的。返回一个新的RDD
  • Action:用来触发RDD的计算;得到相关计算结果或者将结果保存到外部系统中

常见的Transformation算子:

官方文档:http://spark.apache.org/docs/latest/rdd-programming-guide.html#transformations

map(func):对数据集中的每个元素都使用func,然后返回一个新的RDD

filter(func):对数据集中的每个元素都使用func,然后返回一个包含使func为true的元素构成的RDD

flatMap(func):与 map 类似,每个输入元素被映射为0或多个输出元素

mapPartitions(func):和map很像,但是map是将func作用在每个元素上,而mapPartitions是func作用在整个分区上

以上全部是是窄依赖

groupBy(func):按照传入函数的返回值进行分组。将key相同的值放入一个迭代器
glom():将每一个分区形成一个数组,形成新的RDD类型 RDD[Array[T]]

sample(withReplacement, fraction, seed):采样算子。以指定的随机种子(seed)随机抽样出数量为fraction的数据,withReplacement表示是抽出的数据是否放回,true为有放回的抽样,false为无放回的抽样

distinct([numTasks])):对RDD元素去重后,返回一个新的RDD。可传入numTasks参数改变RDD分区数

coalesce(numPartitions):缩减分区数,无shuffle

repartition:增加或减少分区数,有shuffle

sortBy(func,[ascending],[numTasks]): 使用func对数据进行处理,对处理后的结果进行排序

宽依赖的算子:groupBy,distinct,repartition,sortBy

intersection:RDD之间的交

union(otherRDD):RDD之间的并:窄依赖:得到的RDD分区数:两个RDD分区数之和

subtract(otherRDD):RDD之间的差

cartesian(otherRDD):笛卡尔积:宽依赖:两个RDD分区数的积

zip(otherRDD):将两个RDD组合成 key-value 形式的RDD,默认两个RDD的partition数量以及元素数量都相同,否则会抛出异常

action算子:

collect() / collectAsMap()
stats / count / mean / stdev / max / min
reduce(func) / fold(func) / aggregate(func)
first():Return the first element in this RDD

take(n):Take the first num elements of the RDD
top(n):按照默认(降序)或者指定的排序规则,返回前num个元素。
takeSample(withReplacement, num, [seed]):返回采样的数据
foreach(func) / foreachPartition(func):与map、mapPartitions类似,区别是
foreach 是 Action

saveAsTextFile(path) / saveAsSequenceFile(path) / saveAsObjectFile(path)

Key-Value RDD操作

Transformaction操作
  1. 类似Map操作
    mapValues / flatMapValues / keys / values
  2. 聚合操作
    groupByKey / reduceByKey / foldByKey / aggregateByKey
    combineByKey(OLD) / combineByKeyWithClassTag (NEW) => 底层实现
    subtractByKey:类似于subtract,删掉 RDD 中键与 other RDD 中的键相同的元素
    注意:groupByKey在一般情况下效率低,尽量少用
  3. 排序操作
    sortByKey:作用于pairRDD,对Key进行排序
  4. join操作
    cogroup / join / leftOuterJoin / rightOuterJoin / fullOuterJoin

Action操作

collectAsMap/countByKey

lookup(key):高效的查找方法,只查找对应分区的数据(如果RDD有分区器)

广播变量

广播变量主要是为了优化spark程序

广播变量将变量在节点的executor之间进行共享(有Driver广播出去)

广播变量用来高效分发较大的对象。向所有工作节点发送一个较大的只读值,以供一个或多个操作使用

使用广播变量的过程:

  • 对一个类型 T 的对象调用 SparkContext.broadcast 创建出一个 Broadcast[T]对象。 任何可序列化的类型都可以这么实现(在 Driver 端)
  • 通过 value 属性访问该对象的值(在 Executor 中)
  • 变量只会被发到各个 Executor 一次,作为只读值处理

累加器

累加器的作用:可以实现一个变量在不同的 Executor 端能保持状态的累加;
累计器在 Driver 端定义,读取;在 Executor 中完成累加;
累加器也是 lazy 的,需要 Action 触发;Action触发一次,执行一次,触发多次,执
行多次;