高可用HDFS搭建

HDFS+HA架构图

hdfs-arch

上图大致架构包括:

  1. 利用共享存储来在两个NN间同步edits信息。以前的HDFS是share nothing but NN,现在NN又share storage,这样其实是转移了单点故障的位置,但中高端的存储设备内部都有各种RAID以及冗余硬件,包括电源以及网卡等,比服务器的可靠性还是略有提高。通过NN内部每次元数据变动后的flush操作,加上NFS的close-to-open,数据的一致性得到了保证。
  2. DN同时向两个NN汇报块信息。这是让Standby NN保持集群的最新状态的必须步骤。
  3. 用于监视和控制NN进程的FailoverController进程。显然,我们不能在NN进程内部进行心跳等信息同步,最简单的原因,一次FullGC就可以让NN挂起十几分钟,所以,必须要有一个独立的短小精悍的watchdog来专门负责监控。这也是一个松耦合的设计,便于扩展或更改,目前版本里是用ZooKeeper(简称ZK)来做同步锁,但用户可以方便的把这个Zookeeper FailoverController(简称ZKFC)替换为其他的HA方案或leader选举方案。
  4. 隔离(Fencing),防止脑裂,就是保证在任何时候只有一个主NN,包括三个方面:
    • 共享存储fencing,确保只有一个NN可以写入edits。
    • 客户端fencing,确保只有一个NN可以响应客户端的请求。
    • DN fencing,确保只有一个NN向DN下发命令,譬如删除块,复制块等等。

节点规划

hostnameip安装服务
zk1192.168.1.1zookeeper
zk2192.168.1.2zookeeper
zk3192.168.1.3zookeeper

提示:

zookeeper集群安装不在本文描述范围, 请自行参考其他文档。(zookeeper集群也可以跟datanode安装在一起)

hostnameip安装服务
nna192.168.1.4NameNode、DFSZKFailoverController
nns192.168.1.5NameNode、DFSZKFailoverController
dn1192.168.1.6JournalNode、NodeManager、DataNode
dn2192.168.1.7JournalNode、NodeManager、DataNode
dn3192.168.1.8JournalNode、NodeManager、DataNode
  • namenode服务器: 运行namenode的服务器应该有相同的硬件配置。在HA集群中,standby状态的namenode可以完成checkpoint操作,因此没必要配置Secondary namenode、CheckpointNode、BackupNode。如果真的配置了还会报错。
  • journalnode服务器: 运行的journalnode进程非常轻量,可以部署在其他的服务器上。注意:必须允许至少3个节点。当然可以运行更多,但是必须是奇数个,如3,5,7,9个等等。当运行N个节点时,系统可以容忍至少(N-1)/2个节点失败而不影响正常运行。

安装前准备

操作系统:CentOS 6.5 x86_64 JDK:1.8.0_74-b02 (JDK的安装本文不进行描述) Hadoop:hadoop-2.8.0.tar.gz Zookeeper: 3.4.6

安装过程

1. 主机名修改

登录nna节点,修改/etc/hosts文件,在后面追加如下内容:

192.168.1.1   zk1
192.168.1.2   zk2
192.168.1.3   zk3
192.168.1.4   nna
192.168.1.5   nns
192.168.1.6   dn1
192.168.1.7   dn2
192.168.1.8   dn3

分发到其它主机,下面以zk1为例:

scp /etc/hosts root@zk1:/etc

2. 创建hadoop用户

登录除zk外的主机,分别创建hadoop用户:

useradd hadoop

3. 添加ssh信任

su - hadoop

ssh-keygen -t rsa  #一直按回车键,直到交互结束。会在 ~/.ssh/ 目录下生成 id_rsa.pub 文件

cat ~/.ssh/id_rsa.pub  # 拷贝里面的内容

# 在所有主机中重复以上步骤

touch ~/.ssh/authorized_keys && chmod 644 ~/.ssh/authorized_keys

vi ~/.ssh/authorized_keys  # 将所有主机的 id_rsa.pub 文件中的内容都拷贝到此文件中,并将此文件分发到所有主机。注意是hadoop用户下的 ~/.ssh/authorized_keys 文件

做完上述动作后,可以使用如下命令验证免密登录是否设置成功,若登录过程不需要输入密码则已设置成功:

su - hadoop
ssh nns

有必要在所有机器上都相互验证下。

4. 线程数与打开文件句柄数修改

Hdaoop会在同一时间使用很多的文件句柄.大多数linux系统使用的默认值1024是不能满足的。

编辑/etc/security/limits.conf

* soft nofile 65535
* hard nofile 65535
* soft nproc 16384
* hard nproc 16384

若操作系统为centos6.5,还需编辑/etc/security/limits.d/90-nproc.conf

*          soft    nproc     1024
root       soft    nproc     unlimited
hadoop soft nproc 16384
hadoop hard nproc 16384

除zk外的主机,请都完成上述设置。

5. 关闭防火墙

由于hadoop的节点之间需要通信(RPC机制),这样一来就需要监听对应的端口,这里我就直接将防火墙关闭了,命令如下:

chkconfig  iptables off

6. 开启时钟同步

各个节点的时间如果不同步,会出现启动异常,或其他原因。

service ntpd start

7. 环境变量配置

export JAVA_HOME=/usr/lib/java
export HADOOP_HOME=/home/hadoop/hadoop
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

8. 核心文件配置

创建文件夹:

mkdir -p /home/hadoop/tmp
mkdir -p /home/hadoop/data/tmp/journal
mkdir -p /home/hadoop/data/dfs/name
mkdir -p /home/hadoop/data/dfs/data
mkdir -p /home/hadoop/data/yarn/local
mkdir -p /home/hadoop/log/yarn

解压安装包:

tar -xzvf hadoop-2.8.0.tar.gz
ln -s hadoop-2.8.0 hadoop
  • $HADOOP_HOME/etc/hadoop/core-site.xml
<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://cluster1</value>
    </property>
    <property>
        <name>io.file.buffer.size</name>
        <value>131072</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/home/hadoop/tmp</value>
    </property>
    <property>
        <name>hadoop.proxyuser.hadoop.hosts</name>
        <value>*</value>
    </property>
    <property>
        <name>hadoop.proxyuser.hadoop.groups</name>
        <value>*</value>
    </property>
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>zk1:2181,zk2:2181,zk3:2181</value>
    </property>
</configuration>
  • $HADOOP_HOME/etc/hadoop/hdfs-site.xml
<configuration>
    <property>
        <name>dfs.nameservices</name>
        <value>cluster1</value>
    </property>
    <property>
        <name>dfs.ha.namenodes.cluster1</name>
        <value>nna,nns</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.cluster1.nna</name>
        <value>nna:9000</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.cluster1.nns</name>
        <value>nns:9000</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.cluster1.nna</name>
        <value>nna:50070</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.cluster1.nns</name>
        <value>nns:50070</value>
    </property>
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://dn1:8485;dn2:8485;dn3:8485/cluster1</value>
    </property>
    <property>
        <name>dfs.client.failover.proxy.provider.cluster1</name>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>
    <property>
        <name>dfs.ha.fencing.methods</name>
        <value>sshfence</value>
    </property>
    <property>
        <name>dfs.ha.fencing.ssh.private-key-files</name>
        <value>/home/hadoop/.ssh/id_rsa</value>
    </property>
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/home/hadoop/data/tmp/journal</value>
    </property>
    <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/home/hadoop/data/dfs/name</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>/home/hadoop/data/dfs/data</value>
    </property>
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <property>
        <name>dfs.webhdfs.enabled</name>
        <value>true</value>
    </property>
    <property>
        <name>dfs.journalnode.http-address</name>
        <value>0.0.0.0:8480</value>
    </property>
    <property>
        <name>dfs.journalnode.rpc-address</name>
        <value>0.0.0.0:8485</value>
    </property>
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>zk1:2181,zk2:2181,zk3:2181</value>
    </property>
</configuration>
  • $HADOOP_HOME/etc/hadoop/mapred-site.xml
<configuration>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>nna:10020</value>
    </property>
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>nna:19888</value>
    </property>
</configuration>
<configuration>
    <property>
        <name>hbase.rootdir</name>
        <value>hdfs://cluster1/hbase</value>
    </property>
    <property>
        <name>hbase.cluster.distributed</name>
        <value>true</value>
    </property>
    <property>
        <name>hbase.zookeeper.quorum</name>
        <value>172.17.18.9:2181,172.17.18.112:2181,172.17.17.19:2181</value>
    </property>
</configuration>
  • $HADOOP_HOME/etc/hadoop/slaves
dn1
dn2
dn3

将配置好的hadoop复制到其它节点:

scp -r $HADOOP_HOME/ nns:~/
scp -r $HADOOP_HOME/ dn1:~/
scp -r $HADOOP_HOME/ dn2:~/
scp -r $HADOOP_HOME/ dn3:~/

9. 启动

由于我们配置了QJM,所以我们需要先启动QJM的服务,启动顺序如下所示:

  1. 启动zookeeper集群。启动完成之后可以输入zkServer.sh status查看启动状态,会出现一个leader和两个follower。输入jps,会显示启动进程:QuorumPeerMain
  2. 在NN节点上(选一台即可,这里我选择的是一台预NNA节点),然后启动journalnode服务,命令如下:hadoop-daemons.sh start journalnode。或者单独进入到每个DN输入启动命令:hadoop-daemon.sh start journalnode。输入jps显示启动进程:JournalNode
  3. 接着若是配置后首次启动,需要格式化HDFS,命令如下:hadoop namenode –format
  4. 之后我们需要格式化ZK,命令如下:hdfs zkfc –formatZK
  5. 接着我们启动hdfs,命令如下:start-dfs.sh,我们在nna输入jps查看进程,显示如下:DFSZKFailoverController,NameNode,ResourceManager。DN节点也会自动启动DataNode、NodeManager
  6. 接着我们在NNS输入jps查看,发现只有DFSZKFailoverController进程,这里我们需要手动启动NNS上的namenode。命令如下:hadoop-daemon.sh start namenode
  7. 最后我们需要同步NNA节点的元数据,命令如下:hdfs namenode –bootstrapStandby

启动yarn:

  1. 接着上面的步骤,在NNA节点上:start-yarn.sh。输入jps查看进程,会发现多了:ResourceManager
  2. 登录NNS节点,使用:yarn-daemon.sh start resourcemanager。需要注意的是,在NNS上的yarn-site.xml中,需要配置指向NNS,属性配置为rm2,在NNA中配置的是rm1。

启动完成之后,可以访问:

hdfs: http://192.168.1.4:50770/dfshealth.htmlhttp://192.168.1.5:50770/dfshealth.html (其中一个为“active”,一个为“standby”) resourcemanger: http://192.168.1.4:8188/cluster/clusterhttp://192.168.1.5:8188/cluster/cluster

测试:

hadoop fs -mkdir hdfs:/test/ 
hadoop fs -copyFromLocal /home/hadoop/data/webcount hdfs:/test/ 
hadoop fs -ls hdfs:/test/ 
hadoop fs -cat hdfs:/test/webcount

HA的切换

由于我配置的是自动切换,若NNA节点宕掉,NNS节点会立即由standby状态切换为active状态。若是配置的手动状态,可以输入如下命令进行人工切换:

hdfs haadmin -failover --forcefence --forceactive nna  nns

这条命令的意思是,将nna变成standby,nns变成active。而且手动状态下需要重启服务。

工具脚本

`bash copy-config.sh

#!/bin/sh

scp /home/hadoop/hadoop/etc/hadoop/ nns:/home/hadoop/hadoop/etc/hadoop scp /home/hadoop/hadoop/etc/hadoop/ dn1:/home/hadoop/hadoop/etc/hadoop scp /home/hadoop/hadoop/etc/hadoop/ dn2:/home/hadoop/hadoop/etc/hadoop scp /home/hadoop/hadoop/etc/hadoop/ dn3:/home/hadoop/hadoop/etc/hadoop

scp /home/hadoop/hadoop/libexec/ nns:/home/hadoop/hadoop/libexec scp /home/hadoop/hadoop/libexec/ dn1:/home/hadoop/hadoop/libexec scp /home/hadoop/hadoop/libexec/ dn2:/home/hadoop/hadoop/libexec scp /home/hadoop/hadoop/libexec/ dn3:/home/hadoop/hadoop/libexec `


   转载规则


《高可用HDFS搭建》 Angus_Lu 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
高可用HBASE搭建 高可用HBASE搭建
HDFS的高可用搭建不在本篇中描述,请参考《Hadoop HDFS与YARN高可用安装》。节点规划hostnameip安装服务zk1192.168.1.1zookeeperzk2192.168.1.2zookeeperzk3192.168.
2018-01-30 19:14:12
下一篇 
RocketMQ Performance Test RocketMQ Performance Test
测试环境硬件配置4C 4G SSD操作系统centeOS 6.5MQ版本rocketmq-broker-4.2.0-incubating-SNAPSHOT (2017-08-23)测试程序运行机器:Macbook Pro i7 2.3GHz
2018-01-15 15:45:23
  目录