现在Spark正在进行中.Spark使用scala语言来加载和执行程序以及python和java.RDD用于存储数据.但是,我无法理解Spark的架构,它是如何在内部运行的.
请告诉我Spark Architecture以及它如何在内部工作?
Sat*_*ish 94
即使我一直在网上寻找Spark的内部,下面是我可以学习和想到的分享,
Spark围绕弹性分布式数据集(RDD)的概念展开,RDD是一个可以并行操作的容错的容错集合.RDD支持两种类型的操作:转换(从现有数据集创建新数据集)和操作(在数据集上运行计算后将值返回到驱动程序).
Spark将RDD转换转换为DAG(Directed Acyclic Graph)并开始执行,
在高级别,当在RDD上调用任何操作时,Spark会创建DAG并提交给DAG调度程序.
DAG调度程序将运算符划分为任务阶段.阶段由基于输入数据的分区的任务组成.DAG调度程序将运营商连接在一起.例如,许多地图运营商可以在一个阶段进行安排.DAG调度程序的最终结果是一组阶段.
阶段传递给任务计划程序.任务计划程序通过集群管理器启动任务.(Spark Standalone/Yarn/Mesos).任务调度程序不知道阶段的依赖性.
Worker在Slave上执行任务.
让我们来看看Spark如何构建DAG.
在高级别,有两种转换可以应用于RDD,即窄转换和广泛转换.宽变换基本上导致阶段边界.
狭窄的转换 - 不需要跨分区混洗数据.例如,地图,过滤器等.
广泛的转换 - 要求数据被洗牌,例如,reduceByKey等.
我们举一个例子来计算每个严重级别出现的日志消息数,
以下是以严重性级别开头的日志文件,
INFO I'm Info message
WARN I'm a Warn message
INFO I'm another Info message
Run Code Online (Sandbox Code Playgroud)
并创建以下scala代码以提取相同的,
val input = sc.textFile("log.txt")
val splitedLines = input.map(line => line.split(" "))
.map(words => (words(0), 1))
.reduceByKey{(a,b) => a + b}
Run Code Online (Sandbox Code Playgroud)
此命令序列隐式定义RDD对象的DAG(RDD沿袭),稍后将在调用操作时使用.每个RDD都维护一个指向一个或多个父级的指针以及有关它与父级的关系类型的元数据.例如,当我们在RDD上调用val b = a.map()时,RDD b保持对其父a的引用,这是一个沿袭.
为了显示RDD的谱系,Spark提供了一个调试方法toDebugString()方法.例如,在splitedLines RDD 上执行toDebugString(),将输出以下内容,
(2) ShuffledRDD[6] at reduceByKey at <console>:25 []
+-(2) MapPartitionsRDD[5] at map at <console>:24 []
| MapPartitionsRDD[4] at map at <console>:23 []
| log.txt MapPartitionsRDD[1] at textFile at <console>:21 []
| log.txt HadoopRDD[0] at textFile at <console>:21 []
Run Code Online (Sandbox Code Playgroud)
第一行(从底部)显示输入RDD.我们通过调用sc.textFile()创建了这个RDD.请参阅下面更多从给定RDD创建的DAG图的示意图.

构建DAG后,Spark调度程序会创建物理执行计划.如上所述,DAG调度程序将图分割为多个阶段,基于变换创建阶段.狭窄的变换将被分组(管道排列)在一起成为一个阶段.因此,对于我们的示例,Spark将创建两个阶段执行,如下所示,

然后,DAG调度程序将阶段提交到任务调度程序.提交的任务数取决于textFile中存在的分区数.Fox示例考虑我们在此示例中有4个分区,如果有足够的从属/核心,则会创建并提交4组任务.下图更详细地说明了这一点,

有关更多详细信息,我建议您浏览以下YouTube视频,其中Spark创建者提供有关DAG和执行计划及生命周期的详细信息.
| 归档时间: |
|
| 查看次数: |
12111 次 |
| 最近记录: |