Spark Streaming是一个对实时数据流进行高吞吐、高容错的流式处理系统,可以对多种数据源(如:消息队列Kafka、Flume、ZeroMQ等)进行类似Map、Reduce和Join等复杂操作,并将结果保存到外部文件系统、数据库或者实时仪表盘。Spark Streaming最大的优势就是提供的处理引擎和RDD编程模型可以同时进行批处理和流处理。
对于传统流处理一次处理一条记录的方式而言,Spark Streaming使用的是将流数据离散化处理(Discretized Streams)。流数据离散化的好处有三:① 实现了动态的负载均衡,②有利于快速的故障恢复,③将批处理、流处理和交互式工作有效的组合了起来。
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是一个用于在海量数据上运行交互式SQL查询的大规模并行查询引擎,它允许用户通过权衡数据精度提升查询响应时间,其数据的精度被控制在允许的误差范围内。BlinkDB架构如下图所示。
MLBase是Spark生态系统中专注于机器学习的组件。MLBase主要有ML optimizer、MLI、MLlib、Spark/MLRuntime组成,其结构如下图所示。
GraphX是Spark中用于图和图并行计算的API。
R是遵循GNU协议的一款开源、免费的软件,广泛应用于统计计算和统计制图,但是它只能单机运行。为了能够使用R语言分析大规模分布式的数据,伯克利分销AMP实验室开发了SparkR,并在Spark1.4版本中加入了该组件。
Alluxio以内存为中心分布式存储系统,从下图可以看出, Alluxio主要有两大功能,第一提供一个文件系统层的抽象,统一文件系统接口,桥接储存系统和计算框架;第二通过内存实现对远程数据的加速访问。
① RDD的创建
RDD的创建有三种方法:① 来自一个内存中的对象集合;② 使用外部存储器中的数据集;③ 对现有的RDD进行转换。
② 转换和动作
Spark为RDD提供两大类操作:转换(Transformation)和动作(Action)。转换是从现有的RDD生成新的RDD,而动作则触发对RDD的计算并对计算结果执行某种操作,要么返回给用户,要么保存到外部储存器中。
**动作的效果是立杆见影的,但转换是惰性的。**转换过程不会触发任何行动,而只有动作才会触发之前的转换和执行动作本身。
**区分动作和转换的方法:**判断操作的返回类型,若返回类型是RDD,则该操作是转换,否则就是一个动作。
聚合转换
③ 持久化
④ 序列化
使用Spark时,要从两个方面考虑序列化,分别是数据序列化(数据序列化一般使用)和函数序列化(使用java序列化机制);
⑤ RDD应用
迭代计算:如图形处理、数值优化和机器学习等;
交互式SQL查询:如SparkSQL;
MapReduceRDD:通过提供MapReduce的超级,实现高效的执行MapReduce程序;
流式数据处理:Spark中提出的离散数据流D-Stream,将流式计算的执行,当作一些列短而确定的一系列批量计算的序列,并将状态保存在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被存入磁盘等物化动作,同时要寻求任务的最优调度、监控运行调度阶段过程等。如果某个调度阶段运行失败,则需要重新提交该调度阶段。