Bootstrap

1. 初识spark

背景:

作为一名开发人员,用内存处理数据是每天都在做的事情。内存处理数据最大的优势就是方便,快捷,可以很快得到结果,但是内存总是有瓶颈的,不管你运行代码的机器有多大的内存,总是有更大规模的数据需要处理,而且随着单个机器内存扩容,硬件成本会指数级上升。在当今互联网行业,数据快速膨胀的时代,分布式计算来处理数据是大势所趋。本文通过介绍的是大数据领域优秀框架spark ,打开分布式实时计算的大门

1. spark是什么

Spark是一种基于内存的快速、通用、可扩展的大数据分析引擎。以下是对Spark的详细介绍:

1.1 起源与发展

Spark最初于2009年诞生于加州大学伯克利分校AMPLab(AMP:Algorithms,Machines,People),作为伯克利大学的研究性项目。
2010年,Spark正式开源。
2013年6月,Spark成为Apache孵化项目。
2014年2月,Spark成为Apache顶级项目。

1.2 核心特点

  1. 高速性:Spark基于内存进行数据处理,大大减少了磁盘读写的开销,因此比传统的MapReduce作业快上几个数量级。同时,Spark实现了高效的DAG(有向无环图)执行引擎,可以高效地处理数据流。
  2. 易用性:Spark提供了丰富的API,支持多种编程语言(如Scala、Java、Python、R等),并且提供了丰富的高级功能(如SQL查询、机器学习和图计算),使得用户可以轻松地开发复杂的分布式应用程序。此外,Spark还支持交互式的Python和Scala的Shell,方便用户在这些Shell中使用Spark集群来验证解决问题的方法。
  3. 弹性:Spark提供了弹性的分布式数据集(Resilient Distributed Dataset,RDD)抽象,可以在内存中缓存数据,具有强容错性。当节点故障时,Spark可以自动恢复数据,保证作业的稳定执行。
  4. 通用性:Spark不仅支持批处理作业(如MapReduce),还支持交互式查询、流处理和机器学习等多种应用场景。这些不同类型的处理都可以在同一个应用中无缝使用,从而降低了开发和维护的人力成本以及部署平台的物力成本。

1.3 内置模块与组件

Spark包含了多个内置模块和组件,以满足不同场景下的数据处理需求:

  1. Spark Core:实现了Spark的基本功能,包含任务调度、内存管理、错误恢复、与存储系统交互等模块。同时,Spark Core中还包含了对RDD的API定义。
  2. Spark SQL:用于操作结构化数据的程序包。通过Spark SQL,用户可以使用SQL或者Apache Hive版本的SQL方言(HQL)来查询数据。Spark SQL支持多种数据源,如Hive表、Parquet以及JSON等。
  3. Spark Streaming:用于对实时数据进行流式计算的组件。它提供了用来操作数据流的API,并且与Spark Core中的RDD API高度对应。Spark Streaming使得用户可以快速开发流应用程序,并且具有强大的容错能力和集成性。
  4. Spark MLlib:提供常见的机器学习(ML)功能的程序库。包括分类、回归、聚类、协同过滤等算法,还提供了模型评估、数据导入等额外的支持功能。
  5. GraphX:用于图计算的组件。GraphX提供了丰富的图处理算法和工具,使得用户可以高效地处理和分析图数据。

1.4 应用场景与生态系统

Spark的应用场景非常广泛,包括但不限于推荐系统、交互式实时查询等。同时,Spark已经形成了一个丰富的生态圈,能够与其他多种框架和系统进行融合和扩展。这些框架和系统包括数据科学和机器学习框架(如scikit-learn、pandas、TensorFlow、PyTorch等)、SQL分析和BI工具(如Superset、Power BI、Looker等)、存储和基础设施(如Elasticsearch、MongoDB、Kafka等)。

综上所述,Spark作为一种基于内存的快速、通用、可扩展的大数据分析引擎,在大数据处理领域具有广泛的应用前景和重要的学术价值。

2. spark下载与入门

在前期,我会先下载spark并在本地单机运行spark,后期会搭建spark集群并将任务交给集群处理。关于版本问题,本文选择3.4.4 来演示

2.1 下载

  1. 访问spark官网 https://spark.apache.org/downloads.html
  2. 选择对应版本之后点击download下载,下载的是压缩包
  3. 本地解压压缩包
  4. 安装scala

2.2 spark中python 和 scala的shell

Spank 带有交互式的 shell,可以作即时数据分析。如果你使用过类似R、Python、Seala 所提供的 shell,或操作系统的 shell(例如 Bash 或者 Windows 中的命令提示符),你也会对Spark shell 感到很熟悉。

然而和其他 shell 工具不一样的是,在其他she 工具中你只能使用单机的硬盘和内存来操作数据,而Sparkshell 可用来与分布式存储在许多机器的内存或者硬盘上的数据进行交互,并且处理过程的分发由Spark自动控制完成。

由于Spark 能够在工作节点上把数据读取到内存中,所以许多分布式计算都可以在几秒钟之内完成,哪怕是那种在十几个节点上处理TB级别的数据的计算。这就使得一般需要在shell 中完成的那些交互式的即时探索性分析变得非常适合Spark。Spark提供Python 以及Scala的增强版shell,支持与集群的连接。

2.2.1 Scala Shell (spark-shell)

Scala 是 Spark 的原生语言,因此 Spark Shell 默认是基于 Scala 的。spark-shell 提供了一个预配置的环境,其中包含 Spark 上下文(SparkContext)和 SQL 上下文(SparkSession),使得用户可以立即开始使用 Spark。

2.2.1.1 启动 Scala Shell

在命令行中输入以下命令来启动 Scala Shell:

bin/spark-shell

启动后,你会看到一个类似 REPL(Read-Eval-Print Loop)的界面,可以开始输入 Scala 代码。

2.2.1.2 示例
val sc = spark.sparkContext
val data = sc.textFile("hdfs:///path/to/input.txt")
val words = data.flatMap(line => line.split(" "))
val wordCounts = words.map(word => (word, 1)).reduceByKey(_ + _)
wordCounts.collect().foreach(println)

2.2.2 Python Shell (pyspark)

PySpark 是 Spark 的 Python API,允许用户使用 Python 编写 Spark 应用程序。pyspark shell 提供了一个与 Scala shell 类似的环境,但适用于 Python 开发者。

2.2.2.1 启动 Python Shell

在命令行中输入以下命令来启动 PySpark Shell:

bin/pyspark

启动后,你会看到一个 Python REPL 界面,并且 Spark 上下文(sc)和 SQL 上下文(spark)已经预先配置好了。

2.2.2.2 示例
from pyspark import SparkContext, SparkConf

sc = SparkContext(appName="PythonWordCount")
data = sc.textFile("hdfs:///path/to/input.txt")
words = data.flatMap(lambda line: line.split(" "))
wordCounts = words.map(lambda word: (word, 1)).reduceByKey(lambda a, b: a + b)
wordCounts.collect()

2.2.3 注意事项

  1. 环境配置:确保你已经正确安装了 Spark,并且环境变量(如 SPARK_HOME)已经配置好。
  2. 依赖管理:在 PySpark 中,你可能需要管理 Python 依赖,这通常通过 requirements.txt 文件或虚拟环境来实现。
  3. 性能差异:虽然 PySpark 提供了方便的开发体验,但在性能上,Scala 通常会比 Python 更快,因为 Scala 是静态类型语言,并且与 JVM 更紧密集成。

通过使用这些 shell,可以快速原型化和测试 Spark 应用程序,而无需编写完整的脚本或应用程序。

2.3 spark核心概念简介

2.3.1 RDD(弹性分布式数据集)

RDD是Spark的核心数据结构,代表一个不可变、可分区、可并行操作的元素集合。RDD具有如下特性:

  1. 弹性:RDD既可以在内存中存储并计算(优先使用内存),如果内存不够,可以溢出到磁盘上。
  2. 数据集:RDD是一个普通的Scala的不可变的集合。
  3. 分布式:一个完整的RDD数据集被拆分成多个部分,在不同的机器里面存储。被拆分成的部分称之为该RDD的分区(Partition),类似于HDFS中的一个文件被拆分成多个Block块存储。

RDD支持两种操作:

  1. 转换操作(Transformations):如map、filter、reduceByKey等,这些操作是惰性(Lazy)的,即从一个RDD转换生成另一个RDD的操作不会立即执行,而是等到有Actions操作时才会真正启动计算过程进行计算。
  2. 行动操作(Actions):如collect、count、saveAsTextFile等,这些操作会触发Spark启动计算并返回结果或把RDD数据写到存储系统中。

2.3.2 SparkContext

SparkContext是Spark的入口点,用于连接Spark集群,创建RDD并进行操作。它是Spark应用程序的上下文环境,控制应用的生命周期。

2.3.3 Cluster Manager(集群管理器)

Cluster Manager负责管理Spark集群的资源(如CPU核心、内存等)。在不同的部署模式下,Cluster Manager可以是Spark自带的(Standalone模式),也可以是YARN、Mesos等外部集群管理器。

2.3.4 Worker Node(工作节点)

Worker Node是执行作业任务的工作节点,是Spark计算能力的实际提供者。在Standalone模式中,Worker Node负责控制计算节点,启动Executor。

2.3.5 Driver

Driver是每个Spark应用程序的核心,负责启动并控制整个应用程序。它创建SparkContext,与Cluster Manager通信,管理资源申请、任务分配和监控。

2.3.6 Executor

Executor是在Worker Node上运行的进程,可以派生出多个线程来并行处理任务。每个Spark应用程序都拥有独立的一组Executors。

2.3.7 DAGScheduler和TaskScheduler

  1. DAGScheduler:负责将Spark作业分解成一到多个Stage,每个Stage根据RDD的Partition个数决定Task的个数,然后生成相应的Task Set放到TaskScheduler中。DAGScheduler可以看作是Spark的大脑,负责作业的划分和调度。
  2. TaskScheduler:负责将Task分发给Executor执行。

2.3.8 Stage和Task

  1. Stage:一个Spark作业一般包含一到多个Stage。Stage是根据RDD之间的依赖关系(宽依赖或窄依赖)来划分的。
  2. Task:一个Stage包含一到多个Task,通过多个Task实现并行运行的功能。Task的个数由RDD的Partition分区决定。

2.3.9 Actions触发计算

在Spark中,只有Actions操作才会触发计算。Actions操作会返回一个结果或把RDD数据写到存储系统中。常见的Actions操作包括collect、count、saveAsTextFile等。

综上所述,Spark的核心概念包括RDD、SparkContext、Cluster Manager、Worker Node、Driver、Executor、DAGScheduler、TaskScheduler、Stage、Task以及Actions触发计算等。这些概念共同构成了Spark的分布式计算框架,使得Spark能够高效地处理大规模数据。

2.3.10 简单交互

2.3.10.1 Spark作业执行交互图
Client
  |
  v
Driver (SparkContext)
  |
  +--- DAGScheduler (划分Stage)
  |
  +--- TaskScheduler (分发Task)
  |
  v
Cluster Manager (资源分配)
  |
  +--- Worker Node (控制计算节点)
         |
         v
       Executor (执行任务)
2.3.10.2 交互流程说明
  1. Client提交作业

    • 用户通过Client(如spark-submit命令)提交Spark作业。
  2. Driver启动并管理作业

    • Driver是Spark作业的核心,负责启动并管理整个作业的执行。
    • Driver创建SparkContext,它是Spark应用程序的上下文环境,用于连接Spark集群、创建RDD并进行操作。
    • SparkContext内部包含DAGScheduler和TaskScheduler两个重要组件。
  3. DAGScheduler划分Stage

    • DAGScheduler负责将Spark作业分解成一到多个Stage。
    • 每个Stage根据RDD的Partition个数决定Task的个数。
    • DAGScheduler生成相应的Task Set并放到TaskScheduler中等待调度。
  4. TaskScheduler分发Task

    • TaskScheduler负责将Task分发给Executor执行。
    • TaskScheduler与Cluster Manager通信,请求资源并分配Task。
  5. Cluster Manager分配资源

    • Cluster Manager负责管理Spark集群的资源。
    • 在不同的部署模式下,Cluster Manager可以是Spark自带的(Standalone模式),也可以是YARN、Mesos等外部集群管理器。
    • Cluster Manager根据TaskScheduler的请求,为Spark作业分配资源(如CPU核心、内存等)。
  6. Worker Node控制计算节点

    • Worker Node是执行作业任务的工作节点。
    • 在Standalone模式中,Worker Node负责控制计算节点,启动Executor。
  7. Executor执行任务

    • Executor是在Worker Node上运行的进程,可以派生出多个线程来并行处理任务。
    • Executor接收TaskScheduler分发的Task,并执行相应的计算逻辑。
    • Executor将计算结果返回给Driver(对于需要返回结果的Actions操作)。
2.3.10.3 数据流动
  • 数据在RDD之间流动,通过转换操作(Transformations)生成新的RDD。
  • 行动操作(Actions)触发计算,并将结果返回给用户或写入存储系统。

以上,如有错误,请不吝指正!

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;