SparkEnv源码解读

SparkEnv是Spark执行环境的关键对象,涉及安全管理器、RPC通信、序列化管理、广播管理等多个组件。本文深入剖析SparkEnv的构造,包括SecurityManager的权限设置,RpcEnv的通信机制,SerializerManager的序列化配置,以及BroadcastManager、mapOutputTracker和ShuffleManager的功能。此外,还讨论了内存管理和Block传输服务的角色,展示了SparkEnv如何协调Executor的运行。
摘要由CSDN通过智能技术生成

SparkEnv是Spark的执行环境对象,其中包括众多与Executor执行相关的对象。由于local模式下Driver会创建Executor,而cluster模式下Worker启动的CoarseGrainedExecutorBackend进程也会创建Executor,所以SparkEnv存在于Driver或者CoarseGrainedExecutorBackend进程中。

SparkEnv源码解读思维导图

下面是SparkEnv的主构造函数定义:

	/**
	* :: DeveloperApi ::
	* Holds all the runtime environment objects for a running Spark instance (either master or worker),
	* including the serializer, RpcEnv, block manager, map output tracker, etc. Currently
	* Spark code finds the SparkEnv through a global variable, so all the threads can access the same
	* SparkEnv. It can be accessed by SparkEnv.get (e.g. after creating a SparkContext).
	* 保存所有Spark运行时master和worker的环境对象, 包括serializer, RpcEnv, block manager和map output tracker等。
	* 现在Spark代码通过一个全局变量来引用SparkEnv,因此所有线程可以访问同一个SparkEnv对象。
	* 在创建完SparkContext对象后,它可以通过SparkEnv.get方法访问。
	*/
	@DeveloperApi
	class SparkEnv (
	    val executorId: String,
	    private[spark] val rpcEnv: RpcEnv,
	    val serializer: Serializer,
	    val closureSerializer: Serializer,
	    val serializerManager: SerializerManager,
	    val mapOutputTracker: MapOutputTracker,
	    val shuffleManager: ShuffleManager,
	    val broadcastManager: BroadcastManager,
	    val blockManager: BlockManager,
	    val securityManager: SecurityManager,
	    val metricsSystem: MetricsSystem,
	    val memoryManager: MemoryManager,
	    val outputCommitCoordinator: OutputCommitCoordinator,
	    val conf: SparkConf) extends Logging {...}

	object SparkEnv extends Logging {
      // 存储全局的SparkEnv对象,并且为volatile变量,保证各线程得到相同的值
	  @volatile private var env: SparkEnv = _

	  /**
	   * Returns the SparkEnv.
	   */
	  def get: SparkEnv = {
	    env
	  }

安全管理器SecurityManager

主要对权限和账号进行设置。如果使用Hadoop YARN作为集群管理器,则需要使用证书生成secret key登录,最后给当前系统设置默认的口令认证实例,验证器实例采用匿名内部类实现。

		/**
		 * Spark class responsible for security.
		 * 负责安全的spark类
		 * In general this class should be instantiated by the SparkEnv and most components
		 * should access it from that. There are some cases where the SparkEnv hasn't been
		 * initialized yet and this class must be instantiated directly.
		 * 通常这个类应该被SparkEnv初始化,然后大多数组件应该通过SparkEnv对象访问它。
		 * This class implements all of the configuration related to security features described
		 * in the "Security" document. Please refer to that document for specific features implemented
		 * here.
		 * 这个类实现了所有在官网'Security'文档中描述的有关安全特性的配置,具体实现的特性可参考[文档](https://spark.apache.org/docs/latest/security.html "spark安全文档")。
		 */
		private[spark] class SecurityManager(
		    sparkConf: SparkConf,
		    val ioEncryptionKey: Option[Array[Byte]] = None,
		    authSecretFileConf: ConfigEntry[Option[String]] = AUTH_SECRET_FILE)
		  extends Logging with SecretKeyHolder {

		  // Set our own authenticator to properly negotiate user/password for HTTP connections.
		  // This is needed by the HTTP client fetching from the HttpServer. Put here so its
		  // only set once.
          // 设定你自己的验证器为HTTP连接协商正确的用户名/密码。
          // 用户名/密码是给从HTTP服务器获取的HTTP客户端使用的。把它放在这里是为了保证它只被设置一次。
          // 用于每次使用HTTP client从HTTP服务器获取用户的用户和密码。这是由于Spark的节点间通信往往需要动态协商用户名、密码
		  if (authOn) {
		    Authenticator.setDefault(
		      new Authenticator() {
		        override def getPasswordAuthentication(): PasswordAuthentication = {
		          var passAuth: PasswordAuthentication = null
		          val userInfo = getRequestingURL().getUserInfo()
		          if (userInfo != null) {
		            val  parts = userInfo.split(":", 2)
		            passAuth = new PasswordAuthentication(parts(0), parts(1).toCharArray())
		          }
		          return passAuth
		        }
		      }
		    )
		  }
          ...
		}

rpc通信环境RpcEnv

用来进行Master和Worker间的分布式通信及数据传输。RpcEnv是RPC的环境对象,管理着整个RpcEndpoint的生命周期,其主要功能有:根据name或uri注册endpoints、管理各种消息的处理、停止endpoints。其中RpcEnv只能通过NettyRpcEnvFactory创建得到。
Rpc组件关系图

RpcEndpoint是一个通信端,例如Spark集群中的Master,或Worker,都是一个RpcEndpoint。但是,如果想要与一个RpcEndpoint端进行通信,一定需要获取到该RpcEndpoint一个RpcEndpointRef,通过RpcEndpointRef与RpcEndpoint进行通信,只能通过一个RpcEnv环境对象来获取RpcEndpoint对应的RPCEndpointRef。客户端通过RpcEndpointRef发消息,首先通过RpcEnv来处理这个消息,找到这个消息具体发给谁,然后路由给RpcEndpoint实体。

为什么从Spark 1.6以后用Netty代替Akka作为底层通信框架,实现类为NettyRpcEnv:

  • Akka不同版本之间无法互相通信,这就要求用
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值