在部署flink的时候,发现hdfs的namenode有可能会有单点故障问题,所以给它做一个HA的部署。
1、NameNode HA模式下,active的NameNode挂掉之后,切换时间有多长?
答:根据测试来看,切换时间非常短。kill掉active的NameNode之后,再去查询standby的NameNode状态,会发现已经变成active。
具体时间可能有更多因素影响:(1)zk心跳间隔(2)NameNode的qps
2、Flink是否会受到NameNode切换的影响?
答:从运行一个路口的指标计算程序来看,没有受到影响,程序没有任何重启。
其他需额外关注的点:(1)路口增多时是否会有变化(2)任务增多时是否有变化(3)有checkpoint的任务是否会受到影响
(1)启用了HA的hadoop集群,不能再有secondary namenode了,否则会报错
(2)Flink能识别hadoop的nameservice,是因为加载了其配置,方法如下,在flink-conf.yaml文件中添加如下内容:
# 如果使用Hadoop HA的时候,一定要配置hadoop conf目录,把hadoop 集群的配置文件拷贝到这个目录里面,这样 flink就会知道hadoop-ha-nameservice的具体active的nameNode的地址。
env.hadoop.conf.dir: /root/software/hadoop-2.8.5/etc/hadoop
# 另外,其他使用hdfs路径的地方都要配置hadoop HA中core-site.xml中配置的HA nameservice,而不是用namenode的域名
此配置的介绍 : https://ci.apache.org/projects/flink/flink-docs-release-1.10/ops/config.html#env-hadoop-conf-dir
配置参考:http://moheqionglin.com/site/serialize/02006013006/detail.html
(3)当前一个nameservice只支持最多两个namenode;hadoop还支持多个nameservice(这是另外的特性了)
(4)journal node至少需要三个节点,但是只有两台机器,充分利用一下其中一台机器,部署两个进程。需要在hdfs-site.xml文件中添加如下内容,修改默认端口,避免冲突
dfs.journalnode.rpc-address
0.0.0.0:8486
dfs.journalnode.http-address
0.0.0.0:8487
dfs.journalnode.https-address
0.0.0.0:8488
dfs.journalnode.edits.dir
/root/software/hadoop-2.8.5_another/journal_node_data
相关配置项的含义:https://hadoop.apache.org/docs/r2.4.1/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml
修改hadoop-env.sh文件
# 这个配置默认是/tmp目录,如果要在一台机器上启动不同hadoop组件,需要使他们的pid不在一起,避免冲突
export HADOOP_PID_DIR=/root/software/hadoop-2.8.5_another/pids
(5)如果是一个已有的hadoop集群,从非HA变成HA,需要首先创建Journal node日志的目录,其次需要执行下面的命令进行格式化。这个在官网也有说明。
$ hdfs namenode -initializeSharedEdits
前置条件:
三台机器、机器之间已经配置免密、jdk已经安装
1、Download Hadoop
2、配置etc/hadoop/core-site.xml
fs.defaultFS
hdfs://mycluster
ha.zookeeper.quorum
zk-ip:2181
hadoop.tmp.dir
/root/software/hadoop-2.8.5/hadoop_tmp
io.file.buffer.size
4096
3、配置etc/hadoop/hdfs-site.xml
dfs.nameservices
mycluster
dfs.ha.namenodes.mycluster
nn1,nn2
dfs.namenode.rpc-address.mycluster.nn1
1.2.3.4:8020
dfs.namenode.rpc-address.mycluster.nn2
1.1.1.1:8020
dfs.namenode.http-address.mycluster.nn1
1.2.3.4:50070
dfs.namenode.http-address.mycluster.nn2
1.1.1.1:50070
dfs.namenode.shared.edits.dir
qjournal://1.2.3.4:8485;1.1.1.1:8485;1.1.1.1:8486/mycluster
dfs.client.failover.proxy.provider.mycluster
org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider
dfs.ha.fencing.methods
sshfence
dfs.ha.fencing.ssh.private-key-files
/root/.ssh/id_rsa
dfs.journalnode.edits.dir
/root/software/hadoop-2.8.5/journal_node_data
dfs.permissions.enable
false
dfs.ha.automatic-failover.enabled
true
dfs.replication
3
dfs.namenode.name.dir
file:/root/software/hadoop-2.8.5/hdfs/namenode
dfs.datanode.data.dir
file:/root/software/hadoop-2.8.5/hdfs/datanode
4、配置etc/hadoop/mapred-site.xml
$ cp mapred-site.xml.template mapred-site.xml
增加如下内容
mapreduce.framework.name
yarn
mapreduce.jobhistory.address
node2:10020
mapreduce.jobhistory.webapp.address
node2:19888
5、配置etc/hadoop/yarn-site.xml
yarn.resourcemanager.hostname
node2
yarn.resourcemanager.address
${yarn.resourcemanager.hostname}:8032
yarn.resourcemanager.scheduler.address
${yarn.resourcemanager.hostname}:8030
yarn.resourcemanager.webapp.address
${yarn.resourcemanager.hostname}:8088
yarn.resourcemanager.webapp.https.address
${yarn.resourcemanager.hostname}:8090
yarn.resourcemanager.resource-tracker.address
${yarn.resourcemanager.hostname}:8031
yarn.resourcemanager.admin.address
${yarn.resourcemanager.hostname}:8033
yarn.nodemanager.local-dirs
/root/software/hadoop-2.8.5/hadoop_tmp/yarn/local
yarn.log-aggregation-enable
true
yarn.nodemanager.remote-app-log-dir
/root/software/hadoop-2.8.5/hadoop_tmp/logs
yarn.log.server.url
http://node2:19888/jobhistory/logs/
URL for job history server
yarn.nodemanager.vmem-check-enabled
false
yarn.nodemanager.aux-services
mapreduce_shuffle
yarn.nodemanager.aux-services.mapreduce.shuffle.class
org.apache.hadoop.mapred.ShuffleHandler
yarn.nodemanager.resource.memory-mb
2048
yarn.scheduler.minimum-allocation-mb
512
yarn.scheduler.maximum-allocation-mb
4096
mapreduce.map.memory.mb
2048
mapreduce.reduce.memory.mb
2048
yarn.nodemanager.resource.cpu-vcores
1
6、配置etc/hadoop/slaves。将所有worker节点都写进文件,如果只配置一个节点,就是只在这个节点上有datenode和nodeManager
node2
node3
7、配置etc/hadoop/hadoop-env.sh
# 搜索到JAVA_HOME,修改成线上安装的jdk路径
export JAVA_HOME=/root/software/jdk1.8.0_131
8、配置etc/hadoop/yarn-env.sh
# 搜索到JAVA_HOME,修改成线上安装的jdk路径
export JAVA_HOME=/root/software/jdk1.8.0_131
9、配置etc/hadooop/mapred-env.sh
# 搜索到JAVA_HOME,修改成线上安装的jdk路径
export JAVA_HOME=/root/software/jdk1.8.0_131
10、然后通过scp命令将文件发送到其他所有机器
# 多机器地址保持一致
$ scp -r hadoop-2.8.5 root@node3:/root/software/
11、在所有机器上分别启动QJM,至少启动3台机器。(如果机器不够3台,可以做伪分布式,前文“注意”部分已经给出方法)
$ sbin/hadoop-daemon.sh start journalnode
启动后,jps会发现多了 JournalNode 进程
12、格式化NameNode并启动(注意:先格式化一台namenode,然后另一台namenode同步第一台namenode,如果两台都格式化就会有问题)
格式化namanode(只在第一次启动集群之前操作)
# 格式化第一台机器的NameNode,并启动
$ bin/hdfs namenode -format
$ sbin/hadoop-daemon.sh start namenode
# 第二个namenode同步第一个NameNode的数据
[root@hadoop003 hadoop-2.6.5]# bin/hdfs namenode -bootstrapStandby
# 启动第二个namenode
[root@hadoop003 hadoop-2.6.5]# sbin/hadoop-daemon.sh start namenode
操作完成后会发现生成了/root/software/hadoop-2.8.5/hdfs/namenode目录,下面有初始化的namenode信息。如果需要将集群数据重置,可以将下面的数据全部删除(datanode数据也删除,每个机器上都清除数据),重新格式化namenode。
13、此时,两个NameNode都是standby模式,需手动将一个NameNode设置为active
# 可以看到nn1和nn2都是standby状态
$ bin/hdfs haadmin -getServiceState nn1
standby
$ bin/hdfs haadmin -getServiceState nn2
standby
# 手动将nn1改成active状态(这里是强制操作);执行过程中需要输入y确认执行
$ bin/hdfs haadmin -transitionToActive --forcemanual nn1
# 此时再看nn1状态已经变成active
$ bin/hdfs haadmin -getServiceState nn1
active
$ bin/hdfs haadmin -getServiceState nn2
standby
14、在zookeeper上配置故障自动转移节点
[root@hadoop001 hadoop-2.6.5]# bin/hdfs zkfc -formatZK
[zk: localhost:2181(CONNECTED) 5] ls /
[zookeeper, hadoop-ha]
# 可以看到zookeeper上已经有了hadoop-ha节点了
15、启动dfs(这一步必须要执行,因为它会把DFSZKFailoverController启动起来,只有这个进程启动,才能实现故障自动切换)
$ sbin/start-dfs.sh
停止dfs(不必要)
$ sbin/stop-dfs.sh
Test
$ bin/hdfs dfs -mkdir /aa
$ bin/hdfs dfs -ls /
访问NameNode UI:http:1.2.3.4:50070
16、启动yarn(不必要)
$ sbin/start-yarn.sh
访问Yarn UI:http://1.2.3.4:8088
停止yarn
$ sbin/stop-yarn.sh
17、全部启动
$ sbin/start-all.sh
全部停止
$ sbin/stop-all.sh
18、配置环境变量(方便使用),在/etc/profile文件中增加如下配置:
export HADOOP_HOME=/root/software/hadoop-2.8.5
export PATH=$PATH:${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin
19、测试自动切换功能是否生效
# 在nn1机器上执行
$ jps
6708 DFSZKFailoverController
6549 DataNode
5814 JournalNode
6103 NameNode
6825 Jps
5021 QuorumPeerMain
# 杀掉namenode进程
[root@hadoop003 hadoop-2.6.5]# kill -9 6103
#查看nn1状态,连接不上了
$ bin/hdfs haadmin -getServiceState nn1
18/08/21 16:28:52 INFO ipc.Client: Retrying connect to server: hadoop003/192.168.170.133:8020. Already tried 0 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=1, sleepTime=1000 MILLISECONDS)
Operation failed: Call From hadoop003/192.168.170.133 to hadoop003:8020 failed on connection exception: java.net.ConnectException: Connection refused; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused
# 查看nn2状态,已经激活了
$ bin/hdfs haadmin -getServiceState nn2
active
# nn1同步nn2,并重新启动nn1
$ bin/hdfs namenode -bootstrapStandby
$ sbin/hadoop-daemon.sh start namenode
# 这时,nn1是standby状态,nn2是active状态;可以杀掉nn2,会发现自动切换到nn1
1、修改flink-conf.yaml文件,然后分发到集群所有机器上。
# 如果使用Hadoop HA的时候,一定要配置hadoop conf目录
# 如果Hadoop和Flink在同一台机器上,把hadoop 集群的配置文件拷贝到这个目录里面,这样 flink就会知道hadoop-ha-nameservice的具体active的nameNode的地址。
# 如果有Flink的机器上没有Hadoop,那么需要将Hadoop的配置拷贝到该机器的某个目录下,并配置在下面。
# 所有机器需要保持一致,避免产生问题。
env.hadoop.conf.dir: /root/software/hadoop-2.8.5/etc/hadoop
# 另外,其他使用hdfs路径的地方都要配置hadoop HA中core-site.xml中配置的HA nameservice,而不是用namenode的域名;例如:
jobmanager.archive.fs.dir: hdfs://mycluster/flink/completed-jobs/
2、启动Flink集群。(如果是已有的集群,有可能因为上面的操作产生数据丢失导致重启失败,最好将zk和hadoop中关于Flink的数据删除后再启动)
3、测试:
(1)启动一个Flink任务在运行状态(比如指标计算),手动杀死active的namenode,Flink程序无感,没有产生任何崩溃,指标照常产生。
(2)启动一个有checkpoint的程序,手动杀死active的namenode,观察现象。