Spark 的笔记


## Spark是什么


Apache Spark:一种快速,通用引擎用于大规模数据处理,Spark是一个数据并行通用批量处理引擎。工作流中在一个类似的和怀旧风格的MapReduce中定义,但是,比传统Hadoop MapReduce的更能干。Apache Spark有其流API项目,该项目通过短间隔批次允许连续处理。Apache Spark本身并不需要Hadoop操作。但是,它的数据并行模式,需要稳定的数据优化使用共享文件系统。该稳定源的范围可以从S3,NFS或更典型地,HDFS。执行Spark应用程序并不需要Hadoop YARN。Spark有自己独立的主/服务器进程。然而,这是共同的运行使用YARN容器Spark的应用程序。此外,Spark还可以在Mesos集群上运行。运行在内存中。

 

## Spark有什么

 

 

spark 可以用来干什么 spark用来做什么_数据

 

## Spark RDD是什么

 

RDD(Resilient Distributed Datasets,弹性分布式数据集)是一个分区的只读记录的集合。RDD只能通过在稳定的存储器或其他RDD的数据上的确定性操作来创建。我们把这些操作称作变换以区别其他类型的操作。例如map,filter和join。 


RDD 五大特性

 

1、一个RDD由多个分区组成(partitinons)

2、并行计算

3、向上依赖,容错

4、重新分区  (可选)

5、最优的计算,找到最优的位置 (可选)

## Spark的几种运行模式


1、Spark On Local

  此种模式下,我们只需要在安装Spark时不进行hadoop和Yarn的环境配置,只要将Spark包解压即可使用,运行时Spark目录下的bin目录执行bin/spark-shell即可

    具体可参考这篇博客:

2、Spark Standalone

tandalone模式是Spark实现的资源调度框架,其主要的节点有Client节点、Master节点和Worker节点。其中Driver既可以运行在Master节点上中,也可以运行在本地Client端。当用spark-shell交互式工具提交Spark的Job时,Driver在Master节点上运行;当使用spark-submit工具提交Job或者在Eclips、IDEA等开发平台上使用”new SparkConf.setManager(“spark://master:7077”)”方式运行Spark任务时,Driver是运行在本地Client端上的。

       

spark 可以用来干什么 spark用来做什么_Spark RDD noYarn_02

    其运行过程如下:

    1.SparkContext连接到Master,向Master注册并申请资源(CPU Core 和Memory);

    2.Master根据SparkContext的资源申请要求和Worker心跳周期内报告的信息决定在哪个Worker上分配资源,然后在该Worker上获取资源,然后启动StandaloneExecutorBackend;

    3.StandaloneExecutorBackend向SparkContext注册;

    4.SparkContext将Applicaiton代码发送给StandaloneExecutorBackend;并且SparkContext解析Applicaiton代码,构建DAG图,并提交给DAG Scheduler分解成Stage(当碰到Action操作时,就会催生Job;每个Job中含有1个或多个Stage,Stage一般在获取外部数据和shuffle之前产生),然后以Stage(或者称为TaskSet)提交给Task Scheduler,Task Scheduler负责将Task分配到相应的Worker,最后提交给StandaloneExecutorBackend执行;

    5.StandaloneExecutorBackend会建立Executor线程池,开始执行Task,并向SparkContext报告,直至Task完成。

    6.所有Task完成后,SparkContext向Master注销,释放资源。

 

   3、Spark On Yarn

 

的结合,都必须遵循YARN的开发模式。在分析Spark on YARN的实现细节之前,有必要先分析一下YARN框架的一些基本原理。Yarn框架的基本流程如下:

       

spark 可以用来干什么 spark用来做什么_spark 可以用来干什么_03

  

负责将集群的资源分配给各个应用使用,而资源分配和调度的基本单位是Container,其中封装了机器资源,如内存、CPU、磁盘和网络等,每个任务会被分配一个Container,该任务只能在该Container中执行,并使用该Container封装的资源。NodeManager是一个个的计算节点,主要负责启动Application所需的Container,监控资源(内存、CPU、磁盘和网络等)的使用情况并将之汇报给ResourceManager。ResourceManager与NodeManagers共同组成整个数据计算框架,ApplicationMaster与具体的Application相关,主要负责同ResourceManager协商以获取合适的Container,并跟踪这些Container的状态和监控其进度。


1、Yarn Client模式 

模式中,Driver在客户端本地运行,这种模式可以使得Spark Application和客户端进行交互,因为Driver在客户端,所以可以通过webUI访问Driver的状态,默认是http://hadoop1:4040访问,而YARN通过http:// hadoop1:8088访问。

的工作流程分为以下几个步骤:

         

spark 可以用来干什么 spark用来做什么_应用程序_04

       (1).Spark Yarn Client向YARN的ResourceManager申请启动Application Master。同时在SparkContent初始化中将创建DAGScheduler和TASKScheduler等,由于我们选择的是Yarn-Client模式,程序会选择YarnClientClusterScheduler和YarnClientSchedulerBackend;

         (2).ResourceManager收到请求后,在集群中选择一个NodeManager,为该应用程序分配第一个Container,要求它在这个Container中启动应用程序的ApplicationMaster,与YARN-Cluster区别的是在该ApplicationMaster不运行SparkContext,只与SparkContext进行联系进行资源的分派;

       (3).Client中的SparkContext初始化完毕后,与ApplicationMaster建立通讯,向ResourceManager注册,根据任务信息向ResourceManager申请资源(Container);

          (4).一旦ApplicationMaster申请到资源(也就是Container)后,便与对应的NodeManager通信,要求它在获得的Container中启动启动CoarseGrainedExecutorBackend,CoarseGrainedExecutorBackend启动后会向Client中的SparkContext注册并申请Task;

        (5).Client中的SparkContext分配Task给CoarseGrainedExecutorBackend执行,CoarseGrainedExecutorBackend运行Task并向Driver汇报运行的状态和进度,以让Client随时掌握各个任务的运行状态,从而可以在任务失败时重新启动任务;

          (6).应用程序运行完成后,Client的SparkContext向ResourceManager申请注销并关闭自己

2、Spark Cluster模式

模式中,当用户向YARN中提交一个应用程序后,YARN将分两个阶段运行该应用程序:第一个阶段是把Spark的Driver作为一个ApplicationMaster在YARN集群中先启动;第二个阶段是由ApplicationMaster创建应用程序,然后为它向ResourceManager申请资源,并启动Executor来运行Task,同时监控它的整个运行过程,直到运行完成。

的工作流程分为以下几个步骤:

        

spark 可以用来干什么 spark用来做什么_应用程序_05

         (1).   Spark Yarn Client向YARN中提交应用程序,包括ApplicationMaster程序、启动ApplicationMaster的命令、需要在Executor中运行的程序等;

        (2).   ResourceManager收到请求后,在集群中选择一个NodeManager,为该应用程序分配第一个Container,要求它在这个Container中启动应用程序的ApplicationMaster,其中ApplicationMaster进行SparkContext等的初始化;

         (3).   ApplicationMaster向ResourceManager注册,这样用户可以直接通过ResourceManage查看应用程序的运行状态,然后它将采用轮询的方式通过RPC协议为各个任务申请资源,并监控它们的运行状态直到运行结束;

         (4).   一旦ApplicationMaster申请到资源(也就是Container)后,便与对应的NodeManager通信,要求它在获得的Container中启动启动CoarseGrainedExecutorBackend,CoarseGrainedExecutorBackend启动后会向ApplicationMaster中的SparkContext注册并申请Task。这一点和Standalone模式一样,只不过SparkContext在Spark Application中初始化时,使用CoarseGrainedSchedulerBackend配合YarnClusterScheduler进行任务的调度,其中YarnClusterScheduler只是对TaskSchedulerImpl的一个简单包装,增加了对Executor的等待逻辑等;

         (5).   ApplicationMaster中的SparkContext分配Task给CoarseGrainedExecutorBackend执行,CoarseGrainedExecutorBackend运行Task并向ApplicationMaster汇报运行的状态和进度,以让ApplicationMaster随时掌握各个任务的运行状态,从而可以在任务失败时重新启动任务;

         (6).   应用程序运行完成后,ApplicationMaster向ResourceManager申请注销并关闭自己。

3、Spark Client 和 Spark Cluster的区别

和YARN-Cluster深层次的区别之前先清楚一个概念:Application Master。在YARN中,每个Application实例都有一个ApplicationMaster进程,它是Application启动的第一个容器。它负责和ResourceManager打交道并请求资源,获取资源之后告诉NodeManager为其启动Container。从深层次的含义讲YARN-Cluster和YARN-Client模式的区别其实就是ApplicationMaster进程的区别。

  YARN-Cluster模式下,Driver运行在AM(Application Master)中,它负责向YARN申请资源,并监督作业的运行状况。当用户提交了作业之后,就可以关掉Client,作业会继续在YARN上运行,因而YARN-Cluster模式不适合运行交互类型的作业;

  YARN-Client模式下,Application Master仅仅向YARN请求Executor,Client会和请求的Container通信来调度他们工作,也就是说Client不能离开。

                

spark 可以用来干什么 spark用来做什么_数据集_06


##  Spark的Transform与Action操作

 

注意:在没有执行action 之前在其中一个算了失败 ,RDD 的向上依赖找到再重新计算。如果执行了 actiion 之后,在在其中一个算了失败要重头开始计算。
 
RDD 两个操作 :
Each RDD has 2 sets of parallel operations: transformation and action.
(1)Transformation:Return a MappedRDD[U] by applying function f to each element
(2)Action:return T by reducing the elements using specified commutative and associative binary operator
 
transformation:

Transformation

Meaning

 

map(func)

Return a new distributed dataset formed by passing each element of the source through a function func.

对调用map的RDD数据集中的每个element都使用func,然后返回一个新的RDD,这个返回的数据集是分布式的数据集 

 

filter(func)

Return a new dataset formed by selecting those elements of the source on which funcreturns true.

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

 

flatMap(func)

Similar to map, but each input item can be mapped to 0 or more output items (so funcshould return a Seq rather than a single item).

和map差不多,但是flatMap生成的是多个结果,返回值是一个Seq

 

mapPartitions(func)

Similar to map, but runs separately on each partition (block) of the RDD, so func must be of type Iterator<T> => Iterator<U> when running on an RDD of type T.

和map很像,但是map是每个element,而mapPartitions是每个partition

 

mapPartitionsWithIndex(func)

Similar to mapPartitions, but also provides func with an integer value representing the index of the partition, so func must be of type (Int, Iterator<T>) => Iterator<U> when running on an RDD of type T.

和mapPartitions很像,但是func作用的是其中一个split上,所以func中应该有index  

 

sample(withReplacement, fraction, seed)

Sample a fraction fraction of the data, with or without replacement, using a given random number generator seed.

抽样

 

union(otherDataset)

Return a new dataset that contains the union of the elements in the source dataset and the argument.

返回一个新的dataset,包含源dataset和给定dataset的元素的集合 

 

intersection(otherDataset)

Return a new RDD that contains the intersection of elements in the source dataset and the argument.

 

distinct([numTasks]))

Return a new dataset that contains the distinct elements of the source dataset.

返回一个新的dataset,这个dataset含有的是源dataset中的distinct的element  

 

groupByKey([numTasks])

When called on a dataset of (K, V) pairs, returns a dataset of (K, Iterable<V>) pairs. 
Note: If you are grouping in order to perform an aggregation (such as a sum or average) over each key, using reduceByKey or aggregateByKey will yield much better performance. 
Note: By default, the level of parallelism in the output depends on the number of partitions of the parent RDD. You can pass an optional numTasks argument to set a different number of tasks.

返回(K,Seq[V]),也就是hadoop中reduce函数接受的key-valuelist  

 

reduceByKey(func, [numTasks])

When called on a dataset of (K, V) pairs, returns a dataset of (K, V) pairs where the values for each key are aggregated using the given reduce function func, which must be of type (V,V) => V. Like in groupByKey, the number of reduce tasks is configurable through an optional second argument.

就是用一个给定的reduce func再作用在groupByKey产生的(K,Seq[V]),比如求和,求平均数  

 

aggregateByKey(zeroValue)(seqOp, combOp, [numTasks])

When called on a dataset of (K, V) pairs, returns a dataset of (K, U) pairs where the values for each key are aggregated using the given combine functions and a neutral "zero" value. Allows an aggregated value type that is different than the input value type, while avoiding unnecessary allocations. Like in groupByKey, the number of reduce tasks is configurable through an optional second argument.

 

sortByKey([ascending], [numTasks])

When called on a dataset of (K, V) pairs where K implements Ordered, returns a dataset of (K, V) pairs sorted by keys in ascending or descending order, as specified in the boolean ascending argument.

按照key来进行排序,是升序还是降序,ascending是boolean类型  

 

join(otherDataset, [numTasks])

When called on datasets of type (K, V) and (K, W), returns a dataset of (K, (V, W)) pairs with all pairs of elements for each key. Outer joins are supported through leftOuterJoin,rightOuterJoin, and fullOuterJoin.

当有两个KV的dataset(K,V)和(K,W),返回的是(K,(V,W))的dataset,numTasks为并发的任务数  

 

cogroup(otherDataset, [numTasks])

When called on datasets of type (K, V) and (K, W), returns a dataset of (K, (Iterable<V>, Iterable<W>)) tuples. This operation is also called groupWith.

当有两个KV的dataset(K,V)和(K,W),返回的是(K,Seq[V],Seq[W])的dataset,numTasks为并发的任务数  

 

cartesian(otherDataset)

When called on datasets of types T and U, returns a dataset of (T, U) pairs (all pairs of elements).

笛卡尔积就是m*n

 

pipe(command, [envVars])

Pipe each partition of the RDD through a shell command, e.g. a Perl or bash script. RDD elements are written to the process's stdin and lines output to its stdout are returned as an RDD of strings.

 

coalesce(numPartitions)

Decrease the number of partitions in the RDD to numPartitions. Useful for running operations more efficiently after filtering down a large dataset.

 

repartition(numPartitions)

Reshuffle the data in the RDD randomly to create either more or fewer partitions and balance it across them. This always shuffles all data over the network.

 

repartitionAndSortWithinPartitions(partitioner)

Repartition the RDD according to the given partitioner and, within each resulting partition, sort records by their keys. This is more efficient than calling repartition and then sorting within each partition because it can push the sorting down into the shuffle machinery.

 

Action:

Action

Meaning

reduce(func)

Aggregate the elements of the dataset using a function func (which takes two arguments and returns one). The function should be commutative and associative so that it can be computed correctly in parallel.

说白了就是聚集,但是传入的函数是两个参数输入返回一个值,这个函数必须是满足交换律和结合律的  

collect()

Return all the elements of the dataset as an array at the driver program. This is usually useful after a filter or other operation that returns a sufficiently small subset of the data.

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

count()

Return the number of elements in the dataset. 返回的是dataset中的element的个数  

first()

Return the first element of the dataset (similar to take(1)). 返回的是dataset中的第一个元素 

take(n)

Return an array with the first n elements of the dataset. 返回前n个elements,这个士driver program返回的 

takeSample(withReplacement,num, [seed])

Return an array with a random sample of num elements of the dataset, with or without replacement, optionally pre-specifying a random number generator seed. 抽样返回一个dataset中的num个元素,随机种子seed  

takeOrdered(n, [ordering])

Return the first n elements of the RDD using either their natural order or a custom comparator.

saveAsTextFile(path)

Write the elements of the dataset as a text file (or set of text files) in a given directory in the local filesystem, HDFS or any other Hadoop-supported file system. Spark will call toString on each element to convert it to a line of text in the file. 把dataset写到一个text file中,或者hdfs,或者hdfs支持的文件系统中,spark把每条记录都转换为一行记录,然后写到file中  

saveAsSequenceFile(path) 
(Java and Scala)

Write the elements of the dataset as a Hadoop SequenceFile in a given path in the local filesystem, HDFS or any other Hadoop-supported file system. This is available on RDDs of key-value pairs that implement Hadoop's Writable interface. In Scala, it is also available on types that are implicitly convertible to Writable (Spark includes conversions for basic types like Int, Double, String, etc). 只能用在key-value对上,然后生成SequenceFile写到本地或者hadoop文件系统  

saveAsObjectFile(path) 
(Java and Scala)

Write the elements of the dataset in a simple format using Java serialization, which can then be loaded usingSparkContext.objectFile().

countByKey()

Only available on RDDs of type (K, V). Returns a hashmap of (K, Int) pairs with the count of each key. 返回的是key对应的个数的一个map,作用于一个RDD  

foreach(func)

Run a function func on each element of the dataset. This is usually done for side effects such as updating anAccumulator or interacting with external storage systems. 
Note: modifying variables other than Accumulators outside of the foreach() may result in undefined behavior. See Understanding closures for more details. :对dataset中的每个元素都使用func

 

##  RDD的宽依赖与窄依赖

 

spark 可以用来干什么 spark用来做什么_应用程序_07

1、上面图是一个job的运行。

2、三个宽依赖分别三个stage,窄依赖不产生stage。

3、每个管道(Pipeline)是一个task

4、根据算子来判断宽窄依赖。

好处:

1、减少IO,与网络

2、DAG的优化

3、为什么A要先产生一个B,而不是直接与F一起join。

一)先产生一个B,可以做缓存。

二)如果没有的话。7X3的shuffle.这样的话如查有一个失败,就会从重计算。

三)产生一个B的话。先3X3,4X3的两个shuffle,如果有一个失败,只要从其他一个shuffle计算。

 

##  Cluster Overview


Spark : 先申请资源再运行。    MR:边运行边申请资源。


 

spark 可以用来干什么 spark用来做什么_spark 可以用来干什么_08


步骤:1、Drive先向Master申请是否有资源可用。

、Master再向所有WorkerNode询问后,拿到空闲的资源列表返回给Drive。

拿到后。就向WorkeNode申请资源。启动一个进程Exeutor,Exeutor返回告诉SparkContext  我是WorkeNode启动的应用,可以与我交付了。

接下就SparkContext执行对应的业务逻辑了。这里就会在Exeutor中产生多个Task的线程运行。