目录
3、创建serializerManager和closureSerializer
8、创建输出提交协调器outputCommitCoordinator
SparkEnv简述
Java程序运行需要Java运行环境,Scala程序运行需要Scala运行环境,同样Spark程序运行也需要Spark运行环境,这个运行环境就是SparkEnv。SparkEnv中保留了所有运行的spark实例(master或worker)中运行的环境对象。具体包括的内容如下图所示:
SparkEnv的代码结构不算复杂,提供了停止方法和建立、销毁、释放pysparkworker的方法。其主要核心代码,在SparkEnv伴生对象中。
SparkEnv伴生对象提供了创建Driver运行环境和Executor运行环境的方法。
创建Driver运行环境的方法如下:
private[spark] def createDriverEnv(
conf: SparkConf,
isLocal: Boolean,
listenerBus: LiveListenerBus,
numCores: Int,
mockOutputCommitCoordinator: Option[OutputCommitCoordinator] = None): SparkEnv = {
/** spark.driver.host 校验Driver对外宣称的地址 */
assert(conf.contains(DRIVER_HOST_ADDRESS),
s"${DRIVER_HOST_ADDRESS.key} is not set on the driver!")
/** spark.driver.port 校验Driver端口号 */
assert(conf.contains("spark.driver.port"), "spark.driver.port is not set on the driver!")
/**
* Driver绑定的地址:DRIVER_BIND_ADDRESS:
* 优先获取顺序依次是:spark.driver.bindAddress-》spark.driver.host-》Utils.localHostName()
* Driver对外宣称的地址:DRIVER_HOST_ADDRESS
* 优先获取顺序依次是:spark.driver.host-》Utils.localHostName()
* Dirver的端口:port:从spark.driver.port中获取
*
* */
val bindAddress = conf.get(DRIVER_BIND_ADDRESS)
val advertiseAddress = conf.get(DRIVER_HOST_ADDRESS)
val port = conf.get("spark.driver.port").toInt
/** park.io.encryption.enabled默认是fasle,当为true时,建立密钥 */
val ioEncryptionKey = if (conf.get(IO_ENCRYPTION_ENABLED)) {
Some(CryptoStreamUtils.createKey(conf))
} else {
None
}
create(
conf,
SparkContext.DRIVER_IDENTIFIER,
bindAddress,
advertiseAddress,
port,
isLocal,
numCores,
ioEncryptionKey,
listenerBus = listenerBus,
mockOutputCommitCoordinator = mockOutputCommitCoordinator
)
}
在SparkContext初始化的时候,创建Spark运行环境时,最终调用了createDriverEnv方法。
创建Executor运行环境的方法如下:
private[spark] def createExecutorEnv(
conf: SparkConf,
executorId: String,
hostname: String,
port: Int,
numCores: Int,
ioEncryptionKey: Option[Array[Byte]],
isLocal: Boolean): SparkEnv = {
val env = create(
conf,
executorId,
hostname,
hostname,
port,
isLocal,
numCores,
ioEncryptionKey
)
SparkEnv.set(env)
env
}
不难发现无论是createDriverEnv还是createExecutorEnv最终都是调用了create这个私有方法。
解析create方法
0、解析之前
create方法才是主菜,它主要的作用就是创建并保存SparkEnv中的组件,然后创建SparkEnv,在方法的开始就明确了,当前SparkEnv实例是driver端的还是executor端的。create方法的中的代码创建组件的时候,都会依赖此判断,因为driver和executor创建组件的逻辑是不一样的。
这里还要先了解一个方法,这个方法在create方法内部叫registerOrLookupEndpoint,这个方法用来注册或是发现RpcEndpointRef。如果是dirver调用,则将具体的RpcEndpoint注册到dispatcher中,必须带有注册名称;如果是executor调用,则根据注册名到远程的diver的NettyRpcEnv中的dispatcher中查找相关引用。
下面开始正式说SparkEnv真正的创建过程,总结为以下9个步骤:
/**
* 创建SparkEnv共分为9个步骤,该方法适用于创建driver或executor
* 1、建立安全管理器securityManager
* 2、建立RpcEnv
* 3、创建serializerManager和closureSerializer
* 4、创建广播管理器broadcastManager
* 5、创建map输出跟踪器mapOutputTracker
* 6、构建存储体系
* 7、创建地量系统metricsSystem
* 8、创建输出提交协调器outputCommitCoordinator
* 9、正式创建SparkEnv
* */
1、建立安全管理器securityManager
2、建立RpcEnv
3、创建serializerManager和closureSerializer
4、创建广播管理器broadcastManager
5、创建map输出跟踪器mapOutputTracker
6、构建存储体系
6.1 创建ShuffleManager
6.2 创建MemoryManager
6.3 创建blockTransferService
6.4 创建blockManagerMaster和6.5 创建blockManager
7、创建地量系统metricsSystem
8、创建输出提交协调器outputCommitCoordinator
9、正式创建SparkEnv
以上就是SparkEnv的主要内容。