SparkがExecutorプロセスを開始するときにヒープメモリを指定します

CommandUtilsはSparkで最も一般的に使用されるツールの1つであり、その役割はプロセスを構築することです。その実装を気にしないのであれば、Sparkソースコードの読み取りや原則の研究には影響しません。紹介したい方法は次のとおりです。

buildProcessBuilder

  def buildProcessBuilder(
      command: Command,
      securityMgr: SecurityManager,
      memory: Int,
      sparkHome: String,
      substituteArguments: String => String,
      classPaths: Seq[String] = Seq[String](),
      env: Map[String, String] = sys.env): ProcessBuilder = {
    val localCommand = buildLocalCommand(
      command, securityMgr, substituteArguments, classPaths, env)
    val commandSeq = buildCommandSeq(localCommand, memory, sparkHome)
    val builder = new ProcessBuilder(commandSeq: _*)
    val environment = builder.environment()
    for ((key, value) <- localCommand.environment) {
      environment.put(key, value)
    }
    builder
  }

buildLocalCommand

  private def buildLocalCommand(
      command: Command,
      securityMgr: SecurityManager,
      substituteArguments: String => String,
      classPath: Seq[String] = Seq[String](),
      env: Map[String, String]): Command = {
    val libraryPathName = Utils.libraryPathEnvName
    val libraryPathEntries = command.libraryPathEntries
    val cmdLibraryPath = command.environment.get(libraryPathName)
 
    var newEnvironment = if (libraryPathEntries.nonEmpty && libraryPathName.nonEmpty) {
      val libraryPaths = libraryPathEntries ++ cmdLibraryPath ++ env.get(libraryPathName)
      command.environment + ((libraryPathName, libraryPaths.mkString(File.pathSeparator)))
    } else {
      command.environment
    }
 
    if (securityMgr.isAuthenticationEnabled) {
      newEnvironment += (SecurityManager.ENV_AUTH_SECRET -> securityMgr.getSecretKey)
    }
 
    Command(
      command.mainClass,
      command.arguments.map(substituteArguments),
      newEnvironment,
      command.classPathEntries ++ classPath,
      Seq[String](), // library path already captured in environment variable
      command.javaOpts.filterNot(_.startsWith("-D" + SecurityManager.SPARK_AUTH_SECRET_CONF)))
  }

buildCommandSeq

  private def buildCommandSeq(command: Command, memory: Int, sparkHome: String): Seq[String] = {
    val cmd = new WorkerCommandBuilder(sparkHome, memory, command).buildCommand()
    cmd.asScala ++ Seq(command.mainClass) ++ command.arguments
  }

CommandUtilsコマンドツールクラスを導入した後、正式にトピックを入力します。実際、Executorプロセスの開始は、CommandUtils.buildProcessBuilderメソッドを呼び出してProcessBuilderを生成し、そのstartメソッドを実行してProcessBuilderを開始してプロセスを生成することです。ここでは、cmdを構築する方法に焦点を当てています。buildCommandSepメソッドはbuildProcessBuilderで呼び出されます。このメソッドの最後の行では、コマンドの構造(CommandSeq)([javaOpt + classPath] + mainclass + args)を明確に確認してから、WorkerCommandBuilderのbuildCommandメソッドを分析しています。

/**
 * This class is used by CommandUtils. It uses some package-private APIs in SparkLauncher, and since
 * Java doesn't have a feature similar to `private[spark]`, and we don't want that class to be
 * public, needs to live in the same package as the rest of the library.
 */
private[spark] class WorkerCommandBuilder(sparkHome: String, memoryMb: Int, command: Command)
    extends AbstractCommandBuilder {

  childEnv.putAll(command.environment.asJava)
  childEnv.put(CommandBuilderUtils.ENV_SPARK_HOME, sparkHome)

  override def buildCommand(env: JMap[String, String]): JList[String] = {
    val cmd = buildJavaCommand(command.classPathEntries.mkString(File.pathSeparator))
    cmd.add(s"-Xmx${memoryMb}M")
    command.javaOpts.foreach(cmd.add)
    cmd
  }

  def buildCommand(): JList[String] = buildCommand(new JHashMap[String, String]())

}

cmdコマンドのビルド時に-Xmx $ {memoryMb} Mがスプライスされ、ここでのmemoryMbがSparkConfのexecutor-memory値であることがわかります。真実はここで明らかになり、設定したexecutor-memoryがついに完成しました。起動に使用されるExecutorプロセスは、最大ヒープを指定します。

おすすめ

転載: blog.csdn.net/qq_32445015/article/details/104899634