Spark概念及使用简介

Spark是什么?

Spark是一个分布式计算平台(Hadoop是一个包含分布式计算、存储、管理的大数据生态系统),它对标的是Hadoop的MapReduce,那么与Hadoop的MapReduce相比,它具有什么优势呢?

  1. 更快
  2. 更容易使用
    除了Java之外,提供了Scala、Python、R的API;
  3. 好用的库
    基于Spark Core提供了Spark SQL、Spark Streaming、MLib、GraphX等库;
  4. 运行方便
    能够在生产环境下借助Spark生态,也可以在本地测试时独立运行。

Spark架构

spark架构图

Spark的架构图如上,其核心是Spark Core,可以从HDFS、HBase获取数据;它的运行方式可以是本地运行、独立运行、借助Mesos、YARN等运行;基于Spark Core,提供了Spark SQL(类似Hive)、Spark Streaming(类似Storm)、MLib、GraphX。

Spark的运行

1.四种运行模式

Spark的运行模式主要有Local,Standalone,yarn,mesos等,其中Local主要用于本地调试,而yarn是最常见的生产模式。

2.如何运行

Spark的bin目录下,有若干个启动脚本:
pyspark:python交互式接口
spark-class:java交互式接口
spark-shell:scala交互式接口
spark-submit:提交文件执行

Spark关键概念——RDD

1.RDD(Resilient Distributed Dataset) 弹性分布数据集概念

它代表一个不可变、可分区、里面的元素可并行计算的集合。RDD具有数据流模型的特点:自动容错、位置感知性调度和可伸缩性。


RDD示意图解.png

RDD初始来源.png

RDD特点如下:
(1)一组分片(Partition),即数据集的基本组成单位。对于RDD来说,每个分片都会被一个计算任务处理,并决定并行计算的粒度。用户可以在创建RDD时指定RDD的分片个数,如果没有指定,那么就会采用默认值。默认值就是程序所分配到的CPU Core的数目。

(2)一个计算每个分区的函数。Spark中RDD的计算是以分片为单位的,每个RDD都会实现compute函数以达到这个目的。compute函数会对迭代器进行复合,不需要保存每次计算的结果。

(3)RDD之间的依赖关系。RDD的每次转换都会生成一个新的RDD,所以RDD之间就会形成类似于流水线一样的前后依赖关系。在部分分区数据丢失时,Spark可以通过这个依赖关系重新计算丢失的分区数据,而不是对RDD的所有分区进行重新计算。

(4)一个Partitioner,即RDD的分片函数。当前Spark中实现了两种类型的分片函数,一个是基于哈希的HashPartitioner,另外一个是基于范围的RangePartitioner。只有对于于key-value的RDD,才会有Partitioner,非key-value的RDD的Parititioner的值是None。Partitioner函数不但决定了RDD本身的分片数量,也决定了parent RDD Shuffle输出时的分片数量。

(5)一个列表,存储存取每个Partition的优先位置(preferred location)。对于一个HDFS文件来说,这个列表保存的就是每个Partition所在的块的位置。按照“移动数据不如移动计算”的理念,Spark在进行任务调度的时候,会尽可能地将计算任务分配到其所要处理数据块的存储位置。

2. 生成RDD

由外部存储系统的数据集创建,包括本地的文件系统,还有所有Hadoop支持的数据集,比如HDFS、Cassandra、HBase等。
测试时,也可以由数组等生产RDD。

3. RDD算子

RDD包含两大类算子:

  1. 转化操作(Transformation),从已有数据集转化出新的数据集;
    常见的有:map、flatMap、filter、distinct、union、intersection、substract、cartesian、collect;
  2. 启动操作(Action),对数据集进行计算,并返回结果;
    常见的有:collect、count、countByValue、reduce、foreach。

Transformation都是惰性求值的,也就是说它不会马上进行计算,仅仅是计算转换操作,当遇到Action操作时,才会触发计算。

4. RDD的宽依赖和窄依赖

由于RDD是粗粒度的操作数据集,每个Transformation操作都会生成一个新的RDD,所以RDD之间就会形成类似流水线的前后依赖关系;RDD和它依赖的父RDD(s)的关系有两种不同的类型,即窄依赖(narrow dependency)和宽依赖(wide dependency)。如图所示显示了RDD之间的依赖关系。


dependency.png

从图中可知:

窄依赖:是指每个父RDD的一个Partition最多被子RDD的一个Partition所使用,例如map、filter、union等操作都会产生窄依赖;(独生子女)

宽依赖:是指一个父RDD的Partition会被多个子RDD的Partition所使用,例如groupByKey、reduceByKey、sortByKey等操作都会产生宽依赖;(超生)

在这里我们是从父RDD的partition被使用的个数来定义窄依赖和宽依赖,因此可以用一句话概括下:如果父RDD的一个Partition被子RDD的一个Partition所使用就是窄依赖,否则的话就是宽依赖。因为是确定的partition数量的依赖关系,所以RDD之间的依赖关系就是窄依赖;由此我们可以得出一个推论:即窄依赖不仅包含一对一的窄依赖,还包含一对固定个数的窄依赖。
一对固定个数的窄依赖的理解:即子RDD的partition对父RDD依赖的Partition的数量不会随着RDD数据规模的改变而改变;换句话说,无论是有100T的数据量还是1P的数据量,在窄依赖中,子RDD所依赖的父RDD的partition的个数是确定的,而宽依赖是shuffle级别的,数据量越大,那么子RDD所依赖的父RDD的个数就越多,从而子RDD所依赖的父RDD的partition的个数也会变得越来越多。

Shuffle和Stage

宽依赖会导致Shuffle,Shuffle即数据在分片上的重新分布,会产生网络传输是Spark执行过程中最耗时的部分。
调度器会在产生宽依赖的地方(Shuffle)形成一个stage,同一个stage内的RDD操作会流式执行,不会发生数据迁移。


stage.png

数据集持久化

Spark中的持久化概念与数据库中的持久化概念稍有区别:Spark中数据集的持久化更偏向于缓存的概念,将中间结果保存下来,以便后续步骤重复利用,避免了一些耗时步骤的反复运行。
Spark提供了多种持久化级别

持久化级别 说明
MEMORY_ONLY 将RDD以非序列化的Java对象存储在JVM中。 如果没有足够的内存存储RDD,则某些分区将不会被缓存,每次需要时都会重新计算。 这是默认级别。
MEMORY_AND_DISK 将RDD以非序列化的Java对象存储在JVM中。如果数据在内存中放不下,则溢写到磁盘上.需要时则会从磁盘上读取
MEMORY_ONLY_SER (Java and Scala) 将RDD以序列化的Java对象(每个分区一个字节数组)的方式存储.这通常比非序列化对象(deserialized objects)更具空间效率,特别是在使用快速序列化的情况下,但是这种方式读取数据会消耗更多的CPU。
MEMORY_AND_DISK_SER (Java and Scala) 与MEMORY_ONLY_SER类似,但如果数据在内存中放不下,则溢写到磁盘上,而不是每次需要重新计算它们。
DISK_ONLY 将RDD分区存储在磁盘上。
MEMORY_ONLY_2, MEMORY_AND_DISK_2等 与上面的储存级别相同,只不过将持久化数据存为两份,备份每个分区存储在两个集群节点上。
OFF_HEAP(实验中) 与MEMORY_ONLY_SER类似,但将数据存储在堆内存中。 这需要启用堆内存。

共享变量(累加器和共享变量)

Spark中因为算子中的真正逻辑是发送到Executor中去运行的,所以当Executor中需要引用外部变量时,需要使用广播变量累加器相当于统筹大变量,常用于计数,统计。

广播变量:一些公共规则、公共配置可以使用广播
广播变量预先存储在Driver上,当Task需要广播变量时,它会查看它所在的Executor是否包含,若无所在Executor的BlockManager向Driver获取广播变量。
广播变量更新时,要先删除,再声明新的广播变量。

val conf = new SparkConf()
conf.setMaster("local").setAppName("brocast")
val sc = new SparkContext(conf)
val list = List("hello xasxt")
val broadCast = sc.broadcast(list)
val lineRDD = sc.textFile("./words.txt")
lineRDD.filter { x => broadCast.value.contains(x) }.foreach { println}
sc.stop()

具体示例如上图,不使用广播变量,则Driver会把该变量发给每个Task。(在Driver定义,在Executor使用)

累加器:
累加器通常用于统计,在Driver定义,由Executor更新。

import org.apache.spark.{SparkConf, SparkContext}
 
object AccumulatorOperator {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf()
    conf.setMaster("local").setAppName("accumulator")
    val sc = new SparkContext(conf)
    val accumulator = sc.accumulator(0)
    sc.textFile("./records.txt",2).foreach {//两个变量
      x =>{accumulator.add(1)
      println(accumulator)}}
    println(accumulator.value)
    sc.stop()
  }
}

参考文献:
https://www.cnblogs.com/qingyunzong/p/8899715.html#_label0_0(RDD介绍,超详细)
https://blog.csdn.net/databatman/article/details/53023818#4shuffle-%E5%92%8C-stage(shuffle讲的不错,调优讲的不错)
https://www.cnblogs.com/liuliliuli2017/p/6782687.html(共享变量)
https://www.cnblogs.com/LHWorldBlog/p/8424681.html(广播变量和累加器)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容