题外话
初次部署Hadoop HA的时候,踩过很多坑。现在将部署流程记录下来,希望可以帮助到更多的初学者。
HADOOP HA是什么
在HADOOP1.0时代,整个集群中仅有一台NameNode结点,如果该结点丢失或数据发生损坏,会对整个集群造成不可恢复的损失,为了解决这一问题,社区研发出了SecondaryNamenode用以备份NameNode中的元数据,然而使用该组建后,当集群发生损坏时,集群恢复工作的时间相当缓慢,并不能满足商业上的使用。
在HADOOP2.0时代,社群重新定义了NameNode的设计层级,改用Service来对集群进行管理。Hadoop HA使用多个NameNode组成一个服务,每一个服务中有两台或以上的NameNode,NameNode们的功能完全一致,但是同一时间仅有一台处于active状态,其他处于Standby状态,当active集群发生故障时,能在秒级时间内进行切换。
HADOOP HA正式部署
一、集群规划
IP 地址 | Hadoop | HDFS | Yarn | ||
---|---|---|---|---|---|
192.168.20.100 | Master1 | NameNode | ResourceManager | JournalNode | |
192.168.20.101 | Master2 | NameNode | ResourceManager | Zookeeper | JournalNode |
192.168.20.102 | Slave1 | DataNode | NodeManager | Zookeeper | JournalNode |
192.168.20.103 | Slave2 | DataNode | NodeManager | Zookeeper | JournalNode |
192.168.20.104 | Slave3 | DataNode | NodeManager | Zookeeper | JournalNode |
192.168.20.105 | Slave4 | DataNode | NodeManager | Zookeeper |
如果机器数量紧缺,可使用如下方法
- 可以只用3个Zookeepr和JournalNode。
- Slave可以和NameNode部署在同一结点 。
- 但两台Namenode和Resourcemanager须分开。
二、基础配置
使用CentOS 7.2系统,HADOO P版本 2.6.5,Zookeeper版本 3.X
1.更改主机名
vim /etc/hostname
2.设置静态IP
vim /etc/sysconfig/network-scripts/ifcfg-eth0
3.编辑hosts文件
将其他结点的 hostname
以及 ip地址
按照格式写入hosts文件中
vim /etc/hosts
如: 192.168.20.100 Master1
4.关闭防火墙或设置开放端口
为了方便搭建,直接关闭了防火墙,仅限于实验环境
systemctl status firewalld.service 查看防火墙状态
systemctl stop firewalld.service 关闭防火墙
systemctl disable firewalld.service 禁止开机启动防火墙
5.关闭 SELINUX
vim /etc/selinux/config
修改文件中
SELINUX=disabled
三、安装JDK
1、 在集群所有机器上安装 Java 环境
yum install java
2、 设置环境变量
` vim /etc/profile.d/java.sh
增加
export JAVA_HOME=YOURJAVAPATH
export PATH=PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin
export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
四、SSH免密码登陆
ssh-keygen -t rsa
#生成密钥,一路回车- 将每个节点的公钥发送到
master
节点,每个节点的id_rsa.pub
分别导入 authorized_keys,语句为cat id_rsa.pub >> authorized_keys
- 将统一的
authorized_keys
发送到每一个节点的/home/.ssh
路径下 修改配置文件
vi /etc/ssh/sshd_config
RSAAuthentication yes
PubkeyAuthentication yes
重启服务
service sshd restart
- 免密测试
ssh 其他主机名 or ip
五、zookeeper 集群安装
基于zookeepr选主算法,配置奇数台zookeeper最佳。
1. 在集群五台机器上安装 ZooKeeper(192.168.20.101~105)
yum install zookeeper
2. 修改配置文件
zookeeper/conf
目录下的zoo_sample.cfg
,将其改名为zoo.cfg
新增zookeepr集群ip
server.1=zkip:2888:3888
新增数据存储目录以及日志存储目录
mkdir -p /var/lib/zookeeper/data
mkdir -p /var/lib/zookeeper/logs
3. 创建myid文件
创建 myid 文件,并编辑它,编辑的内容就是配置文件中 server.后面跟着的号数
echo "1" > /var/lib/zookeeper/data/myid
4. 启动结点
/usr/lib/zookeeper/bin/zkServer.sh start
5. 检查运行状况
/usr/lib/zookeeper/bin/zkServer.sh status
在每个 slave 节点机器上运行此命令,会出现 Follower 和 Leader ### 六、HADOOP 集群安装
6. 在集群所有机器上安装
Hadoop yum install Hadoop
7. 在两台机器上安装 NameNode(192.168.20.100-101)
yum install Hadoop-hdfs-namenode
8. 在另外四台机器上安装 DataNode(192.168.20.102-105)
yum install Hadoop-hdfs-datanode
9. 在 集 群 所 有 机 器 上 安装 YARN
( NameNode-ResourceManager , DataNode-NodeManager)
yum install hadoop-yarn-resourcemanager
(192.168.20.100-101)
yum install hadoop-yarn-nodemanager(
192.168.20.102-105)
10. 在五台机器上安装 JournalNode 作为两个 NameNode 的共享存储空间
yum install hadoop-hdfs-journalnode
(192.168.20.100~104)
11. 安装 HttpFs,可通过浏览器管理 HDFS
yum install hadoop-httpfs
### 七、配置文件
路径:/etc/hadoop/conf
1. hdfs-site.xml 手动创建目录,更改所有者和所属组
- journalnode 存放数据目录(192.168.20.100~104)
mkdir –p /journal/data chmod –R hdfs:hadoop journal
- nanenode文件目录(192.168.20.100~101),更改文件目录所属组
mkdir –p /var/lib/hadoop-hdfs/cache/hdfs/dfs/name
chown –R hdfs:hadoop hdfs
- 具体配置文件
<configuration>
<property> <!--datanode数据存储位置 -->
<name>dfs.datanode.data.dir</name>
<value>
file:///mnt/volume_b/,
file:///mnt/volume_c/,
file:///mnt/volume_d/,
file:///mnt/volume_e/,
file:///mnt/volume_f/,
file:///mnt/volume_g/,
file:///mnt/volume_h/,
file:///mnt/volume_i/,
file:///mnt/volume_j/,
file:///mnt/volume_k/,
file:///mnt/volume_l/,
file:///mnt/volume_m/
</value>
</property>
<property>
<name>dfs.permissions.superusergroup</name>
<value>root</value><!--设置拥有权限的用户-->
</property>
<property>
<name>dfs.permissions</name><!--是否开启认证-->
<value>false</value>
</property>
<property>
<!--namenode 的文件目录,手动创建,用户权限组为 hdfs:hadoop -->
<name>dfs.namenode.name.dir</name>
<value>file:///mnt/volume_b/hadoop-hdfs/cache/hdfs/dfs/name</value>
</property>
<property>
<!--自定义的服务名称 -->
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<property>
<!--两个NameNode 的别名 -->
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<property>
<!--分别配置两个NameNode 的IP -->
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>Goblin02:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>Goblin01:8020</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>Goblin01:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>Goblin02:50070</value>
</property>
<property>
<!--分别配置JournalNode 的IP便于namenode 通信 -->
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://Goblin01:8485;Goblin02:8485;Goblin03:8485/mycluster</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
shell(/bin/true)
</value>
</property>
<property>
<!--密钥文件,所使用用户的密钥 -->
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/.ssh/id_rsa</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
<property>
<!--手动创建,修改用户组hdfs:hadoop>
<name>dfs.journalnode.edits.dir</name>
<value>/journal/data</value>
</property>
<property>
<!--开启高可用-->
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value
/property>
<property>
<name>dfs.block.size</name>
<value>67108864</value>
<description>The default block size for new files.</description>
</property>
</configuration>
2、 core-site.xml 具体配置
<configuration>
<property>
<!--自定义的文件名-->
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<property>
<!--配置zookeeper 的IP-->
<name>ha.zookeeper.quorum</name>
<value>node-20-101:2181,node-20-102:2181,node-20-103:2181,node-20104:2181,node-20-105:2181</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/hadoop/tmp</value>
</property>
<!--auth-->
<!--相关权限设置-->
<property>
<name>hadoop.proxyuser.mapred.groups</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.mapred.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.nfsserver.groups</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.nfsserver.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.nfsserver.users</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.hdfs.groups</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.hdfs.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.hdfs.users</name>
<value>*</value>
</property>
</configuration>
3. yarn-site.xml
相关端口其实可以使用默认配置,有端口冲突的才需要显式设定
<configuration>
<property>
<name>yarn.resourcemanager.connect.retry-interval.ms</name>
<value>20000</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>mapreduce.shuffle.port</name>
<value>23080</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<description>List of directories to store localized files in.</description>
<name>yarn.nodemanager.local-dirs</name>
<value>file:///mnt/volume_b/hadoop-yarn/cache/${user.name}/nm-localdir</value>
</property>
<property>
<description>Where to store container logs.</description>
<name>yarn.nodemanager.log-dirs</name>
<value>file:///mnt/volume_b/hadoop-yarn/containers</value>
</property>
<property>
<description>Where to aggregate logs to.</description>
<name>yarn.nodemanager.remote-app-log-dir</name>
<value>/yarn/apps</value>
</property>
<property>
<description>Classpath for typical applications.</description>
<name>yarn.application.classpath</name>
<value>
$HADOOP_CONF_DIR,
$HADOOP_COMMON_HOME/*,$HADOOP_COMMON_HOME/lib/*,
$HADOOP_HDFS_HOME/*,$HADOOP_HDFS_HOME/lib/*,
$HADOOP_MAPRED_HOME/*,$HADOOP_MAPRED_HOME/lib/*,
$HADOOP_YARN_HOME/*,$HADOOP_YARN_HOME/lib/*
</value>
</property>
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<property>
<!--设置本RESOURCEMANAGER 的ID,与另外一个区分开来-->
<name>yarn.resourcemanager.ha.id</name>
<value>rm2</value>
<description>If we want to launch more than one RM in single node,we need this configuration</description>
</property>
<!-- 指定RM的cluster id -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>appcluster-yarn</value>
</property>
<!-- 指定RM的名字 -->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!-- 分别指定RM的地址 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>node-20-100</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>node-20-101</value>
</property>
<property>
<!--配置ZOOKEEPER的ip地址-->
<name>ha.zookeeper.quorum</name>
<value>node-20-101:2181,node-20-102:2181,node-20-103:2181,node-20104:2181,node-20-105:2181</value>
</property>
<!--开启故障自动切换-->
<property>
<name>yarn.resourcemanager.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
<!--配置rm1-->
<property>
<name>yarn.resourcemanager.address.rm1</name>
<value>node-20-100:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address.rm1</name>
<value>node-20-100:8030</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>node-20-100:8088</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm1</name>
<value>node-20-100:8031</value>
</property>
<property>
<name>yarn.resourcemanager.admin.address.rm1</name>
<value>node-20-100:8033</value>
</property>
<property>
<name>yarn.resourcemanager.ha.admin.address.rm1</name>
<value>node-20-100:23142</value>
</property>
<!--配置rm2-->
<property>
<name>yarn.resourcemanager.address.rm2</name>
<value>node-20-101:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address.rm2</name>
<value>node-20-101:8030</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>node-20-101:8088</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm2</name>
<value>node-20-101:8031</value>
</property>
<property>
<name>yarn.resourcemanager.admin.address.rm2</name>
<value>node-20-101:8033</value>
</property>
<property>
<name>yarn.resourcemanager.ha.admin.address.rm2</name>
<value>node-20-101:23142</value>
</property>
<!--故障处理类-->
<property>
<name>yarn.client.failover-proxy-provider</name>
<value>org.apache.hadoop.yarn.client.ConfiguredRMFailoverProxyProvider</value>
</property>
<property>
<name>yarn.resourcemanager.ha.automatic-failover.zk-base-path</name>
<value>/yarn-leader-election</value>
<description>Optionalsetting.Thedefaultvalueis/yarn-leader-election</description>
</property>
<property>
<name>yarn.resourcemanager.work-preserving-recovery.enabled</name>
<value>true</value>
<description>Whether to enable work preserving recovery for the Resource Manager</description>
</property>
</configuration>
4、 slaves 配置文件
192.168.20.102 slave1
192.168.20.103 slave2
192.168.20.104 slave3
192.168.20.105 slave4
八、遇到过的问题与解决方法
- 创建 hdfs 用户,更改用户(hdfs)目录
useradd hdfs #创建 hdfs 用户
mkdir /home/hdfs #创建 hdfs 用户目录
vi /etc/passwd #修改主目录配置文件(将默认路径改为 hdfs 用户目录)
usermod –d /home/hdfs hdfs #修改主目录
cp /home/.* /home/hdfs #拷贝/home 目录下所有隐藏文件到/home/hdfs
- 使用 YUM 安装的 HADOOP 需要注意的事项
将/usr/lib/hadoop/
下的文件夹libexec
拷贝到/usr/lib/hadoop-hdfs/ 目录
。
在/etc/hadoop/conf
中创建hadoop-env.sh
并添加JAVA_HOMEexport JAVA_HOME =/usr/local/java/jdk1.8.0_45
- 启动失败时,查看日志中存在文件不存在的情况,手动在相应位置创建文件, 将其用户组改为
hdfs:hadoop
- 使用多次 namenode 格式化后可能出现 ID 不匹配的问题时,删除 current 文 件(可以使用 find -name current 命令查找,namenode 和 datanode 都需 要 删除),重新格式化
- 当 HDFS 集群的每台节点上拥有多块硬盘时,在 hdfs-site.xml 中修改
<property>
<name>dfs.datanode.data.dir</name>
<value> 硬盘 1, 硬盘 2, ….. 硬盘 N </value>
</property>
九、 进程启动
- 启动 zookeeper 集群
命令:./zkServer.sh start
- 格式化 Zookeeper 集群 (只在 namenode 节点运行)(注:在 Zookeeper 集群 建立 hadoop-ha,namenode 的元数据)
格式化命令:hdfs zkfc -formatZK
- 开启 Journalmnode 集群(注:两个 NameNode 为了数据同步,会通过一组称 作 JournalNodes 的独立进程进行相互通信)
- 格式化 Namenode,并启动
格式化命令:hadoop namenode -format
- 格式化 Standby Namenode,同步 Namenode,并启动
格式化命令:hadoop namenode -bootstrapStandby
- 启动所有 Datanode
- 启动 Yarn
8 . 启动 zkfc (注:只在 Namenodehe 和 Standby Namenode)
命令:./hadoop-daemon.sh start zkfc