spark学习笔记

字数 1928阅读 144

概述

Spark 快速通用的集群计算平台
扩充了MapReduce的计算模型
内存计算

包含组件

spark core
spark sql
spark streaming
mlib
GraphX

部署方式

Standalone Deploy Mode: simplest way to deploy Spark on a private cluster
Apache Mesos
Hadoop YARN

集群模式关键概念

Spark应用程序作为独立的进程集合运行在集群上,由主程序(driver program)中的SparkContext对象进行协调。

Spark的应用程序在集群上执行的流程

SparkContext可以连接到多种类型的集群管理器(Spark自己的独立集群管理器,Mesos或YARN),它们跨应用程序分配资源。 一旦连接,Spark将在集群中的节点上获取executors,这些进程可以为应用程序运行计算和存储数据。 接下来,它将您的应用程序代码(由JAR或Python文件传递给SparkContext定义)发送给执行程序。 最后,SparkContext将任务发送给执行程序运行。


Spark cluster components

关注点:
1、Spark应用程序间相互独立,不能跨Spark应用程序共享数据
2、每个Spark应用程序都有他自己的executors,这些executors伴随Spark应用程序的整个生命周期,并通过多线程执行任务(tasks from different applications run in different JVMs)
3、Spark与底层集群管理器无关,只要能获取executors,并且能使其相互间通信就行,甚至这个集群也支持其他应用程序()

关键概念

RDD

RDD:Resilient Distributed Dataset ,弹性分布式数据集
它是一个数据容器,它将分布在集群上各个节点上的数据抽象为一个数据集,并且RDD能够进行一系列的并行计算操作
可以将RDD理解为一个分布式的List,该List的数据为分布在各个节点上的数据
RDDs可以从hadoop文件系统上的文件创建(比如hdfs上存储的文件),也可以从其他RDDs转换获得
RDD有良好的容错机制

共享变量

广播变量(broadcast variables):将一个只读变量缓存到集群的每个节点 上。例如,将一份数据的只读缓存分发到每个节点。
累加变量(accumulators):只允许add操作,用于计数、求和。

Caching

把RDD缓存到内存,提高处理计算效率,用于重复读写的数据

job

就是由一个 rdd 的 action 触发的动作,可以简单的理解为,当你需要执行一个 rdd 的 action 的时候,会生成一个 job。

stage

stage 是一个 job 的组成单位,就是说,一个 job 会被切分成 1 个或 1 个以上的 stage,然后各个 stage 会按照执行顺序依次执行。
一个Job会被拆分为多组Task,每组任务被称为一个Stage就像Map Stage, Reduce Stage。

task

A unit of work that will be sent to one executor
即 stage 下的一个任务执行单元,一般来说,一个 rdd 有多少个 partition,就会有多少个 task,因为每一个 task 只是处理一个 partition 上的数据。
Spark上分为2类task。1.shuffleMapTask 2.resultTask

独立python程序提交spark执行

# Use spark-submit to run your application
$ YOUR_SPARK_HOME/bin/spark-submit \
  --master local[4] \
  SimpleApp.py
...
Lines with a: 46, Lines with b: 23

lambda表达式

匿名函数
lambda 参数:表达式
lambda x,y:x if (x>y) else y 等同于:

def max(x,y):
    if x>y:
        return x
    else:
        return y    

Spark

Spark的所有transformation操作都是懒执行,它们并不立马执行,而是先记录对数据集的一系列transformation操作。在执行一个需要执行一个action操作时,会执行该数据集上所有的transformation操作,然后返回结果。

Spark 外部数据集

scala> val distFile = sc.textFile("data.txt")
distFile: RDD[String] = MappedRDD@1d4cee08

Spark所有的基于文件输入的方法(包括textFile),都支持文件夹、压缩文件、通配符。例如:textFile("/my/directory")、textFile("/my/directory/.txt")、textFile("/my/directory/.gz")。
SparkContext.wholeTextFiles能够读取指定目录下的许多小文本文件,返回(filename,content)对。而textFile只能读取一个文本文件,返回该文本文件的每一行。

Spark应用提交集群运行

https://spark.apache.org/docs/latest/submitting-applications.html

Spark 配置相关

https://spark.apache.org/docs/latest/configuration.html#networking

Spark SQL, DataFrames and Datasets

Spark SQL是用于结构化数据处理的组件,Spark SQL接口为Spark提供更多关于数据和执行计算的结构信息?内部,Spark SQL用这些额外的信息进行额外的优化(与RDD相比),与Spark SQL组件进行交互的方式,SQL 和the Dataset API;
DataSet是Spark1.6版本后提供的一种新的分布式数据集,它提供了RDDs的有点(强类型、强大的Lambda函数功能),同时具备Spark SQL优化执行引擎的优点。DataSet可以从JVM对象构建,然后通过转换函数(map, flatMap, filter, etc.)进行操作,Scala和JAVA中支持DataSet API,Python 不支持;
DataFrame 是组织成列的DataSet,它概念上相当于关系型数据库中的表,但是在Spark SQL引擎下具有更加丰富的优化。DataFrame可以由多种数据源进行构建(structured data files, tables in Hive, external databases, or existing RDDs),DataFrame API 支持Scala, Java, Python, and R, 在Scala和Java中,DataFrame表示DataSet的一行;

RDDs、DataFrames、Datasets比较:

DataFrames和Datasets API在Spark2.0以后进行了统一,如下图:
DataFrames作为Dataset Untyped API


image.png

RDD在Spark2.0以后并没有被废弃,而是作为底层接口,DataSet是建立在RDD之上的,RDD APIs仍然可以继续被开发者使用,何时使用RDD,以下情况可做参考:
*you want low-level transformation and actions and control on your dataset;

*your data is unstructured, such as media streams or streams of text;

*you want to manipulate your data with functional programming constructs than domain specific expressions;

*you don’t care about imposing a schema, such as columnar format, while processing or accessing data attributes by name or column; and

*you can forgo some optimization and performance benefits available with DataFrames and Datasets for structured and semi-structured data.

DataSet的优势

1. Static-typing and runtime type-safety

SQL方式无类型检查,出错成本高
DataFrames API有类型检查,但是知道运行时才会检查列是否存在
Datasets API限制最多,但最安全

image.png

2.对结构化和半结构化数据的高层次抽象和自定义视图

3. 易用的API

4.性能和优化

image.png

什么时候用DataFrames/DataSets

If you want rich semantics, high-level abstractions, and domain specific APIs, use DataFrame or Dataset.

If your processing demands high-level expressions, filters, maps, aggregation, averages, sum, SQL queries, columnar access and use of lambda functions on semi-structured data, use DataFrame or Dataset.

If you want higher degree of type-safety at compile time, want typed JVM objects, take advantage of Catalyst optimization, and benefit from Tungsten’s efficient code generation, use Dataset.

If you want unification and simplification of APIs across Spark Libraries, use DataFrame or Dataset.

If you are a R user, use DataFrames.

If you are a Python user, use DataFrames and resort back to RDDs if you need more control.

FAQ:

  1. spark转换函数中(map、filter等),println函数不输出
    RDD(or DataFrame、Dataset)分布式存储在集群的不同的worker上,如果你想打印里面的数据的话,存在以下问题:
    Where will that data be printed out?
    What node has priority and what partition?
    If all nodes are running in parallel, who will be printed first?
    How will be this print queue created?
    所以,Spark的设计者放弃了在transfortion和action的回调函数中对println的支持,如果你非要支持,比如在开发调试的时候,可以采取以下替代方案:
// Let's create a simple RDD
val rdd = sc.parallelize(1 to 10000)

def printStuff(x:Int):Int = {
  println(x)
  x + 1
}

// It doesn't print anything! because of a logic design limitation!
rdd.map(printStuff)

// But you can print the RDD by doing the following:
rdd.take(10).foreach(println)

参考:https://stackoverflow.com/questions/33225994/spark-losing-println-on-stdout

推荐阅读更多精彩内容