共计 13137 个字符,预计需要花费 33 分钟才能阅读完成。
本文在《Hadoop2.0 的安装和基本配置》(见 http://www.linuxidc.com/Linux/2014-05/101173.htm)一文的基础上继续介绍 hadoop2.0 QJM(Quorum Journal Manager)方式的 HA 的配置(hadoop2.0 架构,具体版本是 hadoop2.2.0)。本文只介绍 HA 的主备的手工切换,自动切换在下一篇文章继续介绍(见 http://www.linuxidc.com/Linux/2014-05/101176.htm)。
————————————– 分割线 ————————————–
相关阅读 :
Ubuntu 13.04 上搭建 Hadoop 环境 http://www.linuxidc.com/Linux/2013-06/86106.htm
Ubuntu 12.10 +Hadoop 1.2.1 版本集群配置 http://www.linuxidc.com/Linux/2013-09/90600.htm
Ubuntu 上搭建 Hadoop 环境(单机模式 + 伪分布模式)http://www.linuxidc.com/Linux/2013-01/77681.htm
Ubuntu 下 Hadoop 环境的配置 http://www.linuxidc.com/Linux/2012-11/74539.htm
单机版搭建 Hadoop 环境图文教程详解 http://www.linuxidc.com/Linux/2012-02/53927.htm
搭建 Hadoop 环境(在 Winodws 环境下用虚拟机虚拟两个 Ubuntu 系统进行搭建)http://www.linuxidc.com/Linux/2011-12/48894.htm
————————————– 分割线 ————————————–
1 准备
文中描述的机器角色包含 2 个 namenode:
- namenode1
- namenode2
其中 namenode1 为 active namenode;namenode2 为 standby namenode。
包含 3 个 journalnode:
- journalnode1
- journalnode2
- journalnode3
journalnode 的机器的数量是奇数,可以是 3,5,7…,2n+1。
其他机器角色本文中不涉及的可以参考《hadoop2.0 的安装和基本配置》一文。
2 配置
HA 的配置只涉及到 core-site.xml 和 hdfs-site.xml 两个配置文件,其他配置可以文件参考《Hadoop2.0 的安装和基本配置》一文。
2.1 core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/tmp/hadoop2.0</value>
</property>
</configuration>
2.2 hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/home/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/home/dfs/data</value>
</property>
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>namenode1:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>namenode2:8020</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>namenode1:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>namenode2:50070</value>
</property>
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://journalnode1:8485;journalnode2:8485;journalnode3:8485/mycluster</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/dfs/journal</value>
</property>
<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>
<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>6000</value>
</property>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>false</value>
</property>
</configuration>
上述有些参数这里需要解释一下。
dfs.ha.automatic-failover.enabled
这里是把主备自动切换关闭,需要手工来切换。在下一篇文章会介绍通过配置 zookeeper 来实现主备自动切换。
fs.ha.namenodes.mycluster
<value> 中的 nn1,nn2 分别是 active namenode 和 standby namenode 的 namenode id,你也可以自己起一个 namenode id,只要在参数中都保持一致就可以了。
dfs.namenode.shared.edits.dir
配置一组 journalnode(3,5,7,…,2n+1)的 URI,用于 active namenode 和 standby namenode 读写 edits 文件(原理可以参考前面的文章《hadoop2.0 的 HA 介绍》),<value> 中的 mycluster 是 dfs.nameservices 保持一致。你可以自己起一个 nameservice ID,只要在参数中都保持一致就可以了。
dfs.journalnode.edits.dir
是在 journalnode 节点上用于存放 active namenode 和 standby namenode 共享的 edits 文件的目录。
dfs.ha.log-roll.period
active namenode 的 edits 文件轮转的时间间隔,前面没有设置这个参数,默认值是 120 秒。即 standby namenode 会隔 120 秒要求 active namenode 切出一个 edits 文件,然后通过 journalnode 去同步这个文件。
active namenode 会隔 120 秒会切出一个新 edits 文件,并且给这些 edits 文件一个编号,越新的 edits 文件编号越大。
日志轮转的时候开始会先生成一个新的“inprogress”edits 文件(文件名带着“inprogress”),说明日志正在生成,轮转没完成。当过了 120 秒之后,日志轮转完成,文件改名,文件名字带着一个目前最大的编号(文件名没有“inprogress”)。然后生成一个新的“inprogress”edits 文件,开始下一次 edits 文件轮转。
当发生主备切换的时候,会触发一次 edit 文件的轮转,这样 standby namenode 就会把剩下的 edits 文件同步过来,在切换到 active 状态时元数据能保持一个最新的状态。
dfs.ha.tail-edits.period
standby namenode 每隔多长时间去检测新的 edits 文件。它只会检查已经完成轮转的 edits 文件,不会检查“inprogress”edits 文件。
dfs.ha.fencing.methods
系统在任何时候只有一个 namenode 节点处于 active 状态。在主备切换的时候,standby namenode 会变成 active 状态,原来的 active namenode 就不能再处于 active 状态了,否则两个 namenode 同时处于 active 状态会造成所谓的“脑裂”��题。所以在 failover 的时候要设置防止 2 个 namenode 都处于 active 状态的方法,可以是 java 类或者脚本。
fencing 的方法目前有两种,sshfence 和 shell
sshfence 方法是指通过 ssh 登陆到 active namenode 节点杀掉 namenode 进程,所以你需要设置 ssh 无密码登陆,还要保证有杀掉 namenode 进程的权限。
shell 方法是指运行一个 shell 脚本 / 命令来防止“脑裂”问题,脚本需要自己写。
注意,QJM 方式本身就有 fencing 功能,能保证只有一个 namenode 能往 journalnode 上写 edits 文件,所以是不需要设置 fencing 的方法就能防止“脑裂”问题的。但是,在发生 failover 的时候,原来的 active namenode 可能还在接受客户端的读请求,这样客户端很可能读到一些过时的数据(因为新的 active namenode 的数据已经实时更新了)。因此,还是建议设置 fencing 方法。如果确实不想设置 fencing 方法,可以设置一个能返回成功(没有 fencing 作用)的方法,如“shell(/bin/true)”。这个纯粹为了 fencing 方法能够成功返回,并不需要真的有 fencing 作用。这样可以提高系统的可用性,即使在 fencing 机制失败的时候还能保持系统的可用性。
更多详情见请继续阅读下一页的精彩内容 :http://www.linuxidc.com/Linux/2014-05/101175p2.htm
3 启动
3.1 先在 journalnode 机器上启动 journalnode
$Hadoop_HOME/sbin/hadoop-daemon.sh start journalnode
3.2 在 namenode 机器上启动 namenode
其中 namenode1 为 active namenode,namenode2 为 standby namenode
3.2.1
如果是首次启动,在 namenode1 上运行 format 命令
$HADOOP_HOME/bin/hadoop namenode -format
如果是非首次启动,则在 namenode1 上运行以下命令
$HADOOP_HOME/bin/hdfs namenode -initializeSharedEdits
这里需要解释一下。
首次启动是指安装的时候就配置了 HA,hdfs 还没有数据。这时需要用 format 命令把 namenode1 格式化。
非首次启动是指原来有一个没有配置 HA 的 HDFS 已经在运行了,HDFS 上已经有数据了,现在需要配置 HA 而加入一台 namenode。这时候 namenode1 通过 initializeSharedEdits 命令来初始化 journalnode,把 edits 文件共享到 journalnode 上。
3.2.2
然后在 namenode1 上启动 namenode
$HADOOP_HOME/sbin/hadoop-daemon.sh start namenode
3.2.3
在 namenode2 上运行以下命令
$HADOOP_HOME/sbin/hadoop-daemon.sh start namenode -bootstrapStandby
这里也需要解释一下。
namenode2 是不需要 format 的。
namenode2 需要运行 bootstrapStandby 命令来同步 namenode1 的元数据,和 namenode1 的元数据保持一致。
具体过程是:前面说过 namenode1 通过 initializeSharedEdits 命令已经把 edits 文件共享到 journalnode 上了,现在 namenode2 需要通过 bootstrapStandby 命令把 namenode1 的元数据和 journalnode 的 edits 文件同步过来,从而使元数据和 namenode1 保持一致。
注意,这里需要 journalnode 上有足够的 edits 文件,这样才能保证 namenode1 和 namenode2 上的元数据保持一致。如果 bootstrapStandby 命令运行失败,可以手工把 namenode1 的元数据(即 ${dfs.namenode.name.dir} 这个目录下的所有数据)拷贝到 namenode2 的 ${dfs.namenode.name.dir} 这个目录下,再运行 bootstrapStandby 命令。
3.2.4
然后在 namenode2 上启动 namenode
$HADOOP_HOME/sbin/hadoop-daemon.sh start namenode
这时,namenode1 和 namenode2 都启动了,都是“standby”状态。
3.2.5
在 namenode1 上运行
$HADOOP_HOME/bin/hdfs haadmin -transitionToActive nn1
这样,namenode1 的状态就变成“active”。
3.3 在 datanode 机器上启动 datanode
$HADOOP_HOME/sbin/hadoop-daemon.sh start datanode
这时 HDFS 就可以正常使用了,并且 HA 功能已经启动。
3.4 检查
可以通过以下页面查看 active namenode(namenode1) 和 standby namenode(namenode2) 的状态
http://namenode1:50070/dfshealth.jsp
http://namenode2:50070/dfshealth.jsp
运行常用的 HDFS shell 命令测试 HDFS 是否正常。
4 测试
停掉 namenode1 的 namenode(模拟 namenode1 挂掉),这时会发现 hdfs 不能用了。
在 namenode2 上运行以下命令
$HADOOP_HOME/bin/hdfs haadmin -transitionToActive nn2
namenode2 的状态就变成“active”,这时 HDFS 恢复正常。
在 namenode1 上运行一下命令做主从切换
$HADOOP_HOME/bin/hdfs haadmin -failover nn1 nn2
这时 namenode2 的状态变成“active”,namenode1 的状态变成“standby”。
5 QJM 方式 HA 的结构图
QJM 方式 HA 的结构涉及到 active namenode,standby namenode,journalnode,datanode,client,这里通过一个图描述他们之间的关系。
6 实战 tips
- 在 namenode1 做的一些配置和操作,在 namenode2 上也要做一次,保持 2 台机器一致。
- 注意首次启动(第一次启动的时候就是 HA)和非首次启动(运行一段时间后加入 HA 特性)的区别。
- 因为 HA 的自动切换容易出现 ssh 登陆和权限的问题,而且网上也有资料测试自动切换有时候会不成功,所以在生产环境还是建议采用手工切换的方式,这样更加可靠,有问题也可以及时查。
在下一篇文章中,我们会在本文的基础上继续介绍 HA 的主备自动切换的配置。通过配置 zookeeper,实现 HA 的主备自动切换。
参考资料
http://hadoop.apache.org/docs/r2.2.0/hadoop-yarn/hadoop-yarn-site/HDFSHighAvailabilityWithQJM.html
本文在《Hadoop2.0 的安装和基本配置》(见 http://www.linuxidc.com/Linux/2014-05/101173.htm)一文的基础上继续介绍 hadoop2.0 QJM(Quorum Journal Manager)方式的 HA 的配置(hadoop2.0 架构,具体版本是 hadoop2.2.0)。本文只介绍 HA 的主备的手工切换,自动切换在下一篇文章继续介绍(见 http://www.linuxidc.com/Linux/2014-05/101176.htm)。
————————————– 分割线 ————————————–
相关阅读 :
Ubuntu 13.04 上搭建 Hadoop 环境 http://www.linuxidc.com/Linux/2013-06/86106.htm
Ubuntu 12.10 +Hadoop 1.2.1 版本集群配置 http://www.linuxidc.com/Linux/2013-09/90600.htm
Ubuntu 上搭建 Hadoop 环境(单机模式 + 伪分布模式)http://www.linuxidc.com/Linux/2013-01/77681.htm
Ubuntu 下 Hadoop 环境的配置 http://www.linuxidc.com/Linux/2012-11/74539.htm
单机版搭建 Hadoop 环境图文教程详解 http://www.linuxidc.com/Linux/2012-02/53927.htm
搭建 Hadoop 环境(在 Winodws 环境下用虚拟机虚拟两个 Ubuntu 系统进行搭建)http://www.linuxidc.com/Linux/2011-12/48894.htm
————————————– 分割线 ————————————–
1 准备
文中描述的机器角色包含 2 个 namenode:
- namenode1
- namenode2
其中 namenode1 为 active namenode;namenode2 为 standby namenode。
包含 3 个 journalnode:
- journalnode1
- journalnode2
- journalnode3
journalnode 的机器的数量是奇数,可以是 3,5,7…,2n+1。
其他机器角色本文中不涉及的可以参考《hadoop2.0 的安装和基本配置》一文。
2 配置
HA 的配置只涉及到 core-site.xml 和 hdfs-site.xml 两个配置文件,其他配置可以文件参考《Hadoop2.0 的安装和基本配置》一文。
2.1 core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/tmp/hadoop2.0</value>
</property>
</configuration>
2.2 hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/home/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/home/dfs/data</value>
</property>
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>namenode1:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>namenode2:8020</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>namenode1:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>namenode2:50070</value>
</property>
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://journalnode1:8485;journalnode2:8485;journalnode3:8485/mycluster</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/dfs/journal</value>
</property>
<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>
<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>6000</value>
</property>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>false</value>
</property>
</configuration>
上述有些参数这里需要解释一下。
dfs.ha.automatic-failover.enabled
这里是把主备自动切换关闭,需要手工来切换。在下一篇文章会介绍通过配置 zookeeper 来实现主备自动切换。
fs.ha.namenodes.mycluster
<value> 中的 nn1,nn2 分别是 active namenode 和 standby namenode 的 namenode id,你也可以自己起一个 namenode id,只要在参数中都保持一致就可以了。
dfs.namenode.shared.edits.dir
配置一组 journalnode(3,5,7,…,2n+1)的 URI,用于 active namenode 和 standby namenode 读写 edits 文件(原理可以参考前面的文章《hadoop2.0 的 HA 介绍》),<value> 中的 mycluster 是 dfs.nameservices 保持一致。你可以自己起一个 nameservice ID,只要在参数中都保持一致就可以了。
dfs.journalnode.edits.dir
是在 journalnode 节点上用于存放 active namenode 和 standby namenode 共享的 edits 文件的目录。
dfs.ha.log-roll.period
active namenode 的 edits 文件轮转的时间间隔,前面没有设置这个参数,默认值是 120 秒。即 standby namenode 会隔 120 秒要求 active namenode 切出一个 edits 文件,然后通过 journalnode 去同步这个文件。
active namenode 会隔 120 秒会切出一个新 edits 文件,并且给这些 edits 文件一个编号,越新的 edits 文件编号越大。
日志轮转的时候开始会先生成一个新的“inprogress”edits 文件(文件名带着“inprogress”),说明日志正在生成,轮转没完成。当过了 120 秒之后,日志轮转完成,文件改名,文件名字带着一个目前最大的编号(文件名没有“inprogress”)。然后生成一个新的“inprogress”edits 文件,开始下一次 edits 文件轮转。
当发生主备切换的时候,会触发一次 edit 文件的轮转,这样 standby namenode 就会把剩下的 edits 文件同步过来,在切换到 active 状态时元数据能保持一个最新的状态。
dfs.ha.tail-edits.period
standby namenode 每隔多长时间去检测新的 edits 文件。它只会检查已经完成轮转的 edits 文件,不会检查“inprogress”edits 文件。
dfs.ha.fencing.methods
系统在任何时候只有一个 namenode 节点处于 active 状态。在主备切换的时候,standby namenode 会变成 active 状态,原来的 active namenode 就不能再处于 active 状态了,否则两个 namenode 同时处于 active 状态会造成所谓的“脑裂”��题。所以在 failover 的时候要设置防止 2 个 namenode 都处于 active 状态的方法,可以是 java 类或者脚本。
fencing 的方法目前有两种,sshfence 和 shell
sshfence 方法是指通过 ssh 登陆到 active namenode 节点杀掉 namenode 进程,所以你需要设置 ssh 无密码登陆,还要保证有杀掉 namenode 进程的权限。
shell 方法是指运行一个 shell 脚本 / 命令来防止“脑裂”问题,脚本需要自己写。
注意,QJM 方式本身就有 fencing 功能,能保证只有一个 namenode 能往 journalnode 上写 edits 文件,所以是不需要设置 fencing 的方法就能防止“脑裂”问题的。但是,在发生 failover 的时候,原来的 active namenode 可能还在接受客户端的读请求,这样客户端很可能读到一些过时的数据(因为新的 active namenode 的数据已经实时更新了)。因此,还是建议设置 fencing 方法。如果确实不想设置 fencing 方法,可以设置一个能返回成功(没有 fencing 作用)的方法,如“shell(/bin/true)”。这个纯粹为了 fencing 方法能够成功返回,并不需要真的有 fencing 作用。这样可以提高系统的可用性,即使在 fencing 机制失败的时候还能保持系统的可用性。
更多详情见请继续阅读下一页的精彩内容 :http://www.linuxidc.com/Linux/2014-05/101175p2.htm