1.此教程默认已经搭建好完全分布式
2. Zookeeper 集群搭建
配置完全分布式zk集群
---------------------
1.挑选3台主机
cs1 ~ cs3
2.每台机器都安装zk
tar
环境变量
3.配置zk配置文件
cs1 ~ cs3
[/home/ap/apps/zk/conf/zoo.cfg]
...
dataDir=/home/ap/zookeeper
4.在每台主机的/home/centos/zookeeper中添加myid,内容分别是1,2,3
[cs1]
$>echo 1 > /home/ap/zookeeper/myid
[cs2]
$>echo 2 > /home/ap/zookeeper/myid
[cs3]
$>echo 3 > /home/ap/zookeeper/myid
5.启动服务器集群
$>zkServer.sh start
6.查看每台服务器的状态
$>zkServer.sh status
* 注意: 如果有3台机器, 只启动一台的话, 会显示如下, 因为根据配置, 有3台机器, 此时只有一台启动, 没有过半数, 整个集群是挂掉的
* 只有启动的机器数量超过配置的半数, zk 集群才有效.
3.HA 集群搭建
首先声明
笔者用的6台主机, 主机名 cs1-cs6
, 用户名为ap
, 可以对照改为自己的主机名&用户名
另外, 搭建 HA 不会影响原来的完全分布式, 具体操作会在下面告知.
hadoop 安装目录层级结构:
/home/ap/apps/hadoop/etc/hadoop/hdfs-site.xml
data 目录层级结构:
-
cs1
:/home/ap/hadoopdata/namenode/current/edits_00....
-
cs2
:/home/ap/hadoopdata/datanode/current/BP-15...
可以对照参考
集群结构如下
开始搭建
首先保证 各节点直接的 ssh 免密登录没问题
- 如果非生产环境, 可以同时把
.ssh
删掉后, 全部重新生成ssh-keygen
, 同时相互发送, 这样操作最简单, 效率最高.
其次上代码了
- 把原本
/home/ap/apps/hadoop/etc/hadoop
中的hadoop
目录改为full
,意思是完全分布式. -
cp -r full ha
, 复制一份 full 为 ha, 在这份配置文件中配置 HA -
ln -s /home/ap/apps/hadoop/etc/ha /home/ap/apps/hadoop/etc/hadoop
, 用一个软链接hadoop 指向 ha - 配置
/home/ap/apps/hadoop/etc/ha/hdfs-site.xml
[hdfs-site.xml]
------------------------------------------------------------------
<configuration>
<!-- 指定 2个 namenode 的命名空间 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<!-- myucluster下的名称节点两个id -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<!-- 配置每个nn的rpc地址。 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>cs1:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>cs6:8020</value>
</property>
<!-- 配置webui端口 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>cs1:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>cs6:50070</value>
</property>
<!-- 名称节点共享编辑目录. -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://cs2:8485;cs3:8485;cs4:8485/mycluster</value>
</property>
<!-- java类,client使用它判断哪个节点是激活态。 -->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 脚本列表或者java类,在容灾保护激活态的nn. -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>
sshfence
shell(/bin/true)
</value>
</property>
<!-- ssh免密登陆 -->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/ap/.ssh/id_rsa</value>
</property>
<!-- 配置 sshfence 隔离机制超时时间(可不配) -->
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
<!-- 配置JN存放edit的本地路径。 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/ap/hadoopdata/journal</value>
</property>
</configuration>
- 配置
core-site.xml
, 这里给出完整配置 (目前不包括 Hive 配置)
[core-site.xml]
------------------------------------------------------------
<configuration>
<!-- 指定 hdfs 的 nameservice 为 mycluster -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<!-- 指定 hadoop 工作目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/home/ap/hadoopdata</value>
</property>
<!-- 指定zk集群访问地址 -->
<property>
<name>ha.zookeeper.quorum</name>
<value>cs1:2181,cs2:2181,cs3:2181</value>
</property>
</configuration>
- 配置
mapred-site.xml
[mapred-site.xml]
-------------------
<configuration>
<!-- 指定 mr 框架为 yarn 方式 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!-- 设置 mapreduce 的历史服务器地址和端口号 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>cs1:10020</value>
</property>
<!-- mapreduce 历史服务器的 web 访问地址 -->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>cs1:19888</value>
</property>
</configuration>
- 把
/home/ap/apps/hadoop/etc/*
发给其他所有节点 2-6- 注意: 软链接scp 的时候会有问题, 最终保证每个节点跟 cs1一样就可以了,可以每个节点单独修改, 也可以写脚本一起修改
ln -sfT /home/ap/apps/hadoop/etc/ha /home/ap/apps/hadoop/etc/hadoop
- 部署细节
0.在 zk 节点启动 zkServer
cs1-cs3: $>zkServer.sh start
1.在jn节点分别启动jn进程
$>hadoop-daemon.sh start journalnode
2.启动jn之后,在两个NN之间进行disk元数据同步
a)如果是全新集群,先format文件系统,只需要在一个nn上执行。
[cs1]
$>hadoop namenode -format
b)如果将非HA集群转换成HA集群,复制原NN的metadata到另一个nn.
1.步骤一
[cs1]
$>scp -r /home/centos/hadoop/dfs ap@cs6:/home/centos/hadoop/
2.步骤二
在新的nn(未格式化的nn)上运行一下命令,实现待命状态引导。
[cs6]
$>hdfs namenode -bootstrapStandby //需要cs1为启动状态,提示是否格式化,选择N.
3.在一个NN上执行以下命令,完成edit日志到jn节点的传输。
$>hdfs namenode -initializeSharedEdits
#查看cs2,cs3,cs4 这几个 jn 节点是否有edit数据.
4.启动所有节点.
[cs1]
$>hadoop-daemon.sh start namenode //启动名称节点
$>hadoop-daemons.sh start datanode //启动所有数据节点
[2,3,4]
$>hadoop-daemon.sh start journalnode
[cs6]
$>hadoop-daemon.sh start namenode //启动名称节点
- HA 管理
# 查看web 界面, 是否是2个 standby 状态
http://cs1:50070/
http://cs6:50070/
hdfs haadmin : 查看 ha 帮助
-----------------
$>hdfs haadmin -transitionToActive nn1 //切成激活态
$>hdfs haadmin -transitionToStandby nn1 //切成待命态
$>hdfs haadmin -transitionToActive --forceactive nn2//强行激活
$>hdfs haadmin -failover nn1 nn2 //模拟容灾演示,从nn1切换到nn2
- 加入 Zookeeper 容灾服务 zkfc
<!-- 1.部署容灾 -->
------------------------------
a.停止所有进程
$>stop-all.sh
b.配置hdfs-site.xml,启用自动容灾.
[hdfs-site.xml]
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
c.配置core-site.xml,指定zk的连接地址.
<property>
<name>ha.zookeeper.quorum</name>
<value>cs1:2181,cs2:2181,cs3:2181</value>
</property>
d.分发以上两个文件到所有节点。
<!-- 2.登录其中的一台NN(s201),在ZK中初始化HA状态,
创建 namenode 的 命名空间节点 mycluster -->
------------------------------------
$>hdfs zkfc -formatZK
<!-- 3.启动hdfs进程. -->
$>start-dfs.sh
<!-- 4.查看 webUI, 是否有一台自动切换为 active 状态了 -->
http://cs1:50070/
http://cs6:50070/
<!-- 5.测试自动容灾(如果cs6是活跃节点) -->
$>kill -9 cs6的 namenode进程号
观察 cs1:50070的状态变化
- 配置RM的HA自动容灾
1.配置yarn-site.xml
<configuration>
<!-- 是否允许高可用 -->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!-- Identifies the cluster. Used by the elector to ensure an RM doesn’t take over as Active for another cluster. -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>cluster1</value>
</property>
<!-- RM 的 id -->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!-- 2台 RM 的宿主 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>cs1</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>cs6</value>
</property>
<!-- 配置web界面 -->
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>cs1:8088</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>cs6:8088</value>
</property>
<!-- zookeeper 地址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>cs1:2181,cs2:2181,cs3:2181</value>
</property>
<!-- YARN 集群为 MapReduce 程序提供的 shuffle 服务(原本的) -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- ===========以下是可选的============= -->
<!-- 开启 YARN 集群的日志聚合功能 -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!-- YARN 集群的聚合日志最长保留时长 -->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>86400</value>
</property>
<!-- 启用自动恢复 -->
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<!-- 指定 resourcemanager 的状态信息存储在 zookeeper 集群上-->
<property>
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
</configuration>
------------------------------------------------------------------
2.使用管理命令
<!-- 查看状态 -->
$>yarn rmadmin -getServiceState rm1
<!-- 切换状态到standby -->
$>yarn rmadmin -transitionToStandby rm1
3.启动yarn集群
$>start-yarn.sh
4.hadoop没有启动两个resourcemanager,需要手动启动另外一个
$>yarn-daemon.sh start resourcemanager
5.查看webUI, 点击 About, 查看 active 或 standby
http://cs1:8088
http://cs6:8088
6.做容灾模拟.
kill -9 活跃的 RM 端口号
7.注意: 如果容灾失败, 检查下每台主机时间是否同步
$>sudo ntpdate ntp1.aliyun.com
至此, 大功告成
4.HA 集群的启动/关闭
4.1 HA 的启动
一:单点启动
启动 zk 服务 QuorumPeerMain, 否则后面 RM 会起不来,连不上 ZK 服务
cs1-cs3: $>zkServer.sh start
启动 namenode/datanode
cs1,cs6: $>hadoop-daemon.sh start namenode
cs1/cs6: $>hadoop-daemons.sh start datanode
cs6: $>hadoop-daemon.sh start namenode
启动 journalnode
cs2-cs4: $>hadoop-daemon.sh start journalnode
启动RM (RM 会自动选出一个 active)
cs1,cs6: $>yarn-daemon.sh start resourcemanager
cs1/cs6: $>yarn-daemons.sh start nodemanager
启动 zk 的 DFSZKFailoverController
cs1,cs6: $>hadoop-daemon.sh start zkfc
此外可以启动MapReduce 的历史任务服务器
[ap@cs1]$> mr-jobhistory-daemon.sh start historyserver
然后访问配置的 http://cs1:19888/jobhistory
二:懒汉启动
启动 zk 服务 QuorumPeerMain, 否则后面 RM 会起不来,连不上 ZK 服务
cs1-cs3: $>zkServer.sh start
-
执行启动全部
cs1: $>
start-all.sh
(RM 节点)或者, 使用新的启动方式
cs1: $>
start-dfs.sh
(任意节点)cs1: $>
start-yarn.sh
(在 RM 节点) -
另一个 RM 节点不会自己启动,要手动启动
cs6: $>
yarn-daemon.sh start resourcemanager
4.2 HA 的关闭
在 一台NN 上stop-all.sh
, 注意 zk 的 server- QuorumPeerMain
不会停掉
5.简单时间同步脚本
# 在所有机器上写定时任务
crontab -e
* */1 * * * /usr/sbin/ntpdate time1.aliyun.com