大数据组件高可用

一、Spark高可用

Spark Standalone集群是Master-Slaves架构的集群模式,和大部分的Master-Slaves结构集群一样,存在着Master单点故障的问题。如何解决这个单点故障的问题,Spark提供了两种方案:

  • 基于文件系统的单点恢复(Single-Node Recovery with Local File system)
  • 基于zookeeper的Standby Masters(Standby Masters with ZooKeeper)

ZooKeeper提供了一个Leader Election机制,利用这个机制可以保证虽然集群存在多个Master,但是只有一个是Active的,其他的都是Standby。当Active的Master出现故障时,另外的一个Standby Master会被选举出来。由于集群的信息,包括Worker, Driver和Application的信息都已经持久化到文件系统,因此在切换的过程中只会影响新Job的提交,对于正在进行的Job没有任何的影响。加入ZooKeeper的集群整体架构如下图所示。

 

本文的测试是在Spark0.9.0 Standalone ,同样适用于Spark1.0.0 Standalone 以上版本。

1.基于文件系统的单点恢复
主要用于开发或测试环境。当spark提供目录保存spark Application和worker的注册信息,并将他们的恢复状态写入该目录中,这时,一旦Master发生故障,就可以通过重新启动Master进程(sbin/start-master.sh),恢复已运行的spark Application和worker的注册信息。
基于文件系统的单点恢复,主要是在spark-env里对SPARK_DAEMON_Java_OPTS设置:

System propertyMeaning

spark.deploy.recoveryMode
Set to FILESYSTEM to enable single-node recovery mode (default: NONE).(设成FILESYSTEM , 缺省值为NONE)

spark.deploy.recoveryDirectory
The directory in which Spark will store recovery state, accessible from the Master’s perspective.(Spark 保存恢复状态的目录)

可以考虑使用NFS的共享目录来保存Spark恢复状态。 

1.1配置

[root@bigdata001 spark]# vi conf/spark-env.sh

添加property

export SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=FILESYSTEM -Dspark.deploy.recoveryDirectory=/nfs/spark/recovery"

1.2测试

1.启动Spark Standalone集群:[root@bigdata001 spark]# ./sbin/start-all.sh 

2.启动一个spark-shell客户端并做部分操作后,然后用sbin/stop-master.sh杀死Master进程

[root@bigdata003 spark]# MASTER=spark://bigdata001:7077 bin/spark-shell

[root@bigdata001 spark]# ./sbin/stop-master.sh

3.测试结果:可以在bigdata003看到information,连接不上master。

14/08/26 13:54:01 WARN AppClient$ClientActor: Connection to akka.tcp://sparkMaster@bigdata001:7077 failed; waiting for master to reconnect...14/08/26 13:54:01 WARN SparkDeploySchedulerBackend: Disconnected from Spark cluster! Waiting for reconnection...14/08/26 13:54:01 WARN AppClient$ClientActor: Connection to akka.tcp://sparkMaster@bigdata001:7077 failed; waiting for master to reconnect...14/08/26 13:54:01 WARN AppClient$ClientActor: Could not connect to akka.tcp://sparkMaster@bigdata001:7077: akka.remote.EndpointAssociationException: Association failed with [akka.tcp://sparkMaster@bigdata001:7077]

4.重新启动一下master,可以恢复正常:

[root@bigdata001 spark]# ./sbin/start-master.sh 

 

2.Standby Masters with ZooKeeper

用于生产模式。其基本原理是通过zookeeper来选举一个Master,其他的Master处于Standby状态。

将Standalone集群连接到同一个ZooKeeper实例并启动多个Master,利用zookeeper提供的选举和状态保存功能,可以使一个Master被选举,而其他Master处于Standby状态。如果现任Master死去,另一个Master会通过选举产生,并恢复到旧的Master状态,然后恢复调度。整个恢复过程可能要1-2分钟。

注意:

  • 这个过程只会影响新Application的调度,对于在故障期间已经运行的 application不会受到影响。
  • 因为涉及到多个Master,所以对于应用程序的提交就有了一点变化,因为应用程序需要知道当前的Master的IP地址和端口。这种HA方案处理这种情况很简单,只需要在SparkContext指向一个Master列表就可以了,如spark://host1:port1,host2:port2,host3:port3,应用程序会轮询列表。

该HA方案使用起来很简单,首先启动一个ZooKeeper集群,然后在不同节点上启动Master,注意这些节点需要具有相同的zookeeper配置(ZooKeeper URL 和目录)。

System propertyMeaning

spark.deploy.recoveryMode
Set to ZOOKEEPER to enable standby Master recovery mode (default: NONE).

spark.deploy.zookeeper.url
The ZooKeeper cluster url (e.g., 192.168.1.100:2181,192.168.1.101:2181).

spark.deploy.zookeeper.dir
The directory in ZooKeeper to store recovery state (default: /spark).

 Master可以在任何时候添加或移除。如果发生故障切换,新的Master将联系所有以前注册的Application和Worker告知Master的改变。

注意:不能将Master定义在conf/spark-env.sh里了,而是直接在Application中定义。涉及的参数是 exportSPARK_MASTER_IP=bigdata001,这项不配置或者为空。否则,无法启动多个master。

2.1 配置

[root@bigdata001 spark]# vi conf/spark-env.sh

添加Property

#ZK HAexport SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=bigdata001:2181,bigdata002:2181,bigdata003:2181 -Dspark.deploy.zookeeper.dir=/spark"

2.2 测试

1.前提:zookeeper集群已经启动。

2.关闭集群后,重新启动spark集群:

[root@bigdata001 spark]# ./sbin/stop-all.sh  [root@bigdata001 spark]# ./sbin/start-all.sh

3.在另一个节点上,启动新的master:[root@bigdata002 spark]# ./sbin/start-master.sh 

4.查看Web UI:http://bigdata001:8081/

 

5.启动一个spark-shell客户端:[root@bigdata003 spark]# MASTER=spark://bigdata001:7077,bigdata002:7077 bin/spark-shell

MASTER is spark://bigdata001:7077,bigdata002:7077=-====-----------------------/home/zjw/tachyon/tachyon-0.4.1/target/tachyon-0.4.1-jar-with-dependencies.jar:/home/zjw/tachyon/tachyon-0.4.1/target/tachyon-0.4.1-jar-with-dependencies.jar:/home/zjw/tachyon/tachyon-0.4.1/target/tachyon-0.4.1-jar-with-dependencies.jar:/home/zjw/tachyon/tachyon-0.4.1/target/tachyon-0.4.1-jar-with-dependencies.jar::/src/java/target/mesos-0.19.0.jar:/src/java/target/mesos-0.19.0.jar:/root/spark/conf:/root/spark/assembly/target/scala-2.10/spark-assembly-0.9.0-incubating-hadoop2.2.0.jar*********RUNNER=/home/zjw/jdk1.7/jdk1.7.0_51//bin/java*********CLASSPATH=/home/zjw/tachyon/tachyon-0.4.1/target/tachyon-0.4.1-jar-with-dependencies.jar:/home/zjw/tachyon/tachyon-0.4.1/target/tachyon-0.4.1-jar-with-dependencies.jar:/home/zjw/tachyon/tachyon-0.4.1/target/tachyon-0.4.1-jar-with-dependencies.jar:/home/zjw/tachyon/tachyon-0.4.1/target/tachyon-0.4.1-jar-with-dependencies.jar::/src/java/target/mesos-0.19.0.jar:/src/java/target/mesos-0.19.0.jar:/root/spark/conf:/root/spark/assembly/target/scala-2.10/spark-assembly-0.9.0-incubating-hadoop2.2.0.jar*********JAVA_OPTS=-Dspark.executor.uri=hdfs://192.168.1.101:8020/user/spark/spark-0.9.2.tar.gz -Dspark.akka.frameSize=20   -Djava.library.path= -Xms512m -Xmx512m

6.停掉正在service的Master:[root@bigdata001 spark]# ./sbin/stop-master.sh

 spark-shell输出如下信息:用sbin/stop-master.sh杀死bigdata001 的Master进程,这时saprk-shell花费了30秒左右的时候切换到bigdata002 上的Master了。

14/08/26 13:54:01 WARN AppClient$ClientActor: Connection to akka.tcp://sparkMaster@bigdata001:7077 failed; waiting for master to reconnect...14/08/26 13:54:01 WARN SparkDeploySchedulerBackend: Disconnected from Spark cluster! Waiting for reconnection...14/08/26 13:54:01 WARN AppClient$ClientActor: Connection to akka.tcp://sparkMaster@bigdata001:7077 failed; waiting for master to reconnect...14/08/26 13:54:01 WARN AppClient$ClientActor: Could not connect to akka.tcp://sparkMaster@bigdata001:7077: akka.remote.EndpointAssociationException: Association failed with [akka.tcp://sparkMaster@bigdata001:7077]14/08/26 13:54:01 WARN AppClient$ClientActor: Connection to akka.tcp://sparkMaster@bigdata001:7077 failed; waiting for master to reconnect...14/08/26 13:54:01 WARN AppClient$ClientActor: Could not connect to akka.tcp://sparkMaster@bigdata001:7077: akka.remote.EndpointAssociationException: Association failed with [akka.tcp://sparkMaster@bigdata001:7077]14/08/26 13:54:01 WARN AppClient$ClientActor: Connection to akka.tcp://sparkMaster@bigdata001:7077 failed; waiting for master to reconnect...14/08/26 13:54:01 WARN AppClient$ClientActor: Could not connect to akka.tcp://sparkMaster@bigdata001:7077: akka.remote.EndpointAssociationException: Association failed with [akka.tcp://sparkMaster@bigdata001:7077]14/08/26 13:54:01 WARN AppClient$ClientActor: Connection to akka.tcp://sparkMaster@bigdata001:7077 failed; waiting for master to reconnect...14/08/26 13:54:30 INFO AppClient$ClientActor: Master has changed, new master is at spark://bigdata002:7077

7.查看UI监控器,这是Active Master是bigdata002。正在运行的Application资源没发生变化。

http://bigdata002:8082/

 

设计理念
      为了解决Standalone模式下的Master的SPOF,Spark采用了ZooKeeper提供的选举功能。Spark并没有采用ZooKeeper原生的Java API,而是采用了Curator,一个对ZooKeeper进行了封装的框架。采用了Curator后,Spark不用管理与ZooKeeper的连接,这些对于Spark来说都是透明的。Spark仅仅使用了100行代码,就实现了Master的HA。

进阶源码学习Spark技术内幕:Master基于ZooKeeper的High Availability(HA)源码实现

参考资料

http://www.cnblogs.com/hseagle/p/3673147.html

https://spark.apache.org/docs/0.9.0/spark-standalone.html#standby-masters-with-zookeeper

 

二、HDFS高可用

实现NameNode高可用性。主要处理如下几个关键问题:

  1. 元数据的备份
  2. 故障节点发现
  3. 故障节点隔离
  4. 备用节点切换

CDH1.0高可用方案如下:

图1-1 CDHv1.0 高可用方案

    1. CDHv1.0 通过将元数据写入共享存储系统来实现NameNode元数据的备份。活动NameNode的更新直到共享存储系统的元数据也更新完成才算完成。备用NameNode定期从共享文件系统同步元数据,并创建检查点,活动NameNode失败后,备用节点从检查点开始恢复元数据,恢复完成后上线工作。
    2. 活动NameNode通过ZooKeeper选举确认,活动NameNode持有ZooKeeper上的一个临时节点,zkfc注册了该节点的观察器,当活动NameNode失效,临时节点将被zookeeper删除,zkfc将获得通知,按照配置对失效节点进行隔离,并将备用节点转换为活动节点。
    3. CDHv1.0提供两种方式实现对故障节点的隔离,ssh和shell。ssh方式通过ssh服务登入到故障节点(如果可能),杀死活动NameNode进程。shell方式执行用户自定义的脚本,这为引入专用的fencing服务器提供了可能。
    4. 备用节点完成元数据同步后,切换为Active状态,上线提供服务。

3.2.1 配置NameServiceID

HDFS NameNode是一个名字空间管理节点,对HDFS集群提供名字空间管理服务。从Apache Hadoop 2.0开始,HDFS通过引入Federation特性来支持多个相互隔离的名字空间,这些名字空间使用NameServiceID来标识。HA集群同样使用NameServiceID来区别不同的HDFS名字空间。设置NameServiceID的涉及的配置项和配置文件如下。

  • 配置项名:dfs.nameservices
  • 配置文件:hdfs-site.xml
  • 配置示例:

hdfs-site.xml
< property> 
<name>dfs.nameservices</name> 
<value>hacluster</value>
</property>
此时,NameServiceID为hacluster。
注意:Hadoop Federation特性也使用dfs.nameservices来标识不同的名字空间,因此,如果需要使用Federation特性,dfs.nameservices应为以逗号分隔开的名字空间管理服务列表,如"cluster1,cluster2…"。

3.2.2 配置NameNode

在高可用配置下,使用NameServiceID作为HDFS的逻辑名称,一个NameServiceID下可以有多个NameNode(目前最多支持2个),一个为活动NameNode(状态为Active),其他为备用NameNode(状态为Standby)。处于活动状态的NameNode在存活期间作为唯一提供名字空间管理服务的节点管理HDFS的元数据。多个NameNode通过NameNodeID来区分,NameNodeID是NameNode的逻辑名,可任意选取(建议与NameNode所在节点的主机名一致)。HA模式涉及NameNode的配置项和配置文件如下:

  • 配置项名:

    配置项名

    说明

    fs.defaultFS(MRv1: fs.default.name)

    HDFS路径前缀,当HDFS客户端在路径中没有提供HDFS NameNode RPC接口地址时,将使用该配置项。对于Yarn框架,配置fs.defaultFS。对于MRv1,则配置fs.default.name。在高可用集群中使用NameServiceID来代替实际节点的主机名。

    dfs.ha.namenodes.{NameServiceID}

    配置高可用集群中NameNode的逻辑名称(NameNodeID)。{NameServiceID}为对应的高可用集群的NameServiceID。不同的名字服务集群需单独配置这一项。

    dfs.namenode.rpc-address. 
    {NameServiceID}.{NameNodeID}

    配置NameNode的rpc接口地址。{NameServiceID}为对应的高可用集群的NameServiceID,{NameNodeID}为集群中对于的NameNode的逻辑名称(NameNodeID)。

    dfs.namenode.http-address. 
    {NameServiceID}.{NameNodeID}

    配置NameNode的WebUI的Http地址。{NameServiceID}为对应的高可用集群的NameServiceID,{NameNodeID}为集群中对于的NameNode的逻辑名称(NameNodeID)。

    dfs.namenode.shared.edits.dir

    配置NameNode元数据在共享存储系统(如nfs)中的路径,该路径应符合POSIX标准,可通过POSIX接口访问。

  • 配置文件:hdfs-site.xml、core-site.xml
  • 配置示例:

配置HDFS逻辑路径
core-site.xml
<property> 
<name>fs.defaultFS</name> 
<!—MRv1配置fs.default.name -->
<value>hdfs://hacluster</value> 
</property>
配置高可用NameNode的逻辑名称 
hdfs-site.xml
<property> 
<name>dfs.ha.namenodes.hacluster</name>
<value>nn1,nn2</value> 
</property>
nn1、nn2为NameNode的逻辑名称,即NameNodeID。
配置NameNode高可用服务监听RPC地址
hdfs-site.xml
<property> 
<name>dfs.namenode.rpc-address.hacluster.nn1</name> 
<value>namenode1:8020</value> 
</property> 
<property> 
<name>dfs.namenode.rpc-address.hacluster.nn2</name> 
<value>namenode2:8020</value> 
</property>
设置namenode Web接口
hdfs-site.xml
<property> 
<name>dfs.namenode.http-address.hacluster.nn1</name> 
<value> namenode1:50070</value> 
</property> 
<property> 
<name>dfs.namenode.http-address.hacluster.nn2</name> 
<value> namenode2:50070</value> 
</property>
设置元数据共享目录
hdfs-site.xml
<property> 
<name>dfs.namenode.shared.edits.dir</name>
<value>file:///nfs</value>
</property>
file:///nfs为nfs共享目录的URL。

3.2.3 配置Client Failover

在Apache Hadoop2.0中,HDFS客户端使用哪个类与活动NameNode交互是可以配置的,当前版本只提供一个实现:org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider,因此,如非必要,请不要改变该配置。

  • 配置项名:dfs.nameservices
  • 配置文件:hdfs-site.xml
  • 配置示例:

hdfs-site.xml
<property> 
<name>dfs.client.failover.proxy.provider.hacluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>

3.2.4 配置Fencing方式

Fencing是集群高可用性方案中需要处理的重要的问题。Fencing的作用主要是隔离故障节点,防止出现脑裂现象。CDHv1.0中提供两种隔离方式,ssh和shell方式。ssh方式在故障切换前,发起故障切换的节点通过ssh登入到活动节点并强制关闭进程来完成故障隔离,ssh方式需要给定一组私钥,以便登入到活动节点,在配置项中以逗号隔开。Shell方式通过指定一组自定义的脚本来实现节点的故障隔离。
对于ssh模式,涉及的配置项和配置文件如下:

  • 配置项名:

    配置项

    说明

    dfs.ha.fencing.methods

    指定Fencing方法

    dfs.ha.fencing.ssh.private-key-files

    设置一组私钥,以逗号隔开

    dfs.ha.fencing.ssh.connect-timeout

    设置ssh超时

  • 配置文件:hdfs-site.xml
  • 配置示例:

hdfs-site.xml
<property> 
<name>dfs.ha.fencing.methods</name> 
<value>sshfence</value> 
<!—如果非标准用户,可以在该配置项中指定,指定方式如下:
sshfence([[username][:port]])
-->
</property> 
<property> 
<name>dfs.ha.fencing.ssh.private-key-files</name> 
<value>/root/.ssh/id_rsa</value> 
</property> 
<property>
<name> dfs.ha.fencing.ssh.connect-timeout</name> 
<value>50000</value> 
</property>
对于shell模式,涉及的配置项和配置文件如下:

  • 配置项名:
  • dfs.ha.fencing.methods
  • 配置文件:hdfs-site.xml
  • 配置示例:

hdfs-site.xml
<property> 
<name>dfs.ha.fencing.methods</name> 
<value> shell(${PathToShell} arg1 arg2 ...) </value> 
</property>
CDH提供一组环境变量,可作为参数传入shell中。参数列表如下:

环境变量

说明

$target_host

需要被隔离的节点主机名

$target_port

需要被隔离的主机的IPC端口

$target_address

$target_host: $target_port

$ target_nameserviceid

需要被隔离的NameNode对应的NameServiceID

$target_namenodeid

需要被隔离的NameNode对应的NameNodeID

3.2.5 配置故障自动切换

CDH可以手动进行故障切换,也可以自动进行。要实现自动故障切换需要进行一些额外的配置,涉及的配置项和配置文件如下:

  • 配置项名

    配置项

    说明

    dfs.ha.automatic-failover.enabled

    设置启用自动故障切换特性

    ha.zookeeper.quorum

    设置HA使用的zookeeper集群

  • 配置文件:hdfs-site.xml
  • 配置示例

hdfs-site.xml
<property> 
<name>dfs.ha.automatic-failover.enabled</name> 
<value>true</value> 
</property> 
<property> 
<name>ha.zookeeper.quorum</name>
<value>hazknode1:2181,hazknode2:2181,hazknode3:2181</value> 
</property>
配置完成后,需初始化Zookeeper上的HA状态,使用下述命令:
$ hdfs zkfc -formatZK

初始化HA

使用HA特性需要首先初始化共享存储中的元数据。

  • 对于新的HDFS集群,执行namenode –format格式化一个namendoe节点,然后,将该节点的namenode元数据目录复制到另一个备用节点的对于路径下即可。
  • 对于已有的HDFS集群,需要运行下述命令来初始化共享存储系统中的NameNode元数据:

$hdfs namenode -initializeSharedEdits
执行完上述步骤后,即可按一般方式启动HDFS集群即可。

验证HA配置

启动集群后,可以使用如下方式验证HA特性是否正常运行。

  • 通过ssh客户端登入到活动NameNode节点
  • 执行jps找到NameNode的PID
  • 执行kill -9 {NameNode PID}来模拟因此JVM崩溃
  • 等待5秒(该时间可配,ha.zookeeper.session-timeout.ms。该值不应太小,以免网络扰动导致频繁的故障切换),查看Standby NameNode的Web界面,看该节点是否转为Active状态。如果是,说明HA正常工作,如果不是,请检查namenode和zkfc的日志。在自动故障切换模式下,Fencing失败可导致故障切换的失败

管理HA集群

CDH提供hdfs haadmin来管理HA集群。可通过hdfs haadmin –help <command>获取特定命令的帮助信息。hdfs haadmin提供的功能如下:

命令名

命令格式

说明

transitionToActive

-transitionToActive <serviceId>

将serviceId切换为Active状态

transitionToStandby

-transitionToStandby <serviceId>

将serviceId切换为Standby状态

failover

failover [forcefence] [-forceactive] <serviceId1> <serviceId2>

执行故障切换,从serviceId1切换到serviceId2。附加选项: 
--forcefence 
强制执行Fencing操作 
--forceactive 
强制将serviceId2切换为活动状态(不论serviceId2是否准备就绪,如是否完成Fencing,是否完成元数据同步等)

getServiceState

-getServiceState <serviceId>

获取serviceId的状态(standby/active)

checkHealth

-checkHealth <serviceId>

检查serviceId的状态,检查失败时返回非零状态码

help

-help <command>

获取帮助

三、Web服务高可用

 使用keepalived+nginx实现。

keepalived负责监控nginx状态,当nginx挂掉后重启nginx服务;keepalived配置主备节点,主备节点配相同的虚拟IP,即使一个keepalived宕掉,虚拟IP仍然可用

nginx负责转发用户(多是浏览器发来的)请求到后端Web服务器(如Tomcat),这样nginx也实现了Web服务负载均衡

 

nginx.conf 配置文件:

user  root;
worker_processes  4;

error_log /var/log/nginx/error.log;
pid        /var/run/nginx/nginx.pid;

events     {
               use epoll; 
               worker_connections  1024;
           }

http{
    include mime.types;
    default_type application/octet-stream;
    server_tokens off;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    upstream web-app-pool{
                  # hash $remote_addr consistent;
                  ip_hash;
                  server host01:8580 weight=3 max_fails=3 fail_timeout=30s;
                  server host02:8580 weight=3 max_fails=3 fail_timeout=30s;
    }
    upstream web-app2-pool{
                  # hash $remote_addr consistent;
                  ip_hash;
                  server host01:8680 weight=3 max_fails=3 fail_timeout=30s;
                  server host02:8680 weight=3 max_fails=3 fail_timeout=30s;
    }

    log_format  main '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" "$upstream_addr" "$upstream_status" "$upstream_response_time" "$request_time" ';

    access_log  /var/log/nginx/access.log main;
 
    server {
                listen 8880;
                server_name host01;
                proxy_set_header           Host $host;
                proxy_set_header  X-Real-IP  $remote_addr;
                proxy_set_header           X-Forwarded-For $proxy_add_x_forwarded_for;
                client_max_body_size  100m;
                location /app-web {
                       proxy_pass  http://web-app-pool;
                }
                location /app2-web { #配置反向代理的第一个tomcat服务
                       proxy_pass  http://web-app2-pool;
                }
    }
}

 keepalived.conf 配置文件:

! Configuration File for keepalived
global_defs {
   smtp_server host1
   smtp_connect_timeout 30
   router_id ngnix_master
}

vrrp_script chk_nginx {
   script "/etc/keepalived/check_nginx.sh"
   interval 10
   weight 5
   rise 1
}

vrrp_instance VI_1 {
           state MASTER
        interface eth0
    virtual_router_id 58
           priority 100
        advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.17.139.113
    }
    track_script {
        chk_nginx
    }
}

virtual_server 10.17.139.113 8980 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    nat_mask 255.255.255.0
    persistence_timeout 50
    protocol TCP

    real_server 10.17.139.240 8980 {
        weight 1
    TCP_CHECK {
        connect_timeout 10
        nb_get_retry 3
        delay_before_retry 3
        connect_port 8980
    }
    }
}

check_nginx.sh脚本负责检测nginx是否存活,如果挂了,则启动它

check_nginx.sh配置文件:

#!/bin/sh

nginxdir=/usr/lib/nginx/sbin/nginx
A=`ps -ef|grep $nginxdir|grep -v grep|wc -l`
if [ $A -eq 0 ]
then
    service nginx start
    sleep 5
A=`ps -ef|grep $nginxdir|grep -v grep|wc -l`
    if [ $A -eq 0 ]
    then
        killall keepalived
    fi
fi

三、大数据组件高可用问题

1.Kafka topic replication设为1时,单节点宕机会导致Topic有问题(已有的数据消费会有问题),解决办法是调整replication>=2

2.HBase: HDFS副本数为1导致关键文件在节点宕机后丢失,因此HBase从Master无法切换

3.Spark宕机问题
1) Spark Master(active)连接了zk leader
2) Spark Master (inactive) 与zk leader在同一个节点上
3) 宕机节点为zk leader节点
4) zk leader节点宕机,Spark Master(active)收到curator的leader选举框架的notleader调用,直接退出
5) 因为spark inactive master也在宕机节点上,所以,导致spark集群没有了master

解决办法:Spark配置3个及以上Master

原文地址:https://www.cnblogs.com/warmingsun/p/5436402.html