Apache Spark 大数据处理详解

在当今信息爆炸的时代,数据量的激增给数据处理带来了前所未有的挑战。为了从海量数据中提取有价值的信息,必须不断进步,发展出更高效的数据处理技术。Apache Spark就是这样一个强大的大数据处理引擎,它不仅能够并行计算数据,而且设计为在一组引擎上运行,具有分布式特性。Spark在处理大数据方面的效率甚至超过了Hadoop的MapReduce。

接下来,将深入了解Apache Spark是如何在内部执行代码的。对以下代码行可能已经很熟悉,但值得注意的是,这些代码在内部是如何被执行的。

from pyspark.sql import SparkSession spark = SparkSession.builder.getOrCreate() sc = spark.sparkContext # 并行化RDD rdd_0 = sc.parallelize(["She saw Sharif's shoes on the sofa but was she so sure those were Sharif's shoes she saw?"]) # 将句子分词成单词 rdd_1 = rdd_0.flatMap(lambda x: x.split()) # 创建键值对RDD rdd_2 = rdd_1.map(lambda x: (x, 1)) # 统计单词出现次数 rdd_3 = rdd_2.reduceByKey(lambda a,b: a+b) # 持久化RDD rdd_3.persist() # 收集RDD rdd_3.collect()

在上面的代码中,有一个Spark应用程序,它在数据集上执行多个RDD转换,并在最后使用单个动作函数计算结果。Spark作业的工作方式是,一旦触发了像collect()、count()等动作操作,负责启动Spark应用程序的驱动程序(也被认为是任何Spark应用程序的入口点)就会将这个Spark应用程序转换成一个作业。

作业被定义为一系列阶段的组合。当数据在网络上发生混洗时,Spark会将作业分成多个阶段。因此,当数据混洗发生时,就会创建一个阶段。这些阶段可以并行或顺序处理,这取决于这些阶段之间的依赖关系。如果有两个阶段,Stage 0和Stage 1,如果它们不是顺序依赖的,它们将并行执行。

在单个阶段中顺序处理RDD被称为流水线处理。在代码中,使用了reduceByKey()函数,它混洗了数据以便对相同的键进行分组。由于数据混洗只发生一次,作业将被分成两个阶段。

Spark中有两类阶段:

  • ShuffleMapStage
  • ResultStage

1. ShuffleMapStage:顾名思义,这是Spark中产生混洗操作数据的阶段。这个阶段的输出作为后续阶段的输入。在代码中,Stage 0将作为ShuffleMapStage,因为它产生混洗操作的数据,作为Stage 1的输入。

2. ResultStage:作业中的最后一个阶段执行动作操作,通过在RDD上运行函数(在例子中,动作操作是collect)来计算结果。Stage 1在示例中作为ResultStage,因为它给出了在RDD上执行的动作操作的结果。在代码中,数据混洗后,相似的键通过reduceByKey()函数被分组,所以这个阶段使用collect(动作操作)函数给出了代码的最终结果。

一个阶段进一步是一组一起执行的任务。现在将讨论什么是任务。

在单个数据分区上执行的单个计算单元被称为任务。它在工作节点的单个核心上计算。每当Spark执行任何计算操作,如转换等,Spark都在数据分区上执行任务。由于在代码中,有两个数据分区,因此有两个任务。每个任务都在工作节点的不同核心上并行计算相同的操作。

需要注意的一些要点:

  1. 集群管理器为每个工作节点分配资源以执行任务。
  2. 核心是CPU的计算单元;它控制执行器可以同时执行或运行的任务数量。
  3. 假设核心数量为3,则执行器最多可以同时运行3个任务。
  4. 执行器负责单独执行任务。执行器并行处理任务的能力取决于分配给它的核心数量,如第二点所述。
  5. 每个工作节点都有缓存内存用于存储,一旦计算结果,它就会被发送到驱动程序。

这就是Spark应用程序如何被转换成作业,进一步被分成阶段和任务的。

现在将执行作为示例的示例代码,看看Spark的内部执行是如何工作的。首先,将导入Spark会话,然后创建这个Spark会话的对象作为‘spark’,如上所示。当查看这个对象时,它将显示Spark集群的配置,如版本、应用名称和主节点。还可以看到Spark UI在这个对象中。它是一个图形用户界面,允许查看所有Spark应用程序的作业、阶段和任务。让点击它。

可以看到一个新窗口打开,但在其中,没有什么可看的,因为还没有运行应用程序。现在将运行代码,输出每个单词的计数。将明确创建一个SparkContext对象(创建SparkContext对象总是必要的,以便与RDDs一起工作),如代码所示。然后将创建一个名为rdd_0的RDD,它将包含以列表形式传递的句子,然后是第一个转换,即flatMap(),它将句子分割成单词列表。

在此之后,应用map转换来创建一个键值对RDD,将每个单词的值设为1并保存在rdd_2中。现在为了统计每个单词的出现次数,将使用reduceByKey()方法来汇总相似单词的值,并将它们存储在rdd_3中。

代码就是这样工作的,现在,在执行它之后,当打开Spark UI时,可以看到已经成功完成了一个作业。它还包含有关阶段、任务、存储等的信息,可以通过点击相应的标签来打开。

所以,在例子中,已经成功完成了一个作业。当点击阶段标签时,会得到有关每个阶段的信息。在例子中,将有两个阶段。它显示了有关混洗数据量、完成阶段所需的时间等的信息。

同样,可以看到在运行Spark应用程序时执行的任务的信息。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485