【云驻共创】学Spark必读!总有一些Spark知识点你需要知道

举报
天阳 发表于 2021/12/20 17:04:29 2021/12/20
【摘要】 主要介绍了Spark的基本概念、技术架构,涉及SparkSQL、 StructuredStreaming、Spark Streaming多个组件基本功能。

前言

本章主要讲述Spark基本概念,了解Spark中RDD、DataSet 、DataFrame结构的异同点。理解Spark SQL、Spark Streaming、Structured Streaming三种常用组件的特点。

目标

学完本章后,您将能够:

  • 理解Spark应用场景,学据Spark特点。
  • 掌握Spark计算能力及具技术架构。

一、Spark概述

Spark简介

  • 2009年诞生于美国加州大学伯克利分校AMP实验室。
  • Apache Spark是一种基于内存的快速、通用、可扩展的大数据计算引擎。
  • Spark是一站式解决方案,集批处理、实时流处理、交互式查询、图计算与机器学习于一体。

Spark应用场景

  • 批处理可用于ETL(抽取、转换、加载)。
  • 机器学习可用于自动判断淘宝的买家评论是好评还是差评。
  • 交互式分析可用于查询Hive数据仓库。
  • 流处理可用于页面点击流分析,推荐系统,舆情分析等实时业务。

Spark的特点

Spark具有简洁、表达能力强、高效的特点

  • 轻:Spark核心代码只有3万行
  • 快:Spark对小数据Spark对小数据的延迟
  • 灵:Spark提供了不同层面的灵活性,它支持批处理计算、流处理计算、图处理计算和实时响应查询这些计算方式
  • 巧:巧妙借力现有大数据组件,spark与Hadoop大数据平台已经无缝的融合了,Spark能够利用Yarn作为资源管理调度器

Spark采用传统的计算引擎,十分之一的资源可以提高大约三倍的效率。另外随着数据容量的增加,spark处理时间并没有呈现指数级别的增加,而是线性增加,所以说Spark是一种高可靠、高可用、并且高效的大数据分布式计算引擎。


二、Spark数据结构

Spark核心概念RDD

  • RDD(Resilient Distributed Datasets)即弹性分布式数据集,是一个只读的,可分区的分布式数据集。
  • RDD默认存储在内存,当内存不足时,溢写到磁盘。
  • RDD 数据以分区的形式在集群中存储。
  • RDD具有血统机制(Lineage),发生数据丢失时,可快速进行数据恢复。

基于RDD的流式计算任务可描述为:从稳定的物理存储(如分布式文件系统)中加载记录,记录被传入由一组确定性操作构成的DAG,然后写回稳定存储。另外RDD还可以将数据集缓存到内存中,使得在多个操作之间可以重用数据集,基于这个特点可以很方便地构建迭代型应用(图计算、机器学习等)或者交互式数据分析应用。

RDD的依赖关系

RDD的依赖关系主要是分为了宽依赖和窄依赖,左边是窄依赖,右边是宽依赖。从图中我们可以发现,对于父RDD的每一个分区,最多只被一个RDD的一个分区所使用,这个呢叫做窄依赖。宽依赖对于父RDD的每一个分区,被子RDD的多个分区所引用。另外宽依赖是RDD进行的划分stage的标准。从图中我们还可以了解另外一个概念,就是血统的概念。血统就是指的是从一个RDD变化到另外一个RDD,它的链接。

宽窄依赖的区别 - - 算子

  • 窄依赖指的是每一个父RDD的Partition最多被子RDD的一个Partition使用。如map,filter、union
  • 宽依赖指的是多个子RDD的Partition会依赖同一个父RDD的Partition。如groupByKey、reduceByKey、sortByKey

宽窄依赖的区别-容错性

假如某个节点出故障了:

窄依赖:只要重算和子RDD分区对应的父RDD分区即可;宽依赖:极端情况下,所有的父RDD分区都要进行重新计算。

如下图所示,b1分区丢失,则需要重新计算a1,a2和a3

宽窄依赖的区别-传输

宽依赖往往对应着shuffle操作,需要在运行过程中将同一个父RDD的分区传入到不同的子RDD分区中,中间可能涉及多个节点之间的数据传输;

窄依赖的每个父RDD的分区只会传入到一个子RDD分区中,通常可以在一个节点内完成转换。

RDD的Stage划分

Spark任务会根据RDD之间的依赖关系,形成一个DAG有向无环图,DAG会提交给DAGScheduler,DAGScheduler会把DAG划分相互依赖的多个stage,划分stage的依据就是RDD之间的宽窄依赖。遇到宽依赖就划分stage,每个stage包含一个或多个task任务。然后将这些task以taskSet的形式提交给TaskScheduler运行。 stage是由一组并行的task组成。

(1) 窄依赖(narrow dependencies)
可以支持在同一个集群Executor上,以pipeline管道形式顺序执行多条命令,例如在执行了map后,紧接着执行filter。分区内的计算收敛,不需要依赖所有分区的数据,可以并行地在不同节点进行计算。所以它的失败恢复也更有效,因为它只需要重新计算丢失的parent partition即可
(2)宽依赖(shuffle dependencies)
则需要所有的父分区都是可用的,必须等RDD的parent partition数据全部ready之后才能开始计算,可能还需要调用类似MapReduce之类的操作进行跨节点传递。从失败恢复的角度看,shuffle dependencies 牵涉RDD各级的多个parent partition。

划分完stage之后,同一个stage里面只有窄依赖,没有宽依赖,可以实现流水线计算,stage中的每一个分区对应一个task,同一个stage中就有很多可以并行运行的task

RDD操作类型

Spark中的操作大致可以分为创建操作、转换操作、控制操作和行为操作。

  • 创建操作(Creation Operation):用于RDD创建工作。RDD创建只有两种方法,一种是来自于内存集合和外部存储系统,另一种是通过转换操作生成的RDD。
  • 转换操作(Transformation Operation):将RDD通过一定的操作转变成新的RDD,RDD的转换操作是惰性操作,它只是定义了一个新的RDD,并没有立即执行。
  • 控制操作(Control Operation):进行RDD持久化,可以让RDD按不同的存储策略保存在磁盘或者内存中,比如cache接口默认将RDD缓存在内存中。
  • 行动操作(Action Operation):能够触发Spark运行的操作。Spark中行动操作分为两类,一类操作输出计算结果,另一类将RDD保存到外部文件系统或者数据库中。

1、创建操作

目前有两种类型的基础RDD:

并行集合接收一个已经存在的集合,然后进行并行计算。

外部存储:在一个文件的每条记录上运行函数。只要文件系统是HDFS,或者Hadoop支持的任意存储系统即可。

这两种类型的RDD都可以通过相同的方式进行操作,从而获得子RDD等一系列拓形成血统关系图。

2、控制操作

Spark可以将RDD持久化到内存或磁盘文件系统中,把RDD持久化到内存中可以极大地提高迭代计算以及各计算模型之间的数据共享,一般情况下执行节点60%内存用于缓存数据,剩下的40%用于运行任务。Spark中使用persist和cache操作进行持久化,其中cache是persist()的特例。

3、转换操作-Transformation算子

Transformation

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

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

reduceBykey(func,[numTasks]): 类似groupBykey,但是每一个key对应的value会根据提供的func进行计算以得到一个新的值。

join(otherDataset,[numTasks]):(K,W),返回(K,(V, W))同时支持leftOuterJoin,rightOutJoin,和fullOuterJoin。

4、行动操作– Action算子

reduce(func):根据函数聚合数据集里的元素。

collect():一般在filter或者足够小的结果的时候,再用collect封装返回一个数组。

count():统计数据集中元素个数。

first():获取数据集第一个元素。

take(n):获取数据集最上方的几个元素,返回—个数组。

saveAsTextFile(path):把dataset写到一个textfile中,或者HDFS,Spark把每条记录都转换为一行记录,然后写到file中。

DataFrame概念

与RDD类似,DataFrame也是一个不可变弹性分布式数据集。除了数据以外,还记录数据的结构信息,即schema。类似二维表格。

DataFrame的查询计划可以通过Spark Catalyst Optimiser进行优化,即使Spark经验并不丰富,用Dataframe写得程序也可以尽量被转化为高效的形式予以执行。

DataSet概念

Dataframe是Dataset的特例,DataFrame=Dataset[Row],所以可以通过as方法将Dataframe转换为Dataset。Row是一个通用的类型,所有的表结构信息都用Row来表示。

DataSet是强类型的,可以有Dataset[Car],Dataset[Person]等。

DataFrame、DataSet、RDD表现形式的区别

如上图所示,对RDD中的数据它是不知道类型,也不知道结构。对于DataFrame中的数据,我们知道结构,但是我们并不知道这种结构下对应的数据是什么类型。比如说这里面的张三,他是一个字符串,但是dDataFrame在编译的时候并不知道张三是一个字符串,我们只有取出来了进行转换之后,才变成了字符串。因此在编译的时候,DataFrame容易出错。再看Dataset中的每一个记录都是有类型的,因此在编译的时候能够去发现一些错误。比如说我们对这里的字符串进行减法操作,DataFrame就不能够发现,但是对于Dataset就能够发现。因为DataFrame和Dataset它具有结构性,因此它能够使用spark SQL中的优化操作,能够对执行的流程进行优化。即使我们对spark不是非常熟悉,也可以写出了非常高效的spark语句。


三、Spark原理与架构

Spark体系架构

在spark中,spark库是居于核心地位的。spark库是类似于MapReduce一种分布式的内存计算架构,其中的Standalone支持单独的资源管理调度,也支持Yarn或者Mesos的资源管理调度。在Spark库之上有Spark SQL。Spark SQL是用于处理结构化数据以及SQL查询的一种工具,Spark Streaming是叫做vp处理,它将流数据划分成了vp,然后就有spark库进行分析处理,MLlib和GraphX是spark的机器学习库以及图学习库。另外Structured Streaming这个融入了Flume的一些特性,提升了spark的流处理的特性。我们可以认为是Structured 是Spark Streaming的提升。

典型案例-WordCount

Word Count 顾名思义就是对单词进行计数,首先会对文件中的单词做统计计数,然后输出出现次数最多的 单词。

单词计数是最简单也是最能体现MapReduce思想的程序之一,可以称为MapReduce版"Hello World",该程序的完整代码可以在Hadoop安装包的"src/examples"目录下找到。单词计数主要完成功能是:统计一系列文本文件中每个单词出现的次数

分别通过map和reduce方法统计文本中每个单词出现的次数,然后按照字母的顺序排列输出,Map过程首先是多个map并行提取多个句子里面的单词然后分别列出来每个单词,出现次数为1,全部列举出来。

Reduce过程首先将相同key的数据进行查找分组然后合并,比如对于key为Hello的数据分组为:<Hello, 1>、<Hello,1>、<Hello,1>,合并之后就是<Hello,1+1+1>,分组也可以理解为reduce的操作,合并减少数据时reduce的主要任务,叠加运算之后就是<Hello, 3>所以最后可以输出Hello 3,这样就完成了一轮MapReduce处理。

Spark SQL概述

Spark SQL是Spark中用于结构化数据处理的模块。在Spark应用中,可以无缝的使用SQL语句亦或是DataFrame API对结构化数据进行查询。

Spark SQL vs Hive区别:

Spark SQL的执行引擎为Spark core,Hive默认执行引擎为MapReduce。

Spark SQL的执行速度是Hive的10-100倍

 Spark SQL不支持buckets,Hive支持。

联系:

Spark SQL依赖Hive的元数据。

Spark SQL兼容绝大部分Hive的语法和函数。

Spark SQL可以使用Hive的自定义函数。

Structured Streaming概述

Structured Streaming是构建在Spark SQL引擎上的流式数据处理引擎。可以像使用静态RDD数据那样编写流式计算过程。当流数据连续不断的产生时,Spark sQL将会增示的、持续不断的处理这些数据,并将结果更新到结果集中。

如上图所示structured streaming的计算流程。structured streaming将流数据看作成无界表新的记录,当新的数据产生时是structured streaming将新的数据作为无界表新的行。那么structured streaming将新的数据当作了静态的RDD一样的利用spark sql所提供的api进行了分析处理。

接下来我们看一个structured streaming的计算模型示例。这里我们采用了nc输入数据,在1时刻我们输入的数据就变成了dataframe。对这个dataframe进行分析处理得到一个结果,在2时刻又输入了新的数据,那这个新的数据也插不到这个所谓的无界表中,产生新的数据。在3时刻又增加了两个单词,也是插入到这个无界表中产生新的结果。structure streaming它引入一个特征状态。当随着数据数据增加的时候,它计算出来的结果会合并先前的计算结果,产生最终的计算结果。

Spark Streaming概述

Spark Streaming的基本原理是将实时输入数据流以时间片(秒级)为单位进行拆分,然后经Spark引擎以类似批处理的方式处理每个时间片数据。

Spark Streaming类似于Apache Storm,用于流式数据的处理。Spark Streaming有高吞吐量和容错能力强等特点,而且Spark Streaming易用、容错、易整合到Spark体系 。Spark Streaming支持的数据输入源很多,例如:Kafka、Flume、Twitter、ZeroMQ和简单的TCP套接字等等。数据输入后可以用Spark的高度抽象原语如:map、reduce、join、window等进行运算。而结果也能保存在很多地方,如HDFS,数据库等。另外Spark Streaming也能和MLlib(机器学习)以及Graphx完美融合。

Spark Streaming使用离散化流(discretized stream)作为抽象表示,叫作DStream。DStream 是随时间推移而收到的数据的序列。在内部,每个时间区间收到的数据都作为 RDD 存在,而 DStream 是由这些 RDD 所组成的序列(因此 得名“离散化”)。

窗口在Dstream上滑动,合并和操作落入窗口内的RDDs,产生窗口化的RDDs;

窗口长度:窗口的持续时间

滑动窗口间隔:窗口操作执行的时间间隔

Spark Streaming vs Storm

从流式数据处理的角度上来说,Spark Streaming与Storm存在一些差距。比如说Storm是一个真正的纯实时的流处理引擎,处理的速度可以达到了毫秒级。另外Storm支持了完善的事务机制,但是Spark Streaming对事物机制支撑不够完善。如果说针对一些场景要求,流数据的处理不多不少,我们需要使用Storm,对一些小型规模的公司来说,大数据资源是有限的,因此我们需要动态的调整的并行度,Storm也可以很好的支撑这种应用场景。对于Spark Streaming来说,它最大的优势是它产生于了spark的生态圈,它可以无缝的与Spark 以及Spark SQL进行的连接。对于软件产生出来的实时数据可以无缝的批处理,以及spark sql进行查询分析。


总结

本章节主要介绍了Spark的基本概念、技术架构,涉及SparkSQL、 StructuredStreaming、Spark Streaming多个组件基本功能。

学习推荐

华为Learning网站: https://support.huawei.cn/learning

华为e学云: https://support.huawei.cn/learning/elearning

华为Support案例库:https://support.huawei.cn/enterprise

本文整理自华为云社区【内容共创系列】活动。
查看活动详情:https://bbs.huaweicloud.cn/blogs/314887
相关任务详情:Spark基于内存的分布式计算

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。