如果你是第一次搭建 hadoop ,建议从零开始,先去看 Linux 安装、配置 hadoop
系统设计
hadoop 完全分布式模式使用的是master-slave(一主多从)的架构,即一个 namanode,多个 datanode。 由于该模式只有一个 namanode,所以存在单点故障问题,生产中一般很少使用。
主机分配
| host | ip | hostname | OS |
|---|---|---|---|
| 虚拟机1 | 192.168.56.101 | hadoop1 | CentOS 7 |
| 虚拟机2 | 192.168.56.102 | hadoop2 | CentOS 7 |
| 虚拟机3 | 192.168.56.103 | hadoop3 | CentOS 7 |
功能分配
| hadoop1 | hadoop2 | hadoop3 | |
|---|---|---|---|
| HDFS | nameNode dataNode | SecondaryNameNode dataNode | dataNode |
| YARN | nodeManager | nodeManager | resourceManager nodeManager |
环境准备
如上,我们需要3台虚拟机,我们可以先创建好一台机器后,通过虚拟机软件的克隆功能,在克隆出两台来,注意克隆出来的机器需要对iP、网卡、mac地址等地方进行修改,怎么克隆和怎么解决克隆产生的问题,这里就不介绍了,不是本文的重点,网上教程很多,这里默认大家都完成了。
配置 java 环境
建议在克隆之前,先在一台机器上配好再克隆,这样多台机器的 java 环境都配置好了。
具体 java 环境配置,参考 Linux 安装配置 java 环境
设置主机名
hostnamectl set-hostname 主机名
修改完成之后重启
reboot
其他几台机器同理
配置 hosts 文件
首先在 hadoop1 上配置 hosts
vi /etc/hosts
在文件末尾追加如下内容
192.168.56.101 hadoop1
192.168.56.102 hadoop2
192.168.56.103 hadoop3
将文件拷贝到其他主机
scp /etc/hosts root@hadoop2:/etc/hosts
scp /etc/hosts root@hadoop3:/etc/hosts
配置静态IP
首先去 hadoop1 下查看网络配置情况
ifconfig
可以看到网卡叫 enp0s3 ip 是 192.168.56.101 ,子网掩码是 255.255.255.0 ,广播地址是 192.168.56.255。这里 ip 虽然是我们想要的,但是这是 dhcp 服务器分配的,可能会发生变化,我们最后还配置成静态的
vi /etc/sysconfig/network-scripts/ifcfg-网卡名
这里的网卡名是上面查到的 enp0s3
如果想修改成静态ip,首先把BOOTPROTO="dhcp"改成BOOTPROTO="static",然后在末尾追加广播地址、ip地址、子网掩码、网关地址
BROADCAST=192.168.56.255
IPADDR=192.168.56.101
NETMASK=255.255.255.0
GATEWAY=192.168.56.1
最后重启网络
/etc/init.d/network restart
其他几台机器也同理
时间同步
设置时区
首先设置所有机器在同一时区下, 比如 UTC+8
查看系统时区
date -R
如果显示 +0800,就说明是 UTC+8 ,就不需要改,如果不是,则需要更改时区
tzselect
如上图选择,完成之后,还需要复制相应的时区文件,替换系统时区文件,或者创建链接文件
cp /usr/share/zoneinfo/$主时区/$次时区 /etc/localtime
例如:在设置中国时区使用亚洲/上海(+8)
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
同步网络世界
安装 ntpdate
yum -y install ntp ntpdate
同步系统世界与网络世界
ntpdate cn.pool.ntp.org
同步系统时间与硬件时间
Linux的时间分为System Clock(系统时间)和Real Time Clock (硬件时间,简称RTC)。
- 系统时间:指当前Linux Kernel中的时间。
- 硬件时间:主板上有电池供电的时间。 这两个时间相互独立,每次系统启动的时候,系统读取硬件时间当做系统时间,为了防止两者误差,将同步后的系统时间写入硬件时间
hwclock –w
其他机器操作相同
禁用防火墙
我的操作系统是 contos7
关闭防火墙
systemctl stop firewalld
取消开机启动
systemctl disable firewalld
配置 ssh 免密登陆
配置 ssh 免密登陆有两个目的
- 让 nameNode 下发命令给 dataNode
- 让 resourceManager 下发命令给 nodeManager
相对的,我们也需要配置 nameNode 免登陆 nameNode,resourceManager 免的登陆 nodeManager。
按照文章开始的功能划分,即
- 配置 hadoop1 免登陆 hadoop2 、hadoop3已经免密登陆自己
- 配置 hadoop2 免登陆 hadoop1 、hadoop3
具体怎么配置 Linux 系统之间的免密登陆,参考 Linux 免密登陆
集群搭建
我们需要现在一台机器上配置好 hadoop,然后再把它拷贝到其他机器上,这里我选择在 hadoop1 也就是要做为 nameNode 的那台机器
下载 hadoop
建议在克隆之前,先在一台机器上,下载、解压好再克隆,这样多台机器就都有了
下载
wget https://archive.apache.org/dist/hadoop/common/hadoop-3.1.3/hadoop-3.1.3.tar.gz
解压
tar -zxvf hadoop-3.1.3.tar.gz -C /usr/local/hadoop
我是解压到 /usr/local/hadoop 目录下,其中 /hadoop 目录是我预先创建的
配置 hadoop 环境变量
vi /etc/profile
在文件末尾追加如下内容
export HADOOP_HOME=/usr/local/hadoop/hadoop-3.1.3
export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin
注意 PATH 的配置
配置完成之后,刷新
source /etc/profile
查看变量是否生效
hadoop version
配置 hadoop-env.sh
首先,查看 JAVA_HOME 的地址
echo $JAVA_HOME
配置 JAVA_HOME 路径
vi $HADOOP_HOME/etc/hadoop/hadoop-env.sh
找到 export JAVA_HOME,在下方添加
export JAVA_HOME=JAVA_HOME 的地址
配置 core-site.xml
创建 HDFS 数据存储目录,我的存储路径是放在 $HADOOP_HOME目录下的 /hdfs_data/
mkdir /usr/local/hadoop/hadoop-3.1.3/hdfs_data
mkdir /usr/local/hadoop/hadoop-3.1.3/tmp
vi $HADOOP_HOME/etc/hadoop/core-site.xml
<configuration>
<property>
<!-- 设置 NameNode 的ip及端口,这里的ip也可以换成主机名 -->
<name>fs.defaultFS</name>
<value>hdfs://hadoop1:9000</value>
</property>
<property>
<!-- 存放数据的临时目录,注意这里的路径要写绝对路径,并且不要使用 ~ 等符号 -->
<name>hadoop.tmp.dir</name>
<value>/usr/local/hadoop/hadoop-3.1.3/tmp</value>
</property>
<property>
<!-- 设置 HDFS 数据在本地文件系统上的存储 -->
<name>dfs.datanode.data.dir</name>
<value>/usr/local/hadoop/hadoop-3.1.3/hdfs_data</value>
</property>
</configuration>
配置 hdfs-site.xml
vi $HADOOP_HOME/etc/hadoop/hdfs-site.xml
<configuration>
<property>
<!-- 设置 SecondaryNameNode 的ip及端口,这里的ip也可以换成主机名-->
<name>dfs.namenode.secondary.http-address</name>
<value>hadoop2:9868</value>
</property>
</configuration>
配置 mapred-site.xml
如果没有 `mapred-site.xml` 文件,看下是不是有个 `mapred-site.xml.template` 的配置模板文件,复制此模板生成 `mapred-site.xml`
vi $HADOOP_HOME/etc/hadoop/mapred-site.xml
<configuration>
<property>
<!-- 设置 mapreduce 使用 yarn 框架 -->
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
配置 yarn-site.xml
vi $HADOOP_HOME/etc/hadoop/yarn-site.xml
<configuration>
<property>
<!-- 设置 yarn 的混洗方式为 mapreduce 默认的混洗算法 -->
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<!-- 指定ResourceManager的地址 -->
<name>yarn.resourcemanager.address</name>
<value>hadoop3</value>
</property>
</configuration>
配置 workers
注意 hadoop2 中的配置文件为 slaves ,而3中已被修改为 workers
vi $HADOOP_HOME/etc/hadoop/workers
删除原来的内容后,添加如下配置
hadoop1
hadoop2
hadoop3
将配置好的 hadoop 拷贝到其他机器
scp -r /usr/local/hadoop/ root@hadoop2:/usr/local/hadoop/
scp -r /usr/local/hadoop/ root@hadoop3:/usr/local/hadoop/
格式化 HDFS
格式化是对HDFS这个分布式文件系统中的DataNode进行分块,统计所有分块后的初始元数据的存储在NameNode中。
格式化时,要注意 hadoop.tmp.dir 目录的权限问题
~/hadoop-3.1.3/bin/hdfs namenode -format
显示 has been successfully formatted 则表示格式化成功
格式化成功后,查看 core-site.xml 里 hadoop.tmp.dir 指定的目录下是否有了 dfs 目录
tree -C -pf ~/hadoop-3.1.3/hdfs/tmp/
- fsimage_* 是 NameNode 元数据在内存满了后,持久化保存到本地的文件。
- fsimage_.md5 是校验文件,用于校验 fsimage_ 的完整性。
- seen_txid 是 hadoop 的版本
- vession 文件内容
- namespaceID :NameNode 的唯一ID
- clusterID : 集群ID,NameNode 和 DataNode 的集群ID应该一致,表明是一个集群。
cat /root/hadoop-3.1.3/hdfs/tmp/dfs/name/current/VERSION
格式化 HDFS
格式化是对HDFS这个分布式文件系统中的DataNode进行分块,统计所有分块后的初始元数据的存储在NameNode中。
$HADOOP_HOME/bin/hdfs namenode -format
显示 has been successfully formatted 则表示格式化成功
格式化成功后,查看 core-site.xml 里 hadoop.tmp.dir 指定的目录下是否有了 dfs 目录
tree -C -pf $HADOOP_HOME/tmp/
- fsimage_* 是 NameNode 元数据在内存满了后,持久化保存到本地的文件。
- fsimage_.md5 是校验文件,用于校验 fsimage_ 的完整性。
- seen_txid 是 hadoop 的版本
- vession 文件内容
- namespaceID :NameNode 的唯一ID
- clusterID : 集群ID,NameNode 和 DataNode 的集群ID应该一致,表明是一个集群。
cat $HADOOP_HOME/tmp/dfs/name/current/VERSION
启动集群
在 hadoop1 上执行如下命令
start-all.sh
如果出现上面的错误,是因为缺少用户定义而造成的
在 start-dfs.sh 、stop-dfs.sh 文件头部添加如下内容
HDFS_NAMENODE_USER=root
HDFS_DATANODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root
在 start-yarn.sh 、stop-yarn.sh 文件头部添加如下内容
YARN_RESOURCEMANAGER_USER=root
YARN_NODEMANAGER_USER=root
配置好之后在重新启动