1、规划
- 现在,使用最新版本的hadoop相关软件搭建一个HA高可用集群,hadoop借助Zookeeper完成高可用,同时需要启动名为JournalNode和DFSZK Failover Controller的新组件,即:日志节点和灾备转移控制器,这样在主节点崩溃时可以迅速的恢复,启用HA后,SNN也就不需要了,因为可以同时存在两个以上的NN做替换。
- 不要将JN启动在NN上,由于hadoop需要运行spark、hive等,所以内存至少分配8g,规划如下:
hadoop101 | hadoop102 | hadoop103 | hadoop104 | |
---|---|---|---|---|
HDFS | NN、DF 日志服务器 |
Spark、Hive等 DN、JN |
NN、DF | DN、JN |
YARN | NM | NM | RM+NM | RM+NM |
Zookeeper | QP | QP | QP | QP |
Hbase | HM | HM | HR | HR |
硬件配置 | CPU:4 内存:4g |
CPU:8 内存:8g |
CPU:4 内存:4g |
CPU:4 内存:4g |
附:进程缩写对照
Zookeeper进程 | QP:QuorumPeerMain | |||
---|---|---|---|---|
HDFS进程 | NN:NameNode | DN:DataNode | JN:JournalNode (日志节点) |
DF :DFSZK Failover Controller |
Yarn进程 | RM: ResourceManager | NM:NodeManager | ||
Hbase进程 | HM:HMaster | HR:HRegionServe |
2、用户参数调优
通过命令查看用户参数,open files限定了当前用户的最大可打开文件数及进程数,建议设置为10240以上
[root@hadoop101 hadoop]# ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 14898
max locked memory (kbytes, -l) 16384
max memory size (kbytes, -m) unlimited
open files (-n) 10240
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 14898
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
编辑配置文件
vim /etc/systemd/system.conf
#最大文件
DefaultLimitNOFILE=10240
#进程打开数
DefaultLimitNPROC=40960
rsync /etc/systemd/system.conf root@hadoop102:/etc/systemd/system.conf
rsync /etc/systemd/system.conf root@hadoop103:/etc/systemd/system.conf
rsync /etc/systemd/system.conf root@hadoop104:/etc/systemd/system.conf
# 在每台主机上执行,使配置生效
sysctl -p
3、配置hadoop
3.1 hadoop-env.sh
Hadoop默认使用的日志级别是info,这意味着频繁操作文件时会疯狂输出日志,影响性能,所以我们适当下调日志级别,同时将初始化堆栈内存调高。HDFS_AUDIT_LOGGER主管NN的编辑日志,所以将此下调至WARN。
#配置java安装录入
export JAVA_HOME=/home/hadoop/hadoop/jdk1.8
#配置hadoop NameNode运行堆内存-Xmx2g -Xms2g(根据配置调优),日志级别下调至WARN级别
export HADOOP_NAMENODE_OPTS="-Xmx2g -Xms2g -Dhadoop.security.logger=${HADOOP_SECURITY_LOGGER:-INFO,RFAS} -Dhdfs.audit.logger=${HDFS_AUDIT_LOGGER:-WARN,NullAppender} $HADOOP_NAMENODE_OPTS"
#配置hadoop DataNode运行堆内存-Xmx2g -Xms2g(根据配置调优),日志级别下调至ERROR级别
export HADOOP_DATANODE_OPTS="-Xmx2g -Xms2g -Dhadoop.security.logger=ERROR,RFAS $HADOOP_DATANODE_OPTS"
配置hadoop进程id文件路径,HADOOP_PID_DIR默认为/tmp,操作系统重启时可能会清除
export HADOOP_PID_DIR=/opt/hadoop
3.2 core-site.xml
<!-- 指定hdfs的nameservice为masters,由于需要高可用,所以配置为集群名 -->
<property>
<name>fs.defaultFS</name>
<value>mycluster</value>
</property>
<!-- hadoop处理文件流的缓存区大小,默认为4096,现在扩大十倍 -->
<property>
<name>io.file.buffer.size</name>
<value>40960</value>
</property>
<!-- 指定hadoop临时目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/tmp/hadoop</value>
</property>
<!-- 指定zookeeper地址 -->
<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop101:2181,hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>
<!-- 解决:Active NameNode日志出现异常IPC‘s epoch [X] is less than the last promised epoch [X+1],出现短期的双Active -->
<property>
<name>ha.health-monitor.rpc-timeout.ms</name>
<value>180000</value>
</property>
3.3 hdfs-site.xml
要点1:dfs.namenode.rpc-address.mycluster.nn1
nn1:9000
默认为端口为:8020,如果此处配置为8020,则客户端访问可以不加端口号
默认为端口为:8020,即客户端调用时不加端口号,如
val uri=”hdfs://hadoop101/profile”;
则自动访问8020端口,如:Connecting to /hadoop101:8020
否则客户端访问可要加端口号,如:val uri=“hdfs://hadoop101:9000/profile”;
要点2:dfs.ha.fencing.methods配置有sshfence和shell两种方法:
- sshfence:防止namenode脑裂,当脑裂时,会自动通过ssh到old-active将其杀掉,将standby切换为active。但是只能在网络通畅时有效,一旦ipdown后fencing方法返回false,standby不会自动切换active,只能手动执行 hdfs haadmin failover namenode1 namenode2 进行切;所以需要加配shell(/bin/true)。想要kill掉namenode active后standby自动切换为active,需要安装psmisc(fuser);因为sshfence方式是使用fuser通过ssh登录old-active进行诊断从而切换active/standby的。
- shell(/bin/true):如果出现故障并且fencing方法返回false,则会继续执行shell(true),从而active/standby自动切换。fencing方法返回true,则不会执行shell。
<configuration> <!-- 集群名为mycluster --> <property> <name>dfs.nameservices</name> <value>mycluster</value> </property> <!-- mycluster下面有两个NameNode(故障转移机制),逻辑名可设置为nn1,nn2,后面的配置要统一引用该逻辑名 --> <property> <name>dfs.ha.namenodes.mycluster</name> <value>nn1,nn2</value> </property> <!-- nn1的RPC通信地址 --> <property> <name>dfs.namenode.rpc-address.mycluster.nn1</name> <value>nn1:9000</value> </property> <!-- nn1的http通信地址 --> <property> <name>dfs.namenode.http-address.mycluster.nn1</name> <value>nn1:50070</value> </property> <!-- nn1的servicerpc通信地址 --> <property> <name> dfs.namenode.servicerpc-address.mycluster.nn1</name> <value>nn1:53310</value> </property> <!-- nn2的RPC通信地址 --> <property> <name>dfs.namenode.rpc-address.mycluster.nn2</name> <value>nn2:9000</value> </property> <!-- nn2的http通信地址 --> <property> <name>dfs.namenode.http-address.mycluster.nn2</name> <value>nn2:50070</value> </property> <!-- nn2的servicerpc通信地址 --> <property> <name>dfs.namenode.servicerpc-address.mycluster.nn2</name> <value>nn2:53310</value> </property> <!-- 指定NameNode的元数据在JournalNode上的存放位置 --> <property> <name> dfs.namenode.name.dir </name> <value>/opt/hadoop/mycluster</value> <final>true</final> </property> <!-- 指定NameNode的元数据在JournalNode上的存放位置,必须是journalnode启动的节点 --> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://hadoop102:8485;hadoop104:8485/mycluster</value> </property> <!-- 指定JournalNode在本地磁盘存放数据的位置 --> <property> <name>dfs.journalnode.edits.dir</name> <value>/opt/tmp/hadoop/journal</value> </property> <!-- 开启NameNode失败自动切换 --> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</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> <!-- 使用sshfence隔离机制时需要ssh免登陆 --> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/root/.ssh/id_rsa</value> </property> <!-- 配置sshfence隔离机制超时时间 --> <property> <name>dfs.ha.fencing.ssh.connect-timeout</name> <value>30000</value> </property> <!-- 指定DataNode数据的存放位置,建议一台机器挂多个盘(逗号分隔),一方面增大容量,另一方面减少磁盘单点故障及增强磁盘读写能力 --> <property> <name> dfs.datanode.data.dir </name> <value>/opt/hadoop/data</value> <final>true</final> </property> <property> <name> dfs.namenode.checkpoint.dir.mycluster </name> <value>/opt/hadoop/data/dfs/namesecondary</value> <final>true</final> </property> <!--每个DataNode上需预留的空间,给非hdfs使用,默认为0,bytes --> <property> <name> dfs.datanode.du.reserved </name> <value>102400</value> <final>true</final> </property> <!--限制hdfs负载均衡时占用的最大带宽bytes --> <property> <name>dfs.datanode.balance.bandwidthPerSec</name> <value>10485760000</value> </property> </configuration>
3.4 mapred-site.xml
<configuration>
<!-- 指定mr运行在yarn上 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!-- 让任务跟踪器在任务完成时发送一个退出频段的心跳,以获得更好的延迟 -->
<property>
<name>mapreduce.tasktracker.outofband.heartbeat</name>
<value>true</value>
</property>
</configuration>
3.5 yarn-site.xml
<configuration>
<!-- 开启RM高可用 -->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!-- 指定RM的cluster id -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>RM_HA_ID</value>
</property>
<!-- 指定RM的名字 -->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!-- 分别指定RM的地址。因为他们都要占用大量资源,可以把namenode和resourcemanager分开到不同的服务器上 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hadoop103</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop104</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>
<!-- 指定zk集群地址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop101:2181,hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 输出包路径 -->
<property>
<name>yarn.application.classpath</name>
<value>
/opt/hadoop/etc/hadoop,
/opt/hadoop/share/hadoop/common/lib/*,
/opt/hadoop/share/hadoop/common/*,
/opt/hadoop/share/hadoop/hdfs,
/opt/hadoop/share/hadoop/hdfs/lib/*,
/opt/hadoop/share/hadoop/hdfs/*,
/opt/hadoop/share/hadoop/mapreduce/lib/*,
/opt/hadoop/share/hadoop/mapreduce/*,
/opt/hadoop/share/hadoop/yarn,
/opt/hadoop/share/hadoop/yarn/lib/*,
/opt/hadoop/share/hadoop/yarn/*
</value>
</property>
</configuration>
3.6 workers
vim etc/hadoop/workers
hadoop101
hadoop102
hadoop103
hadoop104
4、启动集群
- 启动前配置脚本运行用户,防止脚本运行权限不够
```shell
统一在头部第二行开始添加下列参数
start-dfs.sh和stop-dfs.sh
HDFS_DATANODE_USER=root HDFS_DATANODE_SECURE_USER=hdfs HDFS_NAMENODE_USER=root HDFS_SECONDARYNAMENODE_USER=root HDFS_JOURNALNODE_USER=root HDFS_ZKFC_USER=root
start-yarn.sh和stop-yarn.sh
YARN_RESOURCEMANAGER_USER=root HDFS_DATANODE_SECURE_USER=yarn YARN_NODEMANAGER_USER=root
- 分发hadoop安装文件
```shell
scp -r /opt/hadoop root@hadoop102:/opt/hadoop
scp -r /opt/hadoop root@hadoop103:/opt/hadoop
scp -r /opt/hadoop root@hadoop104:/opt/hadoop
- 启动所有的Zookeeper节点,如果编写了群启脚本可以直接运行。
首次启动需要格式化HDFS,在第一台主机上执行即可。
[root@hadoop101 myTools]# hdfs namenode format
接下来严格按照步骤启动,建议编写脚本完成。