SparkEnv是Spark的执行环境对象,其中包括众多与Executor执行相关的对象。由于在local模式下Driver会创建Executor,local-cluster部署模式或者Standalone部署模式下Worker另起的CoarseGrainedExecutorBackend进程中也会创建Executor,所以SparkEnv存在于Driver或者CoarseGrainedExecutorBackend进程中。创建SparkEnv主要使用SparkEnv的createDriverEnv,SparkEnv.createDriverEnv方法有三个参数:conf、isLocal和llistenerBus。
首先在sparkcontext里创建SparkEnv 的入口
private var _env: SparkEnv = _
_env = createSparkEnv(_conf, isLocal, listenerBus)
SparkEnv.set(_env)
createSparkEnv
val isLocal = (master == "local" || master.startsWith("local["))
private[spark] def createSparkEnv(
conf: SparkConf,
isLocal: Boolean,
listenerBus: LiveListenerBus): SparkEnv = {
SparkEnv.createDriverEnv(conf, isLocal, listenerBus)
}
上面代码中的conf是对SparkConf的复制,isLocal标识是否是单机模式,listenerBus采用监听器模式维护各类事件的处理
createDriverEnv
private[spark] def createDriverEnv(
conf: SparkConf,
isLocal: Boolean,
listenerBus: LiveListenerBus,
mockOutputCommitCoordinator: Option[OutputCommitCoordinator] = None): SparkEnv = {
assert(conf.contains("spark.driver.host"), "spark.driver.host is not set on the driver!")
assert(conf.contains("spark.driver.port"), "spark.driver.port is not set on the driver!")
val hostname = conf.get("spark.driver.host")
val port = conf.get("spark.driver.port").toInt
create(
conf,
SparkContext.DRIVER_IDENTIFIER,
hostname,
port,
isDriver = true,
isLocal = isLocal,
listenerBus = listenerBus,
mockOutputCommitCoordinator = mockOutputCommitCoordinator
)
}
SparkEnv的方法createDriverEnv最终调用create创建SparkEnv。SparkEnv的构造步骤如下:
1)创建安全管理器SecurityManager;
2)创建基于Akka的分布式消息系统ActorSystem;
3)创建Map任务输出跟踪器mapOutputTracker;
4)实例化ShuffleManager;
5)创建ShuffleMemoryManager;
6)创建块传输服务BlockTransferService;
7)创建BlockManagerMaster;
8)创建块管理器BlockManager;
9)创建广播管理器BroadcastManager;
10)创建缓存管理器CacheManager;
11)创建HTTP文件服务器HttpFileServer;
12)创建测量系统MetricsSystem
13)创建SparkEnv。
第一步:安全管理器SecurityManager
SecurityManager主要对权限、账号进行设置,如果使用Hadoop YARN作为集群管理器,则需要使用证书生成secret key登录,最后给当前系统设置默认的口令认证实例,此实例采用匿名内部类实现
private val secretKey = generateSecretKey()
// 使用HTTP连接设置口令认证
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
}
}
)
}
generateSecretKey()
// 密钥用于在Hadoop UGI中存储spark秘密
private val sparkSecretLookupKey = "sparkCookie"
//安全管理器是否开启了spark 通信协议
private val authOn = sparkConf.getBoolean(SecurityManager.SPARK_AUTH_CONF, false)
//检查是否启用了Spark通信协议的身份验证
//如果启用了身份验证,则返回true,否则为false
def isAuthenticationEnabled(): Boolean = authOn
private def generateSecretKey(): String = {
//没开启通信协议 设置秘钥为null
if (!isAuthenticationEnabled) return null
//开启了通信协议,如果是yarn模式,秘钥从用户凭证(sparkCookie)获得
val sCookie = if (SparkHadoopUtil.get.isYarnMode) {
val secretKey = SparkHadoopUtil.get.getSecretKeyFromUserCredentials(sparkSecretLookupKey)
if (secret