Spark和MR的不同点:

  • Spark提供了丰富的操作
  • MR只有Map和Reduce两个操作

2.1 Spark程序“Hello World”

存储在HDFS的Log文件中,计算出现过字符串"Hello World"的行数,假设Log文件存储在 hdfs://root/Log

代码

//对于所有的Spark程序,这是必须要做的第一步,创建一个Spark的上下文
//该步骤程序会向集群申请资源以及构建相应的运行环境
SparkContext(参数1,参数2,参数3,参数4)

  • 第一个变量:当前程序运行的集群地址
  • 第二个变量:Spark程序的标识
  • 第三个变量:Spark安装路径
  • 第四个变量:Spark程序的jar包路径
val sc=new SparkContext("spark://...","Hello World","YOUR_SPARK_HOME","YOUR_APP_JAR")

通过sc变量,利用textFile接口从HDFS文件系统读入Log文件
返回一个变量file

val file=sc.textFile("hdfs://root/Log)

对file进行过滤操作
filter()函数参数传入的是一个function对象,该函数对象:p:(A)=>Boolean
就是对每一行字符串判断是否含有对象A,返回一个新的变量filerRDD

val filerRDD=file.filter(_.contains("Hello World"))

进行cache操作,以便后续重用filterRDD变量

filterRDD.cache()

计数,返回包含"Hello World" 字符串的文本行数

filterRDD.count()

上面程序涉及到的相关概念介绍

  • 弹性分布式数据集RDD:file和filterRDD都是RDD
  • 创建操作:RDD的初始创建都是由SparkContext负责的,将内存中的集合或者外部文件系统作为输入源
  • 转换操作:将一个RDD通过一个操作转换为另外一个RDD
  • 控制操作:对RDD进行持久化,将其保存在磁盘或者内存中,便于后面重用
  • 行动操作:由于Spark是惰性计算,行动操作可以触发Spark作业的运行
    行动操作包括两类:
    一类的操作结果变成Scala集合或标量
    将RDD保存到外部文件或者数据库系统

Spark程序流程

spark如何处理大数据 spark大数据处理技术 pdf_数据集

2.2 Spark RDD

RDD概述
RDD:弹性分布式数据集,一个RDD代表一个被分区的只读数据集。

生成RDD的途径:
内存集合和外部存储系统
通过转换操作来自于其他的RDD,比如map,filter,join等

Spark RDD接口

spark如何处理大数据 spark大数据处理技术 pdf_spark_02

2.2.1 RDD分区(partitions)

分区的多少涉及到对这个RDD进行并行计算的粒度,每一个RDD分区的计算操作都在一个单独的任务中被执行。用户可以自行指定分区数量,没指定则使用默认值。

如何查询一个RDD的分区数?
RDD有一个成员变量partitions,返回一个partition数组,该数组的大小就是分区数

rdd.partitions.size

指定分区数

spark如何处理大数据 spark大数据处理技术 pdf_spark_03

不指定分区数,使用默认分区数

spark如何处理大数据 spark大数据处理技术 pdf_数据集_04

2.2.2 RDD优先位置(preferredLocations)

指RDD的每一个分区所存储的位置,根据移动数据不如移动计算的理念,在Spark进行任务调度的时候,尽可能的将任务分配到数据块所存储的位置上.

spark如何处理大数据 spark大数据处理技术 pdf_数据集_05

2.2.3 RDD依赖关系(dependencies)
因为RDD是粗粒度的操作数据集,每一个转换操作都会生成一个新的RDD,所以RDD之间会形成类似于流水线一样的前后依赖关系.

一个矩形代表一个RDD
矩形中的椭圆形表示这个RDD的一个分区

org.apache.spark.OneToOneDependency 窄依赖:每一个父RDD的分区最多只被子RDD的一个分区所使用

spark如何处理大数据 spark大数据处理技术 pdf_spark如何处理大数据_06

org.apache.spark.ShuffleDependency 宽依赖:多个子RDD的分区会依赖于同一个父RDD的分区

spark如何处理大数据 spark大数据处理技术 pdf_字符串_07

为什么要区分这两种依赖关系?

  • 窄依赖可以在集群的一个节点上如流水线一般执行,可以计算所有父RDD的分区;宽依赖需要取得父RDD的所有分区上的数据进行计算.
  • 窄依赖:节点计算失败后的恢复更加有效,只需要计算对应的父RDD的分区;宽依赖:一个节点的失败导致其父RDD的多个分区重新计算,代价较高

具体实例PageRank算法