设为首页 加入收藏

TOP

Spark系列1 - Spark生态和RDD
2019-02-12 01:25:18 】 浏览:25
Tags:Spark 系列 生态 RDD

1 Spark的生态

1700062-09a7160fcde09a12.png
Spark生态

Spark Core中的基本概念

  • DAG(Directed Acyclic Graph), 有向无环图。Spark Core提供了有向无环图的分布式计算框架,并提供内存机制来支持多次迭代计算或者数据共享,大大减少了迭代计算之间读取数据的开销。
  • RDD(Resilient Distributed Dataset),它是一个分布在一组节点中的只读对象集合,这些集合是弹性的,如果数据集一部分丢失,则可以根据“血统”对他们进行重建,保证了数据的高容错性。
  • RDD Partition,RDD分区。RDD Partition可以就近读取分布式文件系统中的数据块到各个节点的内存。(是否类似Hadoop的Block,读取数据时也有就近读取的特性?

Spark Streaming

Spark Streaming是一个对实时数据流进行高吞吐、高容错的流式处理系统,可以对多种数据源(如:消息队列Kafka、Flume、ZeroMQ等)进行类似Map、Reduce和Join等复杂操作,并将结果保存到外部文件系统、数据库或者实时仪表盘。Spark Streaming最大的优势就是提供的处理引擎和RDD编程模型可以同时进行批处理和流处理

1700062-8c2db0b58efb9f36.png
Spark Streaming

对于传统流处理一次处理一条记录的方式而言,Spark Streaming使用的是将流数据离散化处理(Discretized Streams)。流数据离散化的好处有三:① 实现了动态的负载均衡,②有利于快速的故障恢复,③将批处理、流处理和交互式工作有效的组合了起来。

1700062-2f034ee1e5dce9a8.png
spark streaming

Spark SQL

Spark SQL的前生是Shark,即Hive on Spark。Shark本质是通过Hive的HQL进行解析,将HQL翻译成Spark上对应的RDD操作,然后通过Hive的Metadata获取数据数据库里的表信息,实际上为HDFS上的数据和文件,最后由Shark获取并放到Spark上运算。
2014年7月,Databricks宣布终止对Shark的开发,将重点放到Spark SQL上。Spark SQL允许开发人员可以直接操作RDD,同时也可查询在Hive上存放的外部数据,因此Spark SQL在使用SQL进行外部查询的同时,也能进行更复杂的数据分析。
引入了SchemaRDD。SchemaRDD既可以从RDD转换过来,也可以从Parquet文件读入,还可以使用HiveQL从Hive中获取。

BlinkDB

BlinkDB是一个用于在海量数据上运行交互式SQL查询的大规模并行查询引擎,它允许用户通过权衡数据精度提升查询响应时间,其数据的精度被控制在允许的误差范围内。BlinkDB架构如下图所示。

1700062-3d4b3458fbd182f9.png
BlinkDB架构

MLBase/MLlib

MLBase是Spark生态系统中专注于机器学习的组件。MLBase主要有ML optimizer、MLI、MLlib、Spark/MLRuntime组成,其结构如下图所示。


1700062-516b60f7fa9e8ed4.png
ML Base结构

GraphX

GraphX是Spark中用于图和图并行计算的API。

SparkR

R是遵循GNU协议的一款开源、免费的软件,广泛应用于统计计算和统计制图,但是它只能单机运行。为了能够使用R语言分析大规模分布式的数据,伯克利分销AMP实验室开发了SparkR,并在Spark1.4版本中加入了该组件。

Alluxio

Alluxio以内存为中心分布式存储系统,从下图可以看出, Alluxio主要有两大功能,第一提供一个文件系统层的抽象,统一文件系统接口,桥接储存系统和计算框架;第二通过内存实现对远程数据的加速访问。

1700062-9a2d24c5a3b6a15e.png
Alluxio

2 Spark的相关术语和概念

RDD

① RDD的创建
RDD的创建有三种方法:① 来自一个内存中的对象集合;② 使用外部存储器中的数据集;③ 对现有的RDD进行转换。

② 转换和动作
Spark为RDD提供两大类操作:转换(Transformation)和动作(Action)。转换是从现有的RDD生成新的RDD,而动作则触发对RDD的计算并对计算结果执行某种操作,要么返回给用户,要么保存到外部储存器中。
动作的效果是立杆见影的,但转换是惰性的。转换过程不会触发任何行动,而只有动作才会触发之前的转换和执行动作本身。
区分动作和转换的方法:判断操作的返回类型,若返回类型是RDD,则该操作是转换,否则就是一个动作。

聚合转换

  • reduceByKey(),它为键值对中的值重复应用一个二进制函数,直至产生一个结果值,不能改变集合之后值的类型。
  • foldByKey(),和reduceByKey()的功能相似,但必须要提供一个默认的值;
  • aggregateByKey(),可以改变值的类型,如从Integer转变成set。

③ 持久化

  • 将RDD缓存到内存,且被缓存的RDD只能由同一个应用的作业来读取,如果要在应用之间共享数据,则能将数据持久化到外部存储上了。
  • 持久化级别:MEMORY_ONLY,MEMORY_ONLY_SER(默认使用Java的内部序列化机制,Kryo序列化方法通常更好序列化方法),MEMORY_AND_DISK(如果数据操作一定的大小,将溢出到磁盘),MEMORY_AND_DISK_SER等。

④ 序列化
使用Spark时,要从两个方面考虑序列化,分别是数据序列化(数据序列化一般使用)和函数序列化(使用java序列化机制);

⑤ RDD应用

迭代计算:如图形处理、数值优化和机器学习等;
交互式SQL查询:如SparkSQL;
MapReduceRDD:通过提供MapReduce的超级,实现高效的执行MapReduce程序;
流式数据处理:Spark中提出的离散数据流D-Stream,将流式计算的执行,当作一些列短而确定的一系列批量计算的序列,并将状态保存在RDD中。

RDD之间的依赖关系

RDD中的依赖关系分为窄依赖(Narrow Dependency)和宽依赖(Wide Dependency),二者的主要区别在于是否包含Shuffle操作

Shuffle操作是指对Map输出结果进行分区、排序和归并等处理后并较给Reduce处理的过程。尽管Spark是基于内存的分布式计算框架,但是Spark的Shuffle操作也会把数据写入到磁盘中。

窄依赖表现为一个父RDD的分区对应一个子RDD的分区,或多个父RDD分区对应一个子RDD分区。宽依赖表现为存在一个父RDD的分区对应一个子RDD的多个分区。

总结:如果父RDD的一个分区只被一个子RDD的分区所使用,该依赖就是窄依赖,否则就是宽依赖。

窄依赖典型的操作:map、filter、union、协同jion;
宽依赖典型的操作:groupByKey、sortByKey、非协同jion;

Spark通过分析各个RDD之间的依赖关系生成了DAG,DAG提交给DAGScheduler,DAGScheduler再通过分析各个RDD中分区之间的依赖关系来决定如何划分阶段,每个阶段包括一个或者多个任务,这些任务形成任务集,最后将该任务集合提交给TaskScheduler执行。Phase的具体划分方法是:在DAG中进行反向解析,遇到宽依赖就断开(因为只有窄依赖可以实现流水线优化),遇到窄依赖就把当前RDD加入到当前的阶段中。参考论文:A Fault-Tolerant Abstraction for In-Memory Cluster Computing

DAGScheduler记录哪些RDD被存入磁盘等物化动作,同时要寻求任务的最优调度、监控运行调度阶段过程等。如果某个调度阶段运行失败,则需要重新提交该调度阶段。

其他

  • Application/Job/Stage/Task
    Spark的Job是由任意的多阶段(Stages)有向无环图(DAG)构成,每个Stage相当于MapReduce的Map阶段或者Reduce阶段。这些阶段又被Spark运行环境分解为多个任务(Task),任务并行运行在分布于集群中的RDD分区上,就像MapReduce的任务一样。
    Spark的Job始终运行在应用(application)上下文(SparkContext)中,它提供了RDD分组以及共享变量。一个应用可以串行或者并行的执行多个作业,并为这些作业提供访问由先前作业所缓存的RDD。
  • SparkContext,Spark运行的上下文;
  • SparkConf

参考

  • 《图解Spark-核心技术与案例实战》
  • 《Hadoop权威指南》
  • 《Spark编程基础 scala版》

编程开发网
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇spark streaming 集成kafka0.10 o.. 下一篇Spark机器学习过程梳理

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

array(4) { ["type"]=> int(8) ["message"]=> string(24) "Undefined variable: jobs" ["file"]=> string(32) "/mnt/wp/cppentry/do/bencandy.php" ["line"]=> int(214) }