虚拟机中搭建 Hadoop 集群
Hadoop 是一个由 Apache 基金会所开发的分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。Hadoop 实现了一个分布式文件系统( Distributed File System),其中一个组件是 HDFS(Hadoop Distributed File System)。HDFS 有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS 放宽了(relax)POSIX 的要求,可以以流的形式访问(streaming access)文件系统中的数据。Hadoop 的框架最核心的设计就是:HDFS 和 MapReduce。HDFS 为海量的数据提供了存储,而 MapReduce 则为海量的数据提供了计算。
# 提前准备
# 系统
- CPU虚拟化:已启用
# 安装
- 运行虚拟机的工具:VMware (opens new window) (激活密钥:MC60H-DWHD5-H80U9-6V85M-8280D)
- SSH 工具:FinalShell (opens new window)
# 下载
- Linux 镜像:CentOS (opens new window)
- Java 环境:JDK8 (opens new window)
- Hadoop 环境:Hadoop (opens new window)
# 配置模板虚拟机
# 安装虚拟机
- 虚拟机配置:处理器1C 内存1G 硬盘30G
# 网络设置
开始前可以使用 ip addr 查看虚拟机的 IP,然后使用 SSH 工具连接虚拟机方便后续配置信息的修改。
# 修改镜像源到国内
# 安装 Linux 必备工具
安装
#CentOS yum install -y curl wget vim zip sudo rsync openssh-server openssh-clients #Debian apt install -y curl wget vim zip sudo rsync
1
2
3
4
5
# 关闭防火墙
查看防火墙的状态
systemctl status firewalld.service
1关闭防火墙
systemctl stop firewalld.service
1关闭防火墙自动启动
systemctl disable firewalld.service
1开启防火墙
systemctl start firewalld.service
1开启防火墙自动启动
systemctl enable firewalld.service
1
# 静态 IP 配置
备份网络配置文件
# CentOS sudo cp /etc/sysconfig/network-scripts/ifcfg-ens33 /etc/sysconfig/network-scripts/ifcfg-ens33.bak # Debian sudo cp /etc/network/interfaces /etc/network/interfaces.bak
1
2
3
4
5编辑网络配置文件
# CentOS sudo vim /etc/sysconfig/network-scripts/ifcfg-ens33 # Debian sudo vim /etc/network/interfaces
1
2
3
4
5CentOS 参考配置
TYPE="Ethernet" PROXY_METHOD="none" BROWSER_ONLY="no" BOOTPROTO="static" DEFROUTE="yes" IPV4_FAILURE_FATAL="no" IPV6INIT="yes" IPV6_AUTOCONF="yes" IPV6_DEFROUTE="yes" IPV6_FAILURE_FATAL="no" IPV6_ADDR_GEN_MODE="stable-privacy" NAME="ens33" UUID="5a646ee0-bc7e-4793-83b9-1784f237c07d" DEVICE="ens33" ONBOOT="yes" IPADDR=192.168.10.102 GATEWAY=192.168.10.2 NETMASK=255.255.255.0 DNS1=114.114.114.114
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20Debian 参考配置:
# The loopback network interface auto lo iface lo inet loopback # The primary network interface allow-hotplug ens33 iface ens33 inet static address 192.168.10.100 netmask 255.255.255.0 gateway 192.168.10.2 nameserver 114.114.114.114
1
2
3
4
5
6
7
8
9
10
11
# 修改主机名称
编辑 hostname 文件
sudo vim /etc/hostname
1
# 修改主机名称映射
编辑 hosts 文件
sudo vim /etc/hosts
1参考配置:
127.0.0.1 localhost 127.0.1.1 hadoop100 192.168.10.100 hadoop100 192.168.10.101 hadoop101 192.168.10.102 hadoop102 192.168.10.103 hadoop103 192.168.10.104 hadoop104
1
2
3
4
5
6
7
8重启使配置生效
reboot
1因为设置了静态 IP,所以 SSH 工具中的主机 IP 也需要对应修改。
查看是否生效
#查看 IP ip addr #查看主机名 hostname
1
2
3
4
5
# 权限设置
允许 root 用户以 SSH 方式登录
#使用 vim 编辑 sshd_config 文件 sudo vim /etc/ssh/sshd_config
1
2找到下面这一段:
#PermitRootLogin prohibit-password
1修改成下面这一段,注意前面的 # 号需要去掉:
PermitRootLogin yes
1然后重启 SSH 服务:
sudo service sshd restart
1配置普通用户具有 root 权限,方便后期使用 sudo 执行 root 权限的命令
#使用 vim 编辑 sudoers 文件 sudo vim /etc/sudoers
1
2找到下面这一段:
%wheel ALL=(ALL) ALL
1在它的下面添加一行:
<username> ALL=(ALL) NOPASSWD:ALL #替换 <username> 为你自己的用户名
1
2参考配置:
## Allow root to run any commands anywhere root ALL=(ALL) ALL ## Allows members of the 'sys' group to run networking, software, ## service management apps and more. # %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS ## Allows people in group wheel to run all commands %wheel ALL=(ALL) ALL hadoop ALL=(ALL) NOPASSWD:ALL ## Same thing without a password # %wheel ALL=(ALL) NOPASSWD: ALL
1
2
3
4
5
6
7
8
9
10
11
12
# 克隆虚拟机
- 以上步骤完成后关闭虚拟机,然后进行克隆,克隆方法选择创建完整克隆
- 克隆三台名为 hadoop102 到 hadoop104 的虚拟机
- 分别修改 hadoop102 到 hadoop104 的静态 IP 地址和主机名称
# SSH 连接
修改 Windows 主机映射文件
修改此路径中的 hosts 文件 C:\Windows\System32\drivers\etc\ Windows7 用户可以直接修改此文件 Windows10 用户需要复制此文件到其他位置修改,然后再覆盖原始的文件
1
2
3
4
5参考配置:
#将如下内容添加到 hosts 文件最后 192.168.10.100 hadoop100 192.168.10.101 hadoop101 192.168.10.102 hadoop102 192.168.10.103 hadoop103 192.168.10.104 hadoop104
1
2
3
4
5
6
7使用 FinalShell 添加 SSH 连接
名称:hadoop102 (可自定义) 主机:hadoop102 端口:22 名称:hadoop103 (可自定义) 主机:hadoop103 端口:22 名称:hadoop104 (可自定义) 主机:hadoop104 端口:22
1
2
3
4
5
6
7
8
9
10
11
# 安装 JDK & Hadoop
首先在 hadoop102 上安装,后续可以使用 scp 和 rsync 命令复制或同步到 hadoop103、hadoop104。
# 创建安装目录
#创建安装目录
sudo mkdir /opt/module /opt/software
#修改目录所有者
sudo chown <user>:<group> /opt/module/ /opt/software/
#<user>:<group> 需要替换成自己设置的用户名和用户组,例如:
sudo chown hadoop:hadoop /opt/module/ /opt/software/
2
3
4
5
6
7
使用 SSH 工具上传压缩包到 /opt/software 目录中
# 解压
注意:如果下载的版本不一样,压缩包名称也会不一样,自行修改。
tar -zxvf /opt/software/jdk-8u212-linux-x64.tar.gz -C /opt/module
tar -zxvf /opt/software/hadoop-3.1.3.tar.gz -C /opt/module
2
# 配置环境变量
#生成 my_env.sh 文件进行编辑
sudo vim /etc/profile.d/my_env.sh
2
参考配置:
#JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_212
export PATH=$PATH:$JAVA_HOME/bin
#HADOOP_HOME
export HADOOP_HOME=/opt/module/hadoop-3.1.3
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin
2
3
4
5
6
7
8
# 更新环境变量
source /etc/profile
# 验证环境变量是否生效
#查看版本
java -version
hadoop version
2
3
# scp & rsync 命令
# 定义
- scp 可以实现服务器与服务器之间的数据拷贝 (from server1 to server2)
- rsync 主要用于备份和镜像,具有速度快、避免复制相同内容和支持符号链接的优点
- 差异:用 rsync 做文件的复制要比 scp 的速度快,rsync 只对差异文件做更新,scp 是把所有文件都复制过去
# 基本语法
scp
scp -r $pdir/$fname $user@$host:$pdir/$fname $pdir/$fname #表示要拷贝的文件路径/名称 $user@$host:$pdir/$fname #表示目的地的用户@主机:目的地路径/名称 #带参数 -r 表示拷贝目录,不带 -r 则拷贝文件
1
2
3
4
5
6
7rsync
rsync -av $pdir/$fname $user@$host:$pdir/$fname #参数 -a 表示归档模式,表示以递归方式传输文件,并保持所有文件属性 #参数 -v 显示过程
1
2
3
4
# 实操
scp
#将 hadoop102 中的 /opt/module 拷贝到 hadoop103 上 scp -r /opt/module hadoop@hadoop103:/opt #从 hadoop102 中拷贝 /opt/module 到 hadoop103 上 scp -r hadoop@hadoop102:/opt/module /opt
1
2
3
4
5rsync
#同步 hadoop102 和 hadoop103 中的 /opt/module/hadoop-3.1.4 rsync -av /opt/module/hadoop-3.1.4 hadoop@hadoop103:/opt/module/hadoop-3.1.4
1
2
# xsync 分发脚本
#在 /bin 目录下生成 xsync 文件并编辑
sudo vim /bin/xsync
2
参考配置:
#!/bin/bash
#1. 判断参数个数
if [ $# -lt 1 ]; then
echo Not Enough Arguement!
exit
fi
#2. 遍历集群所有机器
for host in hadoop102 hadoop103 hadoop104; do
echo =============== $host ===============
#3. 遍历所有目录,挨个发送
for file in $@; do
#4. 判断文件是否存在
if [ -e $file ]; then
#5. 获取父目录
pdir=$(
cd -P $(dirname $file)
pwd
)
#6. 获取当前文件的名称
fname=$(basename $file)
ssh $host "mkdir -p $pdir"
rsync -av $pdir/$fname $host:$pdir
else
echo $file does not exists!
fi
done
done
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#让 xsync 具有可执行权限
sudo chmod 777 /bin/xsync
2
#使用 xsync 分发环境变量
sudo xsync /etc/profile.d/my_env.sh
2
#然后在每台主机上运行以下命令更新环境变量
source /etc/profile
2
# SSH 免密登录
#分别在 hadoop102、hadoop103、hadoop104 中创建 ssh 密钥
ssh-keygen -t rsa
2
#查看 ssh 密钥
ssh-keygen -l
2
#分别将公钥拷贝到 hadoop102、hadoop103、hadoop104 中
ssh-copy-id hadoop102
ssh-copy-id hadoop103
ssh-copy-id hadoop104
2
3
4
# 集群配置
# 集群部署规划
注意:NameNode 和 SecondaryNameNode 不要安装在同一台服务器上。ResourceManager 也很消耗内存,不要和 NameNode、SecondaryNameNode 配置在同一台服务器上
hadoop102 | hadoop103 | hadoop104 | |
---|---|---|---|
HDFS | NameNode DataNode | DataNode | SecondaryNameNode DataNode |
YARN | NodeManager | ResourceManager NodeManager | NodeManager |
# 自定义配置文件
core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml 四个配置文件都存放在 $HADOOP_HOME/etc/hadoop 这个目录下,用户可以根据项目需求重新进行修改配置。
# 核心配置
vim $HADOOP_HOME/etc/hadoop/core-site.xml
参考配置:
<configuration>
<!-- 指定 NameNode 的地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop102:8020</value>
</property>
<!-- 指定 hadoop 数据的存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/module/hadoop-3.1.3/data</value>
</property>
<!-- 配置 HDFS 网页登录使用的静态用户为 hadoop -->
<property>
<name>hadoop.http.staticuser.user</name>
<value>hadoop</value>
</property>
</configuration>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# HDFS 配置
vim $HADOOP_HOME/etc/hadoop/hdfs-site.xml
参考配置:
<configuration>
<!-- NameNode Web 访问地址 -->
<property>
<name>dfs.namenode.http-address</name>
<value>hadoop102:9870</value>
</property>
<!-- SecondaryNameNode Web 访问地址 -->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>hadoop104:9868</value>
</property>
</configuration>
2
3
4
5
6
7
8
9
10
11
12
# YARN 配置
vim $HADOOP_HOME/etc/hadoop/yarn-site.xml
参考配置:
<configuration>
<!-- 指定 MR 走 shuffle -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 指定 ResourceManager 的地址 -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop103</value>
</property>
<!-- 环境变量的继承 -->
<property>
<name>yarn.nodemanager.env-whitelist</name>
<value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_HOME,PATH,LANG,TZ</value>
</property>
</configuration>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# MapReduce 配置
vim $HADOOP_HOME/etc/hadoop/mapred-site.xml
参考配置:
<configuration>
<!-- 指定 MapReduce 程序运行在 YARN 上 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
2
3
4
5
6
7
# workers 配置
注意:该文件中添加的内容结尾不允许有空格,文件中不允许有空行。
vim $HADOOP_HOME/etc/hadoop/workers
参考配置:
hadoop102
hadoop103
hadoop104
2
3
# 分发配置文件
xsync $HADOOP_HOME/etc/hadoop
# 群起集群
启动集群
如果集群是第一次启动,需要在 hadoop102 节点格式化 NameNode
注意:格式化 NameNode,会产生新的集群 id,导致 NameNode 和 DataNode 的集群 id 不一致,集群找不到已往数据。如果集群在运行过程中报错,需要重新格式化 NameNode 的话,一定要先停止 namenode 和 datanode 进程,并且要删除所有机器的 data 和 logs 目录,然后再进行格化。
hdfs namenode -format
1在 hadoop102 上启动 HDFS
start-dfs.sh
1在 hadoop103 上启动 YARN
start-yarn.sh
1查看运行状态
jsp
1
# 报错解决办法
Hadoop 提示 ERROR: Attempting to operate on yarn resourcemanager as root 的解决方法
在 start-dfs.sh 和 stop-dfs.sh 文件的顶部添加以下参数:
HDFS_DATANODE_USER=root
HADOOP_SECURE_DN_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root
2
3
4
在 start-yarn.sh 和 stop-yarn.sh 文件的顶部添加以下参数:
YARN_RESOURCEMANAGER_USER=root
HADOOP_SECURE_DN_USER=yarn
YARN_NODEMANAGER_USER=root
2
3
# 集群奔溃处理办法
停止集群
stop-dfs.sh
1删除 data 和 logs 目录
注意:每台服务器上的 data 和 logs 目录都需要删除
rm -rf $HADOOP_HOME/data $HADOOP_HOME/logs
1格式化集群
hdfs namenode -format
1启动集群
start-dfs.sh
1
# 两个常用脚本
# 集群启停脚本
#在 /bin 目录下生成 xsync 文件并编辑
sudo vim /bin/myhadoop
2
参考配置:
#!/bin/bash
if [ $# -lt 1 ]; then
echo "No Args Input..."
exit
fi
case $1 in
"start")
echo "=============== 启动 hadoop 集群 ==============="
echo "--------------- 启动 hdfs ---------------"
ssh hadoop102 "$HADOOP_HOME/sbin/start-dfs.sh"
echo "--------------- 启动 yarn ---------------"
ssh hadoop103 "$HADOOP_HOME/sbin/start-yarn.sh"
echo "--------------- 启动 historyserver ---------------"
ssh hadoop102 "$HADOOP_HOME/bin/mapred --daemon start historyserver"
;;
"stop")
echo "=============== 停止 hadoop 集群 ==============="
echo "--------------- 停止 historyserver ---------------"
ssh hadoop102 "$HADOOP_HOME/bin/mapred --daemon stop historyserver"
echo "--------------- 停止 yarn ---------------"
ssh hadoop103 "$HADOOP_HOME/sbin/stop-yarn.sh"
echo "--------------- 停止 hdfs ---------------"
ssh hadoop102 "$HADOOP_HOME/sbin/stop-dfs.sh"
;;
*)
echo "Input Args Error..."
;;
esac
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#让 myhadoop 具有可执行权限
sudo chmod 777 /bin/myhadoop
2
# 查看 Java 进程脚本
#在 /bin 目录下生成 xsync 文件并编辑
sudo vim /bin/jpsall
2
参考配置:
#!/bin/bash
for host in hadoop102 hadoop103 hadoop104; do
echo "=============== $host ==============="
ssh $host jps
done
2
3
4
5
6
#让 jpsall 具有可执行权限
sudo chmod 777 /bin/jpsall
2