Apache spark Spark中的任务是什么?Spark worker如何执行jar文件?

Apache spark Spark中的任务是什么?Spark worker如何执行jar文件?,apache-spark,distributed-computing,Apache Spark,Distributed Computing,在阅读了一些文件之后,我有一些问题需要澄清 以Spark为例: JavaSparkContext spark = new JavaSparkContext( new SparkConf().setJars("...").setSparkHome....); JavaRDD<String> file = spark.textFile("hdfs://..."); // step1 JavaRDD<String> words = file.flatMap(new F

在阅读了一些文件之后,我有一些问题需要澄清

以Spark为例:

JavaSparkContext spark = new JavaSparkContext(
  new SparkConf().setJars("...").setSparkHome....);
JavaRDD<String> file = spark.textFile("hdfs://...");

// step1
JavaRDD<String> words =
  file.flatMap(new FlatMapFunction<String, String>() {
    public Iterable<String> call(String s) {
      return Arrays.asList(s.split(" "));
    }
  });

// step2
JavaPairRDD<String, Integer> pairs =
  words.map(new PairFunction<String, String, Integer>() {
    public Tuple2<String, Integer> call(String s) {
      return new Tuple2<String, Integer>(s, 1);
    }
  });

// step3
JavaPairRDD<String, Integer> counts =
  pairs.reduceByKey(new Function2<Integer, Integer>() {
    public Integer call(Integer a, Integer b) {
      return a + b;
    }
  });

counts.saveAsTextFile("hdfs://...");
JavaSparkContext spark=新的JavaSparkContext(
新的SparkConf().setJars(“…”).setSparkHome…);
JavaRDD file=spark.textFile(“hdfs://...");
//步骤1
JavaRDD单词=
file.flatMap(新的flatMap函数(){
公共Iterable调用(字符串s){
返回数组.asList(s.split(“”);
}
});
//步骤2
JavaPairRDD对=
words.map(新PairFunction(){
公共元组2调用(字符串s){
返回新的Tuple2(s,1);
}
});
//步骤3
JavaPairRDD计数=
pairs.reduceByKey(新函数2(){
公共整数调用(整数a、整数b){
返回a+b;
}
});
counts.saveAsTextFile(“hdfs://...");
假设我有3个节点集群,节点1作为主节点运行,上面的驱动程序已经正确地进行了jar(比如application test.jar)。现在我在主节点上运行这段代码,我相信在创建
SparkContext
之后,application-test.jar文件将被复制到worker节点(每个worker将为该应用程序创建一个dir)

现在我的问题是:
步骤1、步骤2和步骤3是否在发送给工人的示例任务中?如果是,那么工作人员如何执行?像
java-cp“application test.jar”step1
等等?

当您创建
SparkContext
时,每个工作者启动一个执行器。这是一个单独的进程(JVM),它也会加载您的jar。执行器连接回您的驱动程序。现在,驱动程序可以向他们发送命令,如示例中的
flatMap
map
reduceByKey
。当司机退出时,执行人就关门了

RDD有点像被分割成分区的大数组,每个执行器可以持有其中的一些分区

任务是通过序列化
函数
对象从驱动程序发送给执行者的命令。执行器反序列化命令(这是可能的,因为它已经加载了您的jar),并在分区上执行它

(这是一个概念性的概述。我对一些细节进行了润色,但希望能有所帮助。)



回答您的具体问题:不,没有为每个步骤启动新流程。当构建
SparkContext
时,将在每个工作进程上启动一个新流程。

为了清楚地了解任务是如何创建和调度的,我们必须了解Spark中执行模型是如何工作的。简而言之,spark中的应用程序分三步执行:

  • 创建RDD图
  • 根据RDD图创建执行计划。在此步骤中创建阶段
  • 根据计划生成任务,并在员工之间安排任务
  • 在您的字数计算示例中,RDD图相当简单,如下所示:

    文件->行->单词->每单词计数->全局单词计数->输出

    基于此图,将创建两个阶段。阶段创建规则基于将尽可能多的狭窄转换管道化的想法。在您的示例中,狭窄转换在每字计数时结束。因此,您将得到两个阶段

  • 文件->行->字->每字计数
  • 全局字数->输出
  • 一旦确定了阶段,spark将从阶段生成任务。第一个阶段将创建ShuffleMapTask,最后一个阶段将创建ResultTask,因为在最后一个阶段中,包含一个操作操作来生成结果

    要生成的任务数取决于文件的分发方式。假设在三个不同的节点中有三个不同的文件,第一阶段将生成三个任务:每个分区一个任务

    因此,您不应该将步骤直接映射到任务。任务属于阶段,并且与分区相关


    通常,为一个阶段运行的任务数正好是最终RDD的分区数,但由于RDD可以共享(因此
    ShuffleMapStages
    ),它们的数量取决于RDD/阶段共享。请参阅

    有一个重要的转折点。一切都是以懒散的方式发生的。因此,
    rdd.map
    在需要之前不会做任何事情。如果执行
    rdd.filter(…).map(…).collect()
    ,则调用
    collect
    时,
    filter
    map
    函数仅在工作进程上运行。但是大多数时候你不需要考虑这个问题,所以执行者实际上是堆叠rdd转换任务,除非对rdd调用一个操作,否则不会执行它们。这就是为什么它叫弹性?它会记录转换任务,当某些任务失败时,执行者会拿起任务并再次运行吗?谢谢,jar文件是否真的被洗牌到了工作节点?或者它停留在驱动程序应用程序的节点上,当驱动程序将任务发送给工作者时,工作者将返回驱动程序并引用jar作为依赖项来执行命令?所以在整个计算过程中,jar文件只有一个副本?它只停留在驱动程序节点上?感谢您使用
    SparkContext.addJar
    指定的jar将被复制到所有工作节点。这就是一个。。。美丽的。。。讲述spark背后的概念几乎让我流泪。可能误导的是RDD像大阵列这样的概念。它们是关于如何具体化这些数组以及如何对它们进行分区的指令容器,而不是那些数组本身。谢谢。现在有理由解释为什么我在一个阶段有将近20个任务。我的RDD在集群中有20个分区。但有一个问题是,我如何强制每个执行者只处理本地数据。我看到executor日志上写着“storage.BlockManager:远程找到块rdd_2_2”。大部分区块似乎是在本地找到的,但有些区块被标记为远程。当我看到