1、规划

  • 现在,使用最新版本的hadoop相关软件搭建一个HA高可用集群,hadoop借助Zookeeper完成高可用,同时需要启动名为JournalNodeDFSZK 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以上

    1. [root@hadoop101 hadoop]# ulimit -a
    2. core file size (blocks, -c) unlimited
    3. data seg size (kbytes, -d) unlimited
    4. scheduling priority (-e) 0
    5. file size (blocks, -f) unlimited
    6. pending signals (-i) 14898
    7. max locked memory (kbytes, -l) 16384
    8. max memory size (kbytes, -m) unlimited
    9. open files (-n) 10240
    10. pipe size (512 bytes, -p) 8
    11. POSIX message queues (bytes, -q) 819200
    12. real-time priority (-r) 0
    13. stack size (kbytes, -s) 8192
    14. cpu time (seconds, -t) unlimited
    15. max user processes (-u) 14898
    16. virtual memory (kbytes, -v) unlimited
    17. file locks (-x) unlimited
  • 编辑配置文件

    1. vim /etc/systemd/system.conf
    2. #最大文件
    3. DefaultLimitNOFILE=10240
    4. #进程打开数
    5. DefaultLimitNPROC=40960
    1. rsync /etc/systemd/system.conf root@hadoop102:/etc/systemd/system.conf
    2. rsync /etc/systemd/system.conf root@hadoop103:/etc/systemd/system.conf
    3. rsync /etc/systemd/system.conf root@hadoop104:/etc/systemd/system.conf
    1. # 在每台主机上执行,使配置生效
    2. sysctl -p

3、配置hadoop

3.1 hadoop-env.sh

  • Hadoop默认使用的日志级别是info,这意味着频繁操作文件时会疯狂输出日志,影响性能,所以我们适当下调日志级别,同时将初始化堆栈内存调高。HDFS_AUDIT_LOGGER主管NN的编辑日志,所以将此下调至WARN。

    1. #配置java安装录入
    2. export JAVA_HOME=/home/hadoop/hadoop/jdk1.8
    3. #配置hadoop NameNode运行堆内存-Xmx2g -Xms2g(根据配置调优),日志级别下调至WARN级别
    4. 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"
    5. #配置hadoop DataNode运行堆内存-Xmx2g -Xms2g(根据配置调优),日志级别下调至ERROR级别
    6. export HADOOP_DATANODE_OPTS="-Xmx2g -Xms2g -Dhadoop.security.logger=ERROR,RFAS $HADOOP_DATANODE_OPTS"
  • 配置hadoop进程id文件路径,HADOOP_PID_DIR默认为/tmp,操作系统重启时可能会清除

    1. export HADOOP_PID_DIR=/opt/hadoop

3.2 core-site.xml

  1. <!-- 指定hdfs的nameservice为masters,由于需要高可用,所以配置为集群名 -->
  2. <property>
  3. <name>fs.defaultFS</name>
  4. <value>mycluster</value>
  5. </property>
  6. <!-- hadoop处理文件流的缓存区大小,默认为4096,现在扩大十倍 -->
  7. <property>
  8. <name>io.file.buffer.size</name>
  9. <value>40960</value>
  10. </property>
  11. <!-- 指定hadoop临时目录 -->
  12. <property>
  13. <name>hadoop.tmp.dir</name>
  14. <value>/opt/tmp/hadoop</value>
  15. </property>
  16. <!-- 指定zookeeper地址 -->
  17. <property>
  18. <name>ha.zookeeper.quorum</name>
  19. <value>hadoop101:2181,hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
  20. </property>
  21. <!-- 解决:Active NameNode日志出现异常IPC‘s epoch [X] is less than the last promised epoch [X+1],出现短期的双Active -->
  22. <property>
  23. <name>ha.health-monitor.rpc-timeout.ms</name>
  24. <value>180000</value>
  25. </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
    
  • 接下来严格按照步骤启动,建议编写脚本完成。