NameNode HA的部署方法

在部署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文件中添加如下内容,修改默认端口,避免冲突

<property>
    <name>dfs.journalnode.rpc-address</name>
    <value>0.0.0.0:8486</value>
</property>
<property>
    <name>dfs.journalnode.http-address</name>
    <value>0.0.0.0:8487</value>
</property>
<property>
    <name>dfs.journalnode.https-address</name>
    <value>0.0.0.0:8488</value>
</property>


<!-- 这个目录配置修改一下,避免冲突 -->
<property>
      <name>dfs.journalnode.edits.dir</name>
      <value>/root/software/hadoop-2.8.5_another/journal_node_data</value>
</property>

相关配置项的含义: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

<configuration>
        <property>
                <name>fs.defaultFS</name>
<!--这里用的是nameservice id,和hdfs-site.xml中的配置保持一致-->
                <value>hdfs://mycluster</value>
        </property>
        <property>
                <name>ha.zookeeper.quorum</name>
<!-- zookeeper集群 -->
                <value>zk-ip:2181</value>
         </property>
        <property>
                <name>hadoop.tmp.dir</name>
                <value>/root/software/hadoop-2.8.5/hadoop_tmp</value>
        </property>
        <property>
                <name>io.file.buffer.size</name>
                <value>4096</value>
        </property>
</configuration>

3、配置etc/hadoop/hdfs-site.xml

<configuration>
<!-- 完全分布式集群名称,nameservice id,core-site.xml中的fs.default.xml用的就是这里的配置-->
    <property>
        <name>dfs.nameservices</name>
        <value>mycluster</value>
    </property>
<!-- 集群中NameNode节点名称,随意起名,可以保持不变 -->
    <property>
        <name>dfs.ha.namenodes.mycluster</name>
        <value>nn1,nn2</value>
    </property>
<!-- nn1的RPC通信地址,用域名和IP都可以,保险用IP -->
    <property>
      <name>dfs.namenode.rpc-address.mycluster.nn1</name>
      <value>1.2.3.4:8020</value>
    </property>
<!-- nn2的RPC通信地址,用域名和IP都可以,保险用IP -->
    <property>
      <name>dfs.namenode.rpc-address.mycluster.nn2</name>
      <value>1.1.1.1:8020</value>
    </property>
<!-- nn1的http通信地址,用域名和IP都可以,保险用IP;百度内网改成8070端口便于访问 -->
    <property>
        <name>dfs.namenode.http-address.mycluster.nn1</name>
        <value>1.2.3.4:50070</value>
    </property>
<!-- nn2的http通信地址,用域名和IP都可以,保险用IP,百度内网改成8070端口便于访问 -->
    <property>
          <name>dfs.namenode.http-address.mycluster.nn2</name>
          <value>1.1.1.1:50070</value>
    </property>
<!-- 指定NameNode元数据在JournalNode上的存放位置,保持此格式,修改ip和端口;mycluster和nameservice保持一致 -->
<!-- Journal node的默认端口都是8485,如有特殊,需修改-->
    <property>
          <name>dfs.namenode.shared.edits.dir</name>
            <value>qjournal://1.2.3.4:8485;1.1.1.1:8485;1.1.1.1:8486/mycluster</value>
    </property>
    <!-- 访问代理类:client,mycluster,active配置失败自动切换实现方式-->
    <property>
          <name>dfs.client.failover.proxy.provider.mycluster</name>
          <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>
    <!-- 配置隔离机制,即同一时刻只能有一台服务器对外响应 -->
    <property>
          <name>dfs.ha.fencing.methods</name>
          <value>sshfence</value>
    </property>
<!-- 使用隔离机制时需要ssh无秘钥登录,根据具体使用到的用户来进行配置,一般是/root的用户 -->
    <property>
          <name>dfs.ha.fencing.ssh.private-key-files</name>
          <value>/root/.ssh/id_rsa</value>
    </property>
<!-- 声明journalnode服务器存储目录,根据线上目录情况调整-->
    <property>
          <name>dfs.journalnode.edits.dir</name>
          <value>/root/software/hadoop-2.8.5/journal_node_data</value>
    </property>
    <!-- 关闭权限检查-->
    <property>
        <name>dfs.permissions.enable</name>
        <value>false</value>
    </property>
    <!--开启Automatic Failover模式-->
    <property>
           <name>dfs.ha.automatic-failover.enabled</name>
           <value>true</value>
     </property>

    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:/root/software/hadoop-2.8.5/hdfs/namenode</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:/root/software/hadoop-2.8.5/hdfs/datanode</value>
    </property>
</configuration>

4、配置etc/hadoop/mapred-site.xml

$ cp mapred-site.xml.template mapred-site.xml
增加如下内容
<configuration>
     <!--指定mapreduce运行框架-->
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <property>
        <name>mapreduce.jobhistory.address</name>
<!--历史服务的通信地址 -->
        <value>node2:10020</value>
    </property>
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
<!--历史服务的web ui地址 -->
        <value>node2:19888</value>
    </property>
</configuration>

5、配置etc/hadoop/yarn-site.xml

<configuration>
    <property>
        <name>yarn.resourcemanager.hostname</name>
<!--yarn resourceManager地址 -->
        <value>node2</value>
    </property>
    <property>
        <name>yarn.resourcemanager.address</name>
        <value>${yarn.resourcemanager.hostname}:8032</value>
    </property>
    <property>
        <name>yarn.resourcemanager.scheduler.address</name>
        <value>${yarn.resourcemanager.hostname}:8030</value>
    </property>
    <property>
        <name>yarn.resourcemanager.webapp.address</name>
        <value>${yarn.resourcemanager.hostname}:8088</value>
    </property>
    <property>
        <name>yarn.resourcemanager.webapp.https.address</name>
        <value>${yarn.resourcemanager.hostname}:8090</value>
    </property>
    <property>
        <name>yarn.resourcemanager.resource-tracker.address</name>
        <value>${yarn.resourcemanager.hostname}:8031</value>
    </property>
    <property>
        <name>yarn.resourcemanager.admin.address</name>
        <value>${yarn.resourcemanager.hostname}:8033</value>
    </property>
    <property>
        <name>yarn.nodemanager.local-dirs</name>
        <value>/root/software/hadoop-2.8.5/hadoop_tmp/yarn/local</value>
    </property>
    <property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.nodemanager.remote-app-log-dir</name>
        <value>/root/software/hadoop-2.8.5/hadoop_tmp/logs</value>
    </property>
    <property>
        <name>yarn.log.server.url</name>
        <value>http://node2:19888/jobhistory/logs/</value>
        <description>URL for job history server</description>
    </property>
    <property>
        <name>yarn.nodemanager.vmem-check-enabled</name>
        <value>false</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
        <value>org.apache.hadoop.mapred.ShuffleHandler</value>
    </property>
    <property>
        <name>yarn.nodemanager.resource.memory-mb</name>
        <value>2048</value>
    </property>
     <property>
        <name>yarn.scheduler.minimum-allocation-mb</name>
        <value>512</value>
    </property>
    <property>
        <name>yarn.scheduler.maximum-allocation-mb</name>
        <value>4096</value>
    </property>
    <property>
        <name>mapreduce.map.memory.mb</name>
        <value>2048</value>
    </property>
    <property>
        <name>mapreduce.reduce.memory.mb</name>
        <value>2048</value>
    </property>
    <property>
        <name>yarn.nodemanager.resource.cpu-vcores</name>
        <value>1</value>
    </property>
</configuration>

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

 

 

Flink中的相关配置:

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,观察现象。

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值