1、概述
这部分主要描述,在生产环境中,如何来搭建一个高可用性的hadoop集群。在hadoop集群中,NameNode是一个非常核心的组件,上面存储着所有文件的元数据信息,比如文件跟数据块的映射关系,
数据块跟集群中节点的映射关系等内容。一旦
NameNode出现故障,整个集群将不可用。
NameNode的HA方案,是在一个集群中配置两个NameNode,其中一个处于活跃Active状态,另一个为Standby状态。如果活跃的NameNode宕机或者正常关闭,Standby可以快速切换为Active。
另外,还有一种高可用性方案是 --
Federation,他允许hadoop集群中配置多个NameNode,至少4个,它是HA方案的扩展。两个一对,其中一个处于Active状态,另一个处于Standby状态。他们相互独立互不影响,每对
NameNode分管保存一部分元数据信息,但DataNode数据是共享的。
本文档中采用的是HA方案,Federation方案是在此基础上扩展而来的,原理一样,配置文件也差不多,在此不细述。
2、HA方案的原理与架构
HA最核心的部分,就是如何让Active与Standby之间快速、可靠的同步变化的元数据信息。当Active NameNode挂掉后,Standby NameNode能够快速的切换并不丢失元数据信息。
这里采用的是QJM(Quorum Journal Manager)
方案,他提供了一个共享的存储系统来保存实时变化的元数据信息
(editlog)
,
Active
NameNode将变化的(增加或删除)元数据信息写入这个共享系统中,
Standby NameNode则会一直
监听这个共享的存储系统,一旦发现有元数据变化,就会读取这些元数据保存到自己的文件系统中。
QJM是一个基于Paxos算法实现的hadoop HA方案。其原理与ZooKeeper集群的原理相似,都是基于写入大多数节点成功即认为成功,数据不会丢失。假设有2N+1台主机,那么这个算法能够容
忍最多N台机器挂掉。机器数量必须为奇数,最少3台。部署QJM的节点称为JournalNode。
架构图如下所示:
![](https://i-blog.csdnimg.cn/blog_migrate/b61f34df347d543fa7c1ec87800b9fa3.png)
HA分为手动切换和自动切换,自动切换需要预先安装ZooKeeper集群,这里采用手动切换方式。官方文档有详细的操作说明。
3、集群节点描述
由于机器有限,这里只采用了三个节点来搭建hadoop集群,描述如下:
节点
|
Active NameNode
|
Standby
NameNode
|
DataNode
|
JournalNode
|
data-1
| 是 |
否
|
是
|
是
|
data-2
|
否
|
是
|
是
|
是
|
data-3
|
否
|
否
|
是
|
是
|
由于
NameNode比较重要,因此在生产环境中需要单独用一台机器来部署它。JournalNode负载很小,可以跟DataNode部署在同一台机器上。
4、准备工作
这里有几项需要特别说明下。
1)、host配置。每台机器上要配置相同的hosts,如下所示:
192.168.139.73 data-1
192.168.215.174 data-2
192.168.139.86 data-2
需要注意的是,这里可以配置成内网IP,也可以配置成外网
IP。若配置成内网
IP,从外部是无法访问的,如通过web url查看
NameNode信息等,这个根据实际情况来决定。
2)、ssh免密码登陆。这里data-1节点作为Master,因此需要设置成data-1到其他各个节点上的免密码登陆,设置完后,执行 ssh data-1, ssh data-2, ssh data-3测试下。
3)、安装压缩包。
在每个节点上执行 yum install cmake zlib-devel openssl-devel lzo-devel snappy lz4 bzip2 。
5、配置文件
1)、mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>data-1:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>data-1:19888</value>
</property>
<property>
<name>mapreduce.map.memory.mb</name>
<value>256</value>
</property>
<property>
<name>mapreduce.map.java.opts</name>
<value>-Xmx204m</value>
</property>
<property>
<name>mapreduce.map.cpu.vcores</name>
<value>1</value>
</property>
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>512</value>
</property>
<property>
<name>mapreduce.reduce.java.opts</name>
<value>-Xmx409m</value>
</property>
<property>
<name>mapreduce.reduce.cpu.vcores</name>
<value>1</value>
</property>
<property>
<name>yarn.app.mapreduce.am.resource.mb</name>
<value>512</value>
</property>
<property>
<name>yarn.app.mapreduce.am.command-opts</name>
<value>-Xmx409m</value>
</property>
</configuration>
2)、hdfs-site.xml
<configuration>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:data/datastore/hadoop/namenode</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:data/datastore/hadoop/datanode</value>
</property>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<property>
<name>dfs.nameservices</name>
<value>hadoop-cluster</value>
</property>
<property>
<name>dfs.ha.namenodes.hadoop-cluster</name>
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.hadoop-cluster.nn1</name>
<value>data-1:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.hadoop-cluster.nn2</name>
<value>data-2:8020</value>
</property>
<property>
<name>dfs.namenode.http-address.hadoop-cluster.nn1</name>
<value>data-1:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.hadoop-cluster.nn2</name>
<value>data-2:50070</value>
</property>
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://data-1:8485;data-2:8485;data-3:8485/hadoop-journal</value>
</property>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>false</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/data/datastore/hadoop/journal</value>
</property>
<property>
<name>dfs.client.failover.proxy.provider.hadoop-cluster</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>
</configuration>
3)、yarn-site.xml
<configuration>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>data-1</value>
</property>
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<name>yarn.nodemanager.remote-app-log-dir</name>
<value>/yarn-log</value>
</property>
<property>
<name>yarn.nodemanager.remote-app-log-dir-suffix</name>
<value>logs</value>
</property>
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>256</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>1024</value>
</property>
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>1024</value>
</property>
<property>
<name>yarn.acl.enable</name>
<value>true</value>
</property>
<property>
<name>yarn.admin.acl</name>
<value>*</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>data-1:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>data-1:8030</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>data-1:8031</value>
</property>
<property>
<name>yarn.resourcemanager.admin.address</name>
<value>data-1:8033</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>data-1:8088</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
4)、core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop-cluster</value>
</property>
</configuration>
5)、slaves
data-1
data-2
data-3
配置完后,需要把配置文件复制到各个节点上,如
scp hadoop-env.sh core-site.xml mapred-site.xml hdfs-site.xml yarn-site.xml slaves
hadoop@data-3
:/data/software/hadoop-2.6.0-cdh5.5.1/etc/hadoop
需要说明的几点:
a、配置文件中每项值的具体意义,请参照官方文档中的描述。由于更新速度比较快,每个发行版本的配置项可能会不一样,修改配置文件的时候一定要根据自己选择的版本,
然后去官方网站上找相应版本的文档说明,核对配置项是否被修改或者丢弃了。
b、
hdfs-site.xml配置文件中,关于ha的配置部分,请参照官网
http://hadoop.apache.org/docs/r2.6.0/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html中的说明。
5、启动选项
1)、
在各个JournalNode节点上(至少三个),输入以下命令启动JournalNode服务:
sbin/hadoop-daemon.sh start journalnode
2)、
在nn1(data-1)上,对其进行格式化,并启动:
bin/hdfs namenode -format(
第一次运行)
sbin/hadoop-daemon.sh start namenode
3)、
在nn2(data-2)上,同步nn1的元数据信息:
bin/hdfs namenode -bootstrapStandby(
第一次运行)
4)、
在nn2(data-2),启动NameNode:
sbin/hadoop-daemon.sh start namenode
(经过以上四步操作,nn1和nn2均处理standby状态)
5)、
在nn1(data-1)上,将NameNode切换为Active
bin/hdfs haadmin -transitionToActive nn1
6)、
在nn1(data-1)上,启动所有DataNode
sbin/hadoop-daemons.sh start datanode
7)、在data-1上,
启动resourcemanager,nodemanager
sbin/start-yarn.sh
8)、
在data-1上,启动historyserver
sbin/mr-jobhistory-daemon.sh start historyserver
启动完后,在各个节点上
输入jps查看相应的进程都是否成功启动,然后输入hadoop fs -ls /来查看命令是否能正确执行。
关闭顺序
sbin/mr-jobhistory-daemon.sh stop historyserver
sbin/stop-yarn.sh
sbin/stop-dfs.sh
sbin/stop-yarn.sh
sbin/stop-dfs.sh
在配置过程中一定要仔细看官方文档的说明,我在配置dfs.client.failover.proxy.provider.hadoop-cluster的时候,是直接粘贴官方文档的选项(
mycluster
),dfs.nameservices名字搞错了,导致启动集群后,在使用 bin/hadoop fs -ls / 命令时报错,如下:
[hadoop@data-2 hadoop-2.6.0-cdh5.5.1]$ bin/hadoop fs -ls /
-ls: java.net.UnknownHostException: hadoop-cluster
Usage: hadoop fs [generic options] -ls [-d] [-h] [-R] [<path> ...]
参考资料: