Spark StandaloneMode
Spark除了可以运行在Mesos和YARN集群管理系统中,它也提供了一个简单独立的部署模式,你可以手动的启动一个集群环境,通过启动一个master和多个worker,或者使用Spark提供的启动脚本,当然你也可以将这些进程运行在一台机器中以便测试使用。
Installing Spark Standalone to a Cluster
要安装一个Saprk独立的集群,你只需要将编译好的Spark分别放在集群中的每一个节点上,你可以通过在官网下载编译好的Spark或者自己编译。
Starting a Cluster Manually
你可以通过执行如下命令启动一个独立的master。
./sbin/start-master.sh
启动时,master会输出一条spark://HOST:PORT的URL信息,用来启动worker节点时指定的master地址,你也可以通过访问master的控制台获取,默认的控制台地址是http://master:8080
同样的,你也可以启动一个或多个worker节点
./sbin/start-slave.sh <master-spark-URL>
当worker启动成功后,通过查看master的控制台你会看到会有一个新的node以及他的CPU数量、可用内存等信息。
最后,master和worker有如下配置参数
Argument | Meaning |
-h HOST, --host HOST | 要监听的主机地址 |
-i HOST,--ip HOST | 已被废弃,使用-h或者—host代替 |
-p PORT,--port PORT | 监听端口(master默认是7077,worker随机) |
--webui-port PORT | 控制台端口(master默认是8080,worker默认是8081) |
-c CORES,--cores CORES | 控制worker节点中有多少个CPU可以被Spark应用程序所使用 |
-m MEM,--memory MEM | 控制worker节点中共有多少内存可以被Spark应用程序使用,默认是你机器的所有内存减去1GB |
-d DIR,--work-dir DIR | 设置worker的数据暂存空间以及Job的日志存储。默认是SPARK_HOME/work。用户提交的应用程序运行的日志以及jar包都会存放在这个目录中。 |
--properties-file FILE | 加载默认的Spark配置文件。默认在conf/spark-defaults.conf |
Cluster Launch Scripts
可以通过Spark提供的shell脚本启动一个独立的Spark集群,你需要在conf文件夹中创建一个slaves的文件,里面包含你要启动的worker节点的主机名,每个主机名占用一行。如果你没有创建这个文件也调用了这个启动独立集群的脚本那么会默认在localhost中启动一个worker节点,非常适合测试使用。注意,master节点通过ssh访问各个worker节点,所以你需要配置ssh免密码登录。如果你没有配置ssh免密码登录那么你需要配置SPARK_SSH_FOREGROUND环境变量为每个worker提供一个登录密码。
当创建完这个salves文件后,你可以通过如下脚本启动或停止Spark集群,在SPARK_HOME/sbin目录中。
sbin/start-master.sh 启动本机的master节点
sbin/start-slaves.sh 根据slaves配置文件启动所有的worker节点
sbin/start-slave.sh 启动本机的slave节点
sbin/start-all.sh 启动本机的master节点以及slaves中配置的所有worker节点
sbin/stop-master.sh 停止本机启动的master节点
sbin/stop-slaves.sh 根据slaves配置文件停止全部的worker节点
sbin/stop-all.sh 停止本机的master以及slaves中配置的所有worker节点
注意:这些脚本必须在master节点中运行。
你也可以通过在conf/spark-env.sh中配置环境变量,如果这个文件不存在可以通过拷贝conf/spark-env.sh.template模版创建,并且需要将这个文件拷贝到各个worker节点,如下配置可用
Environment Variable | Meaning |
SPARK_MASTER_HOST | master要绑定的ip或者主机名 |
SPARK_MASTER_PORT | master要绑定的端口,默认是7077 |
SPARK_MASTER_WEBUI_PORT | master的控制台端口,默认是8080 |
SPARK_MASTER_OPTS | 配置master的JVM参数,使用“-Dx=y”格式。 |
SPARK_LOCAL_DIRS | 配置Spark用于存储数据的空间,包括一些计算时的输出数据,最好是本地高速磁盘,可以通过逗号分割指定多个磁盘目录。 |
SAPRK_WORKER_CORES | 控制worker节点中有多少个CPU可以被Spark应用程序所使用 |
SAPRK_WORKER_MEMORY | 控制worker节点中共有多少内存可以被Spark应用程序使用,默认是你机器的所有内存减去1GB |
SPARK_WORKER_PORT | worker的监听端口 |
SPARK_WORKER_WEBUI_PORT | worker的控制台端口,默认是8081 |
SPARK_WORKER_DIR | 设置worker的数据暂存空间以及Job的日志存储。默认是SPARK_HOME/work。用户提交的应用程序运行的日志以及jar包都会存放在这个目录中。 |
SPARK_WORKER_OPTS | 配置worker的JVM参数,使用“-Dx=y”格式。 |
SPARK_DAEMON_MEMORY | 配置master和worker进行的内存,默认是1G |
SPARK_DAEMON_JAVA_OPTS | 配置master和worker进程的JVM参数,使用“-Dx=-y”根式。 |
SPARK_PUBLIC_DNS | master和worker的DNS配置 |
注意:Spark暂时没有提供Windows环境下的快捷启动脚本,Windows中需要手动启动Spark集群
SPARK_MASTER_OPTS支持如下系统参数.
Property Name | Default | Meaning |
spark.deploy.retainedApplications | 200 | 控制台中可以显示的运行完成的应用程序最大数量,更早的数据会被删除。 |
spark.deploy.retainedDrivers | 200 | 控制台中可以显示运行完成的驱动程序最大数量,更早的数据会被删除。 |
spark.deploy.spreadOut | true | spark独立集群管理是否将应用程序调度运行在分散的节点中或者尽可能少的节点中去工作。分散运行在不同的节点中访问HDFS数据时可以更加并发高效,合并在尽量少的节点中更适合密集型的计算。 |
spark.deploy.defaultCores | 正无穷 | spark应用程序默认使用的CPU数量,如果提交应用时没有指定spark.cores.max应用程序则会使用所有可用的CPU,在集群模式中需要设置这个为一个适当的值避免一个应用抢占了所有的资源导致其余应用处于等待资源状态。 |
spark.deploy.timeout | 60 | master和worker之间心跳检测的超时时间,单位为秒,超过这个事件master认为worker已经死掉。 |
SPARK_WORKER_OPTS支持如下系统参数.
Property Name | Default | Meaning |
Spark.worker.cleanup.enabled | False | 是否允许Spark周期性的删除worker节点中已经停止的应用程序产生的数据。仅在独立集群中生效。 |
Spark.worker.cleanup.interval | 1800(秒) | 清除worker节点中数据的间隔时间。 |
Spark.worker.cleanup.appDataTtl | 7*24*3600(秒) | Worker目录下应用程序数据保留事件,这个参数的配置应该根据你的可用的磁盘空间,应用程序的日志以及jar包都会下载到work dir中,如果你运行任务非常频繁那么这个目录很快就会填满。 |
Connecting an Application to the Cluster
在Spark集群中运行应用程序只需要在构造SparkContext时候传入master的地址,
也可以通过如下命令通过脚本交互式的方式在Spark集群中运行
./bin/spark-shell --master spark://IP:PORT
你也可以指定—total-executor-cores<numCores>参数控制spark-shell在spark集群中使用几个CPU。
Launching Spark Applications
./bin/spark-submit脚本提供了非常方便的方式将一个编译好的应用程序提交到集群中运行,spark独立集群支持两种运行模式,client模式,driver程序和spark-submit运行在同一个进程中,cluster模式,driver程序会运行在集群中的某一个worker节点中,而且如果是cluster模式提交任务后spark-submit会马上退出而不像client模式那样一直在运行。
如果你的程序是通过spark-submit提交运行,那么这个应用程序会自动分发到所有的worker节点中,如果有多个依赖jar你需要通过指定—jars参数多个使用逗号分割。
此外,独立的集群模式支持程序异常退出自动重启,要想开启这个功能需要在spark-sibmit时指定—supervise参数,如果你想kill掉这个程序则可以通过执行如下命令:
./bin/spark-class org.apache.spark.deploy.Client kill <master url> <driver ID>
你可以通过访问master的控制台(http://master:8080)获取driver id。
Resource Scheduling
Spark独立集群目前只支持FIFO的调度方式,然而,你可以通过控制每个应用程序最大的资源使用数量来达到并发用户的目的。默认的应用程序会获取集群中所有可用的CPU,这仅适合同一时间只有一个应用程序在运行。你可以通过在你的SparkConf中设置spark.cores.max参数来修改这个默认的配置。例如:
SparkConf conf=newSparkConf()
.setMaster(...)
.setAppName(...)
.set("spark.cores.max","10")
SparkContext sc=newSparkContext(conf)
此外,你还可以通过在master中配置spark.deploy.defaultCores这个参数来修改默认值,这样就不用在每个SparkConf中都配置spark.cores.max参数。conf/spark-env.sh中修改:
export SPARK_MASTER_OPTS="-Dspark.deploy.defaultCores=<value>"
这非常适合在共享的集群环境中,可以避免用户忘记配置最大CPU数量导致所有资源被这个用户独占。
Monitoring and Logging
Spark独立模式提供了一个控制台用于监视整个集群。Master和所有的worker都有自己的控制台可以查看集群以及任务状态。默认的master控制台端口是8080,这个端口可以通过配置文件或者命令行修改。
此外,应用程序的运行产生的日志会在每个节点的SPARK_HOME/work目录中,有stdout和stderr两个日志文件。
Running Alongside Hadoop
你可以在同一个机器中基于已经存在的Hadoop环境运行Spark程序,在Spark中可以通过hdfs://namenode:9000/path访问HDFS中的文件,具体的文件可以通过访问Hadoop Namenode的控制台获取。
Configuring Ports for Network Security
Spark依赖网络,需要为spark使用的相关端口设置防火墙例外。
High Availability
默认的,Spark独立集群中如果worker节点失败是可以恢复的(如果一个worker挂掉,可以将任务移动到另一个健康的worker中继续运行),然而这种任务调用都是由master完成,但是master存在单点故障问题,如果master挂掉那么新提交的应用程序将无法运行,有2种方案可以避免这个问题,如下:
Standby Masters with ZooKeeper
Overview
利用ZooKeeper提供状态存储以及leader选举,你可以在集群中运行多个master,但是这些master需要连接同一组ZooKeeper地址,其中一个master会被选举为leader其余的master则为standby。如果当前的leader挂掉,其余的standby会变成leader并且从ZooKeeper中恢复上一个leader的状态信息,然后重新开始调度。整个恢复阶段可能会花费1到2分钟,注意这个延迟仅影响新提交的应用调度,已经提交运行的应用不受影响。
Configuration
启动可恢复模式需要在spark-env中设置SPARK_DAEMON_JAVA_OPTS环境变量,配置spark.deploy.recoveryMode以及deploy.zookeeper.*相关参数。具体参数Spark配置章节。
如果你的集群中有多个master但是错误的配置了ZooKeeper,那么所有的master都会变成leader,导致所有的master都在独立的调度任务。
Details
如果ZooKeeper集群已经配置好,那么开启高可用性是非常简单的。只需要在不同的节点中启动master进程并配置好ZooKeeper的地址,可以在任何时间添加或者移除master。
当调度新应用程序或者添加新的worker节点时首先需要知道当前的leader,这个可以通过设置一个master列表来完成。例如,你可以构造SparkContext时指定spark://host1:port1,host2:port2。这会使你的SparkContext尝试在所有的master中都注册,如果host1挂掉,这个配置也可以正常工作,因为他会找到新的leader也就是host2。
这里有一个区别在注册一个master和普通的操作,当一个应用程序或者worker启动时候需要去寻找当前的leader,然后注册到leader中,一旦注册成功这些信息就会存储在ZooKeeper中。如果当前leader挂掉,那么新的leader会联系之前注册过的应用程序以及worker节点告诉他们leader已经改变,请连接新的leader,所以应用和worker甚至可以在启动时不知道新的master的存在。
由于这个特性,新的master可以在任何时间创建,你只需要关心当新的应用程序以及worker第一次注册。
Single-Node Recovery with Local File System
Overview
ZooKeeper是一个处理高可用性最好的方案,但是如果你只想在master失败后重启,那么FILESYSTEM模式可以胜任,当应用程序和worker节点注册时,他们会将状态信息写到磁盘中以用来恢复master状态。
Configuration
这种恢复模式你可以通过在spark-env中配置SPARK_DAEMON_JAVA_OPTS环境变量。
System Property | Meaning |
Spark.worker.recoveryMode | 设置为FILESYSTEM来开启单点恢复模式,默认NONE |
Spark.worker.recoveryDirectory | Spark用来存储master状态的路径,用来恢复master。 |
Details
这种解决方案可以和进程监视工具一起联合使用,例如monit,或者可以通过手动重启。
FILESYSTEM恢复方式看起来比失败后不做任何处理好一些,这种模式可能对开发和测试环境来说是次优的,尤其是当你通过stop-master.sh杀掉master进程时并不会自动清理存储的状态信息,所以当你启动新的master时会自动进入recovery模式。这会导致启动时间延迟可能会导致之前注册过的应用和worker连接超时。
目前还没有正式的支持这种方式,你可以将recovery的目录指向到NFS目录,如果之前的master挂掉,你可以在另一个机器上启动新的master,新的master也可以通过NFS中存储的状态数据恢复。以后应用程序会增加查询新的master的功能。