前言
老长一段时间没有回来写博客了,但这段时间我也没闲着一直在弄 Hadoop、Hive、HBase、Spark...(听起来似乎很牛X,实际只是弄懂和简单的应用这个软件生态 和 摸鱼),也用 Joplin 记录下折腾过程中碰到的问题和解决方案,最近在慢慢更新(...
这篇文章是我跟着 GitHub 一个 Hadoop 入门教程一步步做完之后临摹下来的 /狗头。原文链接
前置条件
- 所有节点都配置好
JDK
:Linux下安装 JDK - 所有节点都安装配置好
Zookeeper
:Zokeeper 单机或集群搭建 - 所有节点都配置好
免密
登录 - 所有节点都配置好
/etc/hosts
文件
安装 Hadoop
解压 Hadoop 安装包
[root@master ~]# tar -zxvf hadoop-2.6.0.tar.gz -C /usr/local/
修改配置文件
core-site.xml
<configuration>
<property>
<!-- 指定 namenode 的 hdfs 协议文件系统的通信地址 -->
<name>fs.defaultFS</name>
<value>hdfs://master:8020</value>
</property>
<property>
<!-- 指定 hadoop 集群存储临时文件的目录 -->
<name>hadoop.tmp.dir</name>
<value>/usr/local/hadoop-2.6.0/tmp</value>
</property>
<property>
<!-- ZooKeeper 集群的地址 -->
<name>ha.zookeeper.quorum</name>
<value>master:2181,slave1:2181,slave2:2181</value>
</property>
<property>
<!-- ZKFC 连接到 ZooKeeper 超时时长 -->
<name>ha.zookeeper.session-timeout.ms</name>
<value>10000</value>
</property>
</configuration>
hdfs-site.xml
<configuration>
<property>
<!-- 指定 HDFS 副本的数量 -->
<name>dfs.replication</name>
<value>3</value>
</property>
<property>
<!-- namenode 节点数据(即元数据)的存放位置,可以指定多个目录实现容错,多个目录用逗号分隔 -->
<name>dfs.namenode.name.dir</name>
<value>/usr/local/hadoop-2.6.0/tmp/dfs/namenode</value>
</property>
<property>
<!-- datanode 节点数据(即数据块)的存放位置 -->
<name>dfs.datanode.data.dir</name>
<value>/usr/local/hadoop-2.6.0/tmp/datanode</value>
</property>
<property>
<!-- 集群服务的逻辑名称 -->
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<property>
<!-- NameNode ID 列表-->
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<property>
<!-- nn1 的 RPC 通信地址 -->
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>master:8020</value>
</property>
<property>
<!-- nn2 的 RPC 通信地址 -->
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>master:8020</value>
</property>
<property>
<!-- nn1 的 http 通信地址 -->
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>master:50070</value>
</property>
<property>
<!-- nn2 的 http 通信地址 -->
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>slave1:50070</value>
</property>
<property>
<!-- NameNode 元数据在 JournalNode 上的共享存储目录 -->
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://master:8485;slave1:8485;slave2:8485/mycluster</value>
</property>
<property>
<!-- Journal Edit Files 的存储目录 -->
<name>dfs.journalnode.edits.dir</name>
<value>/usr/local/hadoop-2.6.0/tmp/dfs/journalnode</value>
</property>
<property>
<!-- 配置隔离机制,确保在任何给定时间只有一个 NameNode 处于活动状态 -->
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<property>
<!-- 使用 sshfence 机制时需要 ssh 免密登录 -->
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_rsa</value>
</property>
<property>
<!-- SSH 超时时间 -->
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
<property>
<!-- 访问代理类,用于确定当前处于 Active 状态的 NameNode -->
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<property>
<!-- 开启故障自动转移 -->
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
</configuration>
yarn-site.xml
<configuration>
<property>
<!--配置 NodeManager 上运行的附属服务。需要配置成 mapreduce_shuffle 后才可以在 Yarn 上运行 MapReduce 程序。-->
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<!-- 是否启用日志聚合 (可选) -->
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<!-- 聚合日志的保存时间 (可选) -->
<name>yarn.log-aggregation.retain-seconds</name>
<value>86400</value>
</property>
<property>
<!-- 启用 RM HA -->
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<property>
<!-- RM 集群标识 -->
<name>yarn.resourcemanager.cluster-id</name>
<value>my-yarn-cluster</value>
</property>
<property>
<!-- RM 的逻辑 ID 列表 -->
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<property>
<!-- RM1 的服务地址 -->
<name>yarn.resourcemanager.hostname.rm1</name>
<value>slave1</value>
</property>
<property>
<!-- RM2 的服务地址 -->
<name>yarn.resourcemanager.hostname.rm2</name>
<value>slave2</value>
</property>
<property>
<!-- RM1 Web 应用程序的地址 -->
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>slave1:8088</value>
</property>
<property>
<!-- RM2 Web 应用程序的地址 -->
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>slave2:8088</value>
</property>
<property>
<!-- ZooKeeper 集群的地址 -->
<name>yarn.resourcemanager.zk-address</name>
<value>master:2181,slave1:2181,slave2:2181</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>
</configuration>
mapred-site.xml
<configuration>
<property>
<!--指定 mapreduce 作业运行在 yarn 上-->
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
slaves
配置所有从属节点的主机名或 IP 地址,每行一个。所有从属节点上的 DataNode 服务和 NodeManager 服务都会被启动。
master
slave1
slave2
分发 Hadoop 目录
[root@master ~]# scp -r /usr/local/hadoop-2.6.0 root@slave1:/usr/local/
[root@master ~]# scp -r /usr/local/hadoop-2.6.0 root@slave2:/usr/local/
启动集群
各节点启动 Zookeeper
分别到三个节点上启动 Zookeeper 服务
zkServer.sh start
启动Journalnode
分别到三个节点上 $HADOOP_HOME/sbin
目录下启动 Journalnode 进程
hadoop-daemon.sh start journalnode
格式化主节点 NameNode
[root@master ~]# hdfs namenode -format
执行格式化后需要将 NameNode
元数据内容复制分发到其它未格式化的 NameNode
上。元数据存放在 hdfs-site.xml
中 dfs.namenode.name.dir
属性值所指向的路径。
[root@master ~]# scp -r /usr/local/hadoop-2.6.0/tmp root@slave1:/usr/local/hadoop-2.6.0
初始化 HA 状态
在任意 NameNode
上来初始化 Zookeeper
中的 HA 状态
[root@master ~]# hdfs zkfc -formatZK
启动 HDFS
进入 master
节点的 $HADOOP_HOME/sbin
目录,启动 HDFS 。此时 master
和 slave1
上的 NameNode
服务和三个节点上的 DataNode
服务都已经启动。
[root@master ~]# start-dfs.sh
启动 YARN
进入 slave1
节点的 $HADOOP_HOME/sbin
目录, 启动 YARN。此时 slave1
上的 ResourceManager
服务和三个节点上的 NodeManager
都已启动:
[root@slave1 ~]# start-yarn.sh
需要注意的是 这个时候
slave2
上的ResourceManager
通常是没有启动的,需要手动启动:
[slave2@root ~]# yarn-daemon.sh start resourcemanager
查看集群
查看进程
成功启动后,每台服务器上的进程应该如下:
[root@master sbin]# jps
4512 DFSZKFailoverController
3714 JournalNode
4114 NameNode
3668 QuorumPeerMain
5012 DataNode
4639 NodeManager
[root@slave1 sbin]# jps
4499 ResourceManager
4595 NodeManager
3465 QuorumPeerMain
3705 NameNode
3915 DFSZKFailoverController
5211 DataNode
3533 JournalNode
[root@slave2 sbin]# jps
3491 JournalNode
3942 NodeManager
4102 ResourceManager
4201 DataNode
3435 QuorumPeerMain