hadoop 完全分布式系统搭建

1,792 阅读4分钟

如果你是第一次搭建 hadoop ,建议从零开始,先去看 Linux 安装、配置 hadoop

系统设计

hadoop 完全分布式模式使用的是master-slave(一主多从)的架构,即一个 namanode,多个 datanode。 由于该模式只有一个 namanode,所以存在单点故障问题,生产中一般很少使用。

主机分配

hostiphostnameOS
虚拟机1192.168.56.101hadoop1CentOS 7
虚拟机2192.168.56.102hadoop2CentOS 7
虚拟机3192.168.56.103hadoop3CentOS 7

功能分配

hadoop1hadoop2hadoop3
HDFSnameNode

dataNode
SecondaryNameNode

dataNode
dataNode
YARNnodeManagernodeManagerresourceManager

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 免密登陆有两个目的

  1. 让 nameNode 下发命令给 dataNode
  2. 让 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.xmlhadoop.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.xmlhadoop.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.shstop-dfs.sh 文件头部添加如下内容

HDFS_NAMENODE_USER=root
HDFS_DATANODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root

start-yarn.shstop-yarn.sh 文件头部添加如下内容

YARN_RESOURCEMANAGER_USER=root
YARN_NODEMANAGER_USER=root

配置好之后在重新启动