1. 搭建环境准备工作
1. VMware虚拟机,下载地址:https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html
2. Centos7 系统,下载地址:http://mirrors.shu.edu.cn/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1708.iso
3. JDK8,下载地址:http://download.oracle.com/otn-pub/java/jdk/8u161-b12/2f38c3b165be4555a1fa6e98c45e0808/jdk-8u161-linux-x64.rpm?AuthParam=1520575824_7d45767eda6b3a96b3f824521e1e3f3b
4. Hadoop2.6,下载地址:http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-2.6.5/hadoop-2.6.5.tar.gz
2. Linux集群搭建与配置
1. 本次使用三台虚拟主机进行 Linux 集群的搭建,各主机命名:Master,Slave1,Slave2。
2. 在 /opt 目录下创建 hadoop-conponents 目录,用于存放 Hadoop 各组件及数据文件。
3. 更改 root 用户密码,并将各主机创建管理员用户:hadoop(注意:这里各节点的用户名最好相同,否则后续解决起来有点麻烦)
1.1 设置 Linux 主机名
Centos7 安装后,系统会自动将主机名设置为 localhost,为了辨别各主机所在节点,我们一般将主机名修改为对应节点名称,如:Master,Slave1,Slave2。
设置主机名需要 root 权限:
1. 使用 su 命令切换到 root 用户后进行操作:
首先,切换用户:su root
接下来,修改 root 用户密码:passwd root,回车后输入新密码。
然后,编辑文件:vi /etc/sysconfig/network,在文件中输入如下代码:
NETWORKING=yes
HOSTNAME=Master
保存并退出,然后在命令行界面输入:hostname Master,确认修改生效。
最后,修改静态主机名,编辑文件:vi /etc/hostname,在编辑器输入新主机名:Master,保存并退出。
重启终端后,输入:hostname,即可查看修改结果。
2. 管理员用户使用 sudo 命令获取 root 权限进行操作:
若没有管理员用户可以新建:
2.1 新建普通用户 hadoop:adduser hadoop
2.2 修改用户密码:passwd hadoop
2.3 为用户赋予 root 权限,编辑文件:vi /etc/sudoers,找到下面一行,并在 root 下添加一行,如下所示:
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
hadoop ALL=(ALL) ALL
修改完毕后保存退出,则该 hadoop 用户就为管理员用户了,可以使用 sudo 命令获取管理员权限。
补充:在编辑 /etc/sudoers 文件后,无法保存:
查看文件权限:ll /etc/sudoers 发现文件为只读文件(r 权限)
为文件添加写权限:chmod +w /etc/sudoers
再次编辑 /etc/sudoers 文件,然后保存退出。
创建完成后,在 hadoop 用户下编辑文件:sudo vi /etc/sysconfig/network,操作同上。
1.2 网络设置
默认情况下,网络是关闭的,无法通过IP地址连接主机,需要手动开启。
查看IP地址信息,打开终端窗口:输入 ifconfig 命令,或输入 ip addr 命令,发现 ens33 没有 inet 这个属性,即网卡未启动。
启动网卡,编辑文件:sudo vi /etc/sysconfig/network-scripts/ifcfg-ens33,找到代码 ONBOOT=no,并将这里的 no 改为 yes,保存退出。
重启网络服务:sudo service network restart
查看IP地址:命令行输入 ifconfig,ens33 网卡下的 inet 属性值即为IP地址。
查看各虚拟主机之间的连通性:ping IP地址,若有返回值,说明两台主机之间是连通的。
为了使用计算机名进行网络访问,需要配置主机名与IP地址的映射,编辑文件:sudo vi /etc/hosts,在文件内新增如下信息:
IP地址值 主机名
例:192.168.105.133 Master
192.168.105.134 Slave1
192.168.105.135 Slave2
保存退出(各主机都要配置)。
测试配置是否成功:ping Master,若有返回值,说明配置成功。
1.3 关闭防火墙
查看系统防火墙状态:systemctl status firewalld.service,发现系统的防火墙服务处于活动状态(active(running))。
关闭系统防火墙:sudo systemctl stop firewalld.service
继续查看防火墙状态:systemctl status firewalld.service,发现防火墙已经关闭(inactive(dead))。
关闭防火墙后,执行命令:systemctl disable firewalld.service,使下次启动计算机的时候取消防火墙服务。
1.4 安装JDK
1. 下载 Linux 版 JDK,本次选择 jdk-8u161-linux-x64.rpm。
2. 在 Linux 各节点用户目录下创建 software 文件夹,用于存放各安装包文件,并将 Linux 主节点上的 JDK 发送给其它分节点,在主节点终端窗口输入命令:scp /home/hadoop/software/jdk-8u161-linux-x64.rpm hadoop@Slave1:/home/hadoop/software
注意:若外部实体主机系统为 Windows,可以使用 XShell 工具将软件上传到 Linux 集群主节点;若外部实体主机系统为 Linux,则可以使用上述命令将软件复制到 Linux 集群节点。
3. 各节点安装 JDK :sudo rpm -ivh /home/hadoop/software/ jdk-8u161-linux-x64.rpm
4. 查看 JDK 安装位置:rpm -qal | grep java | more,一般安装在 /usr/java 目录下。
5. 配置环境变量:
方式一,配置用户变量:sudo vi /home/hadoop/.bash_profile,在文件末尾添加如下命令并保存:
export JAVA_HOME=/usr/java/jdk1.8.0_161/
export PATH=$JAVA_HOME/bin:$PATH
方式二,配置系统变量:sudo vi /etc/profile,在文件末尾添加如下命令并保存:
export JAVA_HOME=/usr/java/jdk1.8.0_161/
export PATH=$JAVA_HOME/bin:$PATH
6. 刷新配置,使修改生效:source /home/hadoop/.bash_profile 或 source /etc/profile
7. 验证配置是否成功:java -version,若输出 java 版本信息,则安装配置成功。
1.5 免密钥登录配置
大多数集群中的 Linux 计算机之间需要频繁的通信,但是 Linux 系统在相互通信中需要进行用户身份认证,也就是输入登陆密码。而免密钥登录是指两台 Linux 机器之间使用 SSH 连接时不需要用户名和密码。
注意:下面配置切换到 hadoop 用户下进行:
1. Master节点的配置
首先,在终端生成密钥,输入:ssh-keygen -t rsa,回车后,系统会出现一系列提示,这个时候只需回车即可。
ssh-keygen 是用来生成 private 和 public 密钥对的命令,将 public 密钥拷贝到远程机器后,就可以使 SSH 登录远程机器不用密码。
ssh-keygen 通过参数 -t 指定加密算法,这里是 rsa 。RSA 加密算法是一种典型的非对称加密算法,它基于大数的因式分解数学难题,是应用最广泛的非对称加密算法。
生成的密钥在用户根目录的 .ssh 目录下,查看目录内容:ll ~/.ssh
接下来,将公钥文件复制到 ./ssh 目录:cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys,复制文件是为了便于修改该文件权限;修改文件权限,限拥有用户读写:chmod 600 ~/.ssh/authorized_keys。
最后将 authorized_keys 文件复制到所有 Slave 节点的用户根目录,命令:scp ~/.ssh/authorized_keys Slave@Slave2:~/,回车后出现提示,输入 yes 确认连接,然后输入Slave2登录密码。
2. Slave节点的配置
首先,还是生成密钥:ssh-keygen -t rsa,一路回车即可。
接下来,将从 Master 节点复制过来的 authorized_keys 文件移动到 .ssh 目录下:mv ~/authorized_keys ~/.ssh/
最后,修改文件权限:chmod 600 ~/.ssh/authorized_keys
上述配置在所有 Slave 节点上执行,至此,免密钥登录配置完毕。
验证配置是否有效,在 Master 机器终端执行:ssh Slave2,登录 Slave2 计算机,如果登录成功并且无需输入密码,证明配置完成。(SSH 远程连接时,默认使用当前计算机用户名进行登录远程主机,若当前主机用户名和远程主机用户名不一致,需要使用:ssh 主机名@IP地址,进行连接)
退出远程节点回到本地计算机,输入命令:exit
2. Hadoop HDFS 安装与配置
注:由于每一个节点的安装和配置是相同的,所以我们在主节点下进行配置,然后复制到分节点,并且下面配置是在 hadoop 用户下进行。
2.1 解压 Hadoop 安装包
1. 将 Hadoop 安装包复制到 VMware 中 Master 主机的 software 目录下。
2. 进入 Master 主机的 software 目录,执行解压缩命令:tar -zxvf ~/software/hadoop-2.6.5.tar.gz,执行成功后,系统将在 software 目录下创建 hadoop-2.6.5 子目录,将解压得到的文件移动到 /opt/hadoop-components/ 目录:sudo mv ~/software/hadoop-2.6.5 /opt/hadoop-components/。
3. 由于下面要安装 Hadoop 组件,所以我们将基本安装文件重命名为 hadoop-base:sudo mv /opt/hadoop-components/hadoop-2.6.5 /opt/hadoop-components/hadoop-base,至此 Hadoop 安装完成。
4. 更改 hadoop-components 文件夹及子文件所属用户(改为hadoop用户):chown -R hadoop /opt/hadoop-components。注意:这里如果不更改目录所属用户,后续 hadoop 用户操作该目录文件的时候可能会失败:权限不足。
2.2 配置 Hadoop 运行环境
注:由于下面所有配置文件位置均位于 Hadoop 安装目录下的 ./etc/hadoop 子目录,所以我们先执行:cd /opt/hadoop-components/hadoop-base/etc/hadoop,以进入 hadoop 子目录进行文件的编辑配置工作。
1. 配置 Hadoop 环境变量
Hadoop 环境变量文件是 hadoop-env.sh,它位于 Hadoop 安装目录下的 ./etc/hadoop 子目录,我们只需配置该文件的 JDK 路径即可。
编辑 hadoop-env.sh 文件:vi hadoop-env.sh,在文件前面部分找到代码 “export JAVA_HOME=${JAVA_HOME}”,并将其修改为实际的 JDK 安装目录,即:“export JAVA_HOME=/usr/java/jdk1.8.0_161/”
修改完毕,保存退出即可。
2. 配置 Yarn 环境变量
Yarn 环境变量文件是 yarn-env.sh,也位于 Hadoop 安装目录下的 ./etc/hadoop 子目录,我们只需配置该文件的 JDK 路径即可。
编辑 yarn-env.sh 文件:vi yarn-env.sh,在文件前面部分找到代码 “# export JAVA_HOME=/home/y/libexec/jdk1.6.0/”,将其修改为实际 JDK 安装目录,即:“export JAVA_HOME=/usr/java/jdk1.8.0_161/”
3. 配置核心组件文件
Hadoop 的核心组件文件是 core-site.xml,位于 Hadoop 安装目录下的 ./etc/hadoop 子目录。
编辑 core-site.xml 文件,将下面配置代码放在文件的 和 之间。
fs.defaultFS
hdfs://Master:9000
hadoop.tmp.dir
/opt/hadoop-components/hadoop-data
4. 配置文件系统
Hadoop 的文件系统配置文件是 hdfs-site.xml,位于 Hadoop 安装目录的 ./etc/hadoop 子目录。
编辑 hdfs-site.xml 文件:vi hdfs-site.xml,将下面代码填充到文件的 和 之间。
dfs.replication
1
这里HDFS 数据块的副本数,系统的缺省值为 3,即默认副本数为 3 份,我们可以把副本数设置为 (0,3] 内的整数,其余数据无意义,因为 HDFS 数据副本数最大为:3,最小为:1。
5. 配置 yarn-site.xml文件
Yarn 的网页站点配置文件是 yarn-site.xml,位于 Hadoop 安装目录的 ./etc/hadoop 子目录。
编辑 yarn-site.xml 文件:vi yarn-site.xml,将下面代码填充到文件的 和 之间。
yarn.nodemanager.aux-services
mapreduce_shuffle
yarn.resourcemanager.address
Master:18040
yarn.resourcemanager.scheduler.address
Master:18030
yarn.resourcemanager.resource-tracker.address
Master:18025
yarn.resourcemanager.admin.address
Master:18141
yarn.resourcemanager.webapp.address
Master:18088
6. 配置 MapReduce计算框架文件
在 Hadoop 安装目录的 ./etc/hadoop 子目录下,有一个名为 mapred-site.xml.template 文件,将该文件复制并重命名,位置不变,命令:cp ./mapred-site.xml.template ./mapred-site.xml。
编辑 mapred-site.xml 文件,将下面代码填充到文件的 和 之间。
mapreduce.framework.name
yarn
7. 配置 Msater 节点的 Slaves 文件
在 Hadoop 的安装录下的 ./etc/hadoop 子目录,有一个slaves 文件,该文件给出了 Hadoop 集群的 Slave 节点列表,在启动 Hadoop 的时候,系统总是根据当前 slaves 文件中 Slave 节点名称列表启动集群,不在列表中的 Slave 节点便不会被视为计算节点。
根据自己所搭建集群的实际情况编辑 slaves 文件:vi slaves,由于本次安装了 Slave1 和 Slave2 节点,并且全部投入 Hadoop 集群运行,所以输入如下代码:
Slave1
Slave2
注:文件中原来有缺省的 localhost,应将其删除。
8. 复制 Master 上的 Hadoop 到 Slave 节点
通过复制 Master 节点上的 Hadoop,能够提高系统部署效率,由于本次只有 Slave1 和 Slave2 节点,所以复制两次,命令:scp -r /opt/hadoop-components/hadoop-base hadoop@Slave2:/opt/hadoop-components
需要注意的是,在复制之前,首先更改子节点的 /opt/hadoop-components 目录所属用户,否则上述复制会失败(权限不足):sudo chown -R hadoop /opt/hadoop-components
至此,Hadoop 集群的安装和配置完成。
2.3 Hadoop 集群的启动
注:首次启动 Hadoop 还需要做一些准备工作。
1. 配置操作系统环境变量
注:这里的配置需要在集群的所有计算机上运行,本次配置用户变量。
编辑 .bash_profile 文件:vi ~/.bash_profile,将下述代码追加到文件尾部:
# HADOOP
export HADOOP_HOME=/opt/hadoop-components/hadoop-base/
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
保存退出后,执行:source ~/.bash_profile 命令,使配置生效。
2. 创建 Hadoop 数据目录
注:本次操作在所有节点上进行
创建 Hadoop 数据目录:mkdir /opt/hadoop-components/hadoop-data
注意,这里的数据目录名 hadoop-data 与前面 Hadoop 核心组件文件 core-site.xml 中的配置相同。
3. 格式化文件系统
该操作只需要在 Master 节点上进行,命令:hdfs namenode -format。若没有出现 Exception/Error 信息,则表示格式化成功。
格式化失败可能原因及解决方法:
1). 无法连接到子节点,由于 Hadoop 默认以当前系统用户名登录远程主机,所以当主节点和子节点用户名不一致的时候会导致 SSH 连接失败,如:主节点用户为 Master,子节点用户为 Slave。
解决方法:更改 Hadoop 安装目录下的 ./etc/hadoop 子目录内的 slaves 文件配置,编辑文件:vi slaves,改为如下格式:用户名@主机名,即
Slave@Slave1
Slave@Slave2
2). 格式化文件系统报错:java.lang.IllegalArgumentException: URI has an authority component,这是因为 hdfs-site.xml 配置文件中 hadoop.tmp.dir 配置问题,解决办法:将所有节点的数据目录写为绝对地址,并且所有数据目录地址要相同。
hadoop.tmp.dir
/opt/hadoop-components/hadoop-data
4. 启动和关闭 Hadoop
完成上述配置,就可以启动 Hadoop 集群了,可以使用 start-all.sh 命令启动 Hadoop 集群,执行后系统会出现提示,输入:yes,之后系统即可启动。
要关闭 Hadoop 集群,可以使用 stop-all.sh 命令
但是,有必要指出,下次启动 Hadoop 时候,无需 NameNode 的初始化,只需要使用 start-dfs.sh 命令即可,然后用 start-yarn.sh 启动 yarn。
实际上,Hadoop 系统建议放弃使用 start-all.sh 和 stop-all,sh 一类的命令,而改用 start-dfs.sh 和 start-yarn.sh 命令。
5. 验证启动是否成功
用户可以在终端执行 jps 命令查看 Hadoop 是否启动成功。在 Master 节点,执行 jps 后如果是如下四个进程,则主节点(Master)启动成功。
SecondaryNameNode、ResourceManager、Jps、NameNode
在子节点(Slave)执行 Jps 命令,如果打印如下三个进程,则子节点(Slave)启动成功。
NodeManager、Jps、DataNode
在 Hadoop 集群的运维中,系统管理人员还常常使用 Web 界面监视系统状况。例如,当集群启动后,在浏览器地址栏中输入:http://Master:18088,可以检查 Yarn 的运行情况。同样,在浏览器地址栏输入 http://Master:50070,可以看到 Hadoop 的一些基本信息及日志等。
启动失败原因及解决方法:
1). 格式化文件系统失败,无法创建目录:java.io.IOException:Cannot create directory 目录名:
由于格式化文件系统的时候,当前用户会向 Hadoop 数据目录 hadoop-data 内写入数据,所以查看 hadoop-data 目录权限:ll /opt/hadoop-components/hadoop-data,发现 hadoop-data 属于 root 用户,当前用户没有写权限。
解决办法:为当前用户增加向 hadoop-data 写数据的权限
方式一:更改文件为所有用户可写:sudo chmod 777 /opt/hadoop-components/hadoop-data。
方式二:更改文件所属用户,让其属于当前用户,推荐方式:sudo chown -R hadoop /opt/hadoop-components/hadoop-data/
2). NameNode 或 DataNode 启动失败:
当 Hadoop 重新启动的时候,由于我没有在 hdfs-site.xml 中配置下面内容:
dfs.namenode.name.dir
file:/opt/hadoop-components/hadoop-tmp/namenode
dfs.datanode.data.dir
file:/opt/hadoop-components/hadoop-tmp/datanode
导致 Hadoop 系统重新启动后会默认读取 Linux 根目录下的 /tmp/ 下的文件。如果 Linux 系统没有重启,这个目录内的内容不会被系统清理掉,保存了 namenode 和 datanode 相关信息。
这样下次启动hadoop时(不论是重新格式化hdfs文件系统,还是其他操作),Hadoop 还是会读取默认位置,也就是 /tmp/ 下的文件作为 namenode、datanode 的配置信息。而重新格式化之后,namenode 会重新生成,但保存在 /tmp/ 中的 datanode 配置信息,不会重新生成。两个 cluster-ID 冲突,导致启动 datanode 或 namenode 失败。
解决办法:
方式一:
首先,手动清空 /tmp/ 目录内的 namenode、datanode 配置信息,方式:sudo rm -r /tmp/*,该方式可以清空 /tmp 文件夹(所有节点都要清除一遍)。
接下来,清空 hadoop-data 目录内数据,以清除格式化文件:rm -r /opt/hadoop-components/hadoop-data/*,因为只有在集群第一次启动的时候才需要格式化 namenode,也就是说一般这个时候 hadoop-data 内还没有数据文件,有的只是一些格式化信息,所以可以放心清除,并且所有节点都要清除。
最后,重新格式化文件系统,再次启动 Hadoop。
方式二:
首先,在 hdfs-site.xml 文件中,显示确定 namenode 和 datanode 配置文件位置,如配置到 hadoop-base 同级目录的 hadoop-tmp 目录(由于目录是新建的,所以相当于上述的清空 /tmp 文件夹,若起初配置好了,则上述清除 /tmp 文件夹改为清除本目录内数据)。
接下来,同上面一样,清空 hadoop-data 文件夹。
最后,重新格式化文件系统,再次启动 Hadoop。
补充:DataNode 启动失败还有一种可能,就是当 Hadoop 启动的时候,会向子节点 hadoop-data 目录内写入格式化信息,如果子节点的 hadoop-data 目录没有用户写权限,则会导致文件夹创建失败,进而无法启动 DataNode,具体情况可以查看日志文件。
3). SecondaryNameNode 启动失败:
查看主节点 Hadoop 安装目录下的 /logs 子目录内的 *-secondarynamenode-*.log:vim /opt/hadoop-components/hadoop-base/logs/*-secondarynamenode-*.log。问题:端口被占用,java.net.BIndException:Port in use:0.0.0.0:50090
解决方案:结束占用端口进程
首先,查看占用该端口的进程:netstart -apn | grep 50090,得到进程的 PID。
接下来,根据进程 PID 杀死进程:kill -9 PID。
5. 补充
1). 安装 vim 编辑器:sudo yum -y install vim
2). 查看端口占用:lsof -i:端口号;或 netstat -apn | grep 端口号;
3). 关闭端口对应的应用程序:kill -9 PID(进程号)
4). 查看在终端输入的所有历史命令:history | more 或直接编辑保存历史命令的文件,默认保存1000条:vim ~/.bash_history
5). 查看最近 n 条命令,终端输入:history n
6). IP 地址 0.0.0.0:表示本机所有的 IP 地址,如果监听本机的 0.0.0.0 上的端口,则等于监听本机器上的所有 IP 对应的该端口。
7). vim 跳转到文件最后一行:执行 vim 命令进入文本后,直接按 G,即可直达文件最后一行;按 gg,光标定位到文件第一行,然后按 i 进入编辑模式。
8). 当 Hadoop 集群搭建好以后,首先要查看与 Hadoop 平台相关目录对当前用户的读写权限,如果对当前用户没有读写权限,后续会出现一系列问题,所以首先要为当前用户赋予读写权限。
9). 删除用户及其家目录:sudo userdel -r 用户名