环境:
spark 2.3.3
scala 2.11.8
Java 1.8.0_141
本文主要内容:
Spark集群HA安装部署
Spark Master HA 主备切换流程
Spark Master HA 在Zookeeper上的持久化
spark集群安装部署
节点分布
| Master | Worker |
|
node01.zf.com | √ |
| 192.168.0.100 |
node02.zf.com | √ | √ | 192.168.0.110 |
node03.zf.com |
| √ | 192.168.0.120 |
修改配置,修改所有节点上的${SPARK_HOME}/conf/spark-env.sh
#配置java的环境变量
export JAVA_HOME=/soft/install/jdk1.8.0_141
#配置zk相关信息
export SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=node01:2181,node02:2181,node03:2181 -Dspark.deploy.zookeeper.dir=/spark"
修改配置,修改所有节点上的${SPARK_HOME}/conf/slaves
node02
node03
启动前,先查看下zookeeper下有没有/spark
此时没有/spark znode
启动Spark集群
1.在node01 执行$SPARK_HOME/sbin/start-all.sh
此时会在node01启动一个Master
从启动日志,可以看到
同时,jps
会有一个master进程
此时查看zookeeper下 /spark znode信息
此时/spark znode已经创建,并在在/spark/master_status下面保存两个worker节点信息
2.此时在node02上,执行$SPARK_HOME/sbin/start-master.sh,再启动一个master
从启动日志和jps信息,可以判断
此时,查看zookeeper的/spark/leader_election
发现,又进行了一次master elect。
此时通过spark webUI进行确认node01:8080,node02:8080
node01为active状态,node02为standby状态。
3.验证HA
kill掉node01 的Master进程,看node02的Master是否变为active
在node01执行kill 34099, 杀掉Master进程
查看zookeeper
可以看到master发生变化
通过spark webUI
可以看到node02已经重新被选举为active,同时也为从zookeeper中获取worker信息。
下面从代码层面来分析下:
org.apache.spark.deploy.master.Master类,在启动后,会匹配到onStart事件,在onstart方法的最后,会设置持久化方式。
首先获取RECOVERY_MODE
private val RECOVERY_MODE = conf.get("spark.deploy.recoveryMode", "NONE")
通过spark-env.sh中的配置项-Dspark.deploy.recoveryMode=ZOOKEEPER,可以获得RECOVERY_MODE为ZOOKEEPER
而ZooKeeperRecoveryModeFactory.createPersistenceEngine方法
会创建ZooKeeperPersistenceEngine对象
在实例化ZooKeeperPersistenceEngine对象时,会在zookeeper中创建/spark/master_status的znode。
而ZooKeeperRecoveryModeFactory.createLeaderElectionAgent方法会ZooKeeperLeaderElectionAgent对象,用于代理zookeeper选举领导角色的对象。
在实例化ZooKeeperLeaderElectionAgent对象时,
会痛LeaderLatch对象的leaderLatch.start()方法创建/spark/leader_election znode。具体的调用逻辑如下:
LeaderLatch.start() -> LeaderLatch.internalStart() -> LeaderLatch.reset()
在 LeaderLatch.reset()方法的最后会创建znode
client.create().creatingParentsIfNeeded().withProtection().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).inBackground(callback).forPath(ZKPaths.makePath(latchPath, LOCK_NAME), LeaderSelector.getIdBytes(id));
由于创建的zknode是CreateMode.EPHEMERAL_SEQUENTIAL,在Master挂掉后,该znode会被删掉