完全分布式Hadoop集群搭建

学习了这么久hadoop,都没有搭过集群,是不合格的。这次搭建完,细扣具体的Job运行情况,日志信息,对Hadoop了解更深了。后面也要陆续搭建分布式flume,kafka,hbase,mysql来完成最终的离线批处理分析项目。

搭建步骤

  1. 虚拟机环境准备(IP地址、主机名、新用户、防火墙、SSH免密访问)
  2. 安装jdk
  3. 安装hadoop
  4. 配置hadoop文件

虚拟机环境准备

用VMware配置三台Ubuntu 18.04虚拟机。配置如下:

  • 内存4GB
  • 处理器4
  • 硬盘20GB
VMware Tools

由于用的是VMware虚拟机软件,可以下载VMware Tools,这样可以之间拖拽传输文件。

修改IP地址

用的是NAT网络。很无语,一个简单的东西操作了一个下午。由于使用的是Ubuntu18.04,所以修改IP地址的文件与以往不同,配置文件目录在下面。本次是用的wire setting,可视化配置的,或许重启了IP地址就又变了。

sudo apt-get update
sudo apt install net-tools
才有ifconfig命令,查看IP地址

配置IP的文件在/etc/netplan/下。
需要增加IP地址,子网掩码,以及网关地址。
网关地址要和VMware虚拟化网络配置中的NAT网络的网关一致。

前面把VMware的虚拟化网络的DHCP关闭,配置了网关,也手动配置了本机下网络连接的VMware Network Adapter VMnet8,结果虚拟机就连接不上网络。很疑惑,网关地址配置成同一个的,本机IP地址另起一个,三个虚拟机IP地址各不相同,但就是连接不上。可能是对NAT网络理解不够的原因。

!!!感觉就是没配置错,都在同一个网段,配置了同一个网关地址,三个虚拟机通过网关连接本机来访问因特网。

解决方法就是继续开着虚拟化网络的DHCP,VMware Network Adapter VMnet8直接自动获取IP地址。
在保证虚拟机能连接网络的情况下,再将其IP地址修改成我们要的。

hadoop1 192.168.204.121
hadoop2 192.168.204.122
hadoop3 192.168.204.123
互相ping都没问题
修改主机名和映射

需要修改两个文件/etc/hosts和/etc/hostname

hostname分别改为master,slave1,slave2
在终端输入hostname可以看到修改后的主机名

在/etc/hosts文件下增加主机名和地址的映射
192.168.204.121 master
192.168.204.122 slave1
192.168.204.123 slave2

测试:
ping master
ping slave1
ping slave2
不连通说明配置失败
关闭防火墙

我查看状态发现一开始就是关闭的,应该默认就是禁闭。

//查看防火墙状态,
sudo ufw status
//激活防火墙
sudo ufw enable
//关闭防火墙
sudo ufw disable
创建新用户

!!!最后因为用户不一致,而不能启动集群,所以这一步是必要的,每个虚拟机的用户名需要一致。 同时需要注意的是下面的文件配置如果是hadoop1,hadoop2,hadoop3要修改为hadoop。

为三个虚拟机创建同样的用户名。

sudo useradd -m hadoop -s /bin/bash
sudo passwd hadoop
sudo adduser hadoop sudo

这一步太麻烦了,不断切换,电脑只有16G,承受不了。记得给用户hadoop关于目录hadoop的权限。

ssh免密登录

如果一开始没有安装ssh,会显示下面的错误。

ssh: connect to host localhost port 22: Connection refused

sudo apt-get install openssh-server
这次显示以下错误
E: Could not get lock /var/lib/dpkg/lock - open (11 Resource temporarily unavailable)
E: Unable to lock the administration directory (/var/lib/dpkg/) is another process using it?  

解决方法[https://askubuntu.com/questions/15433/unable-to-lock-the-administration-directory-var-lib-dpkg-is-another-process]

问题应该是有一个apt-get进程死锁了,需要杀死这个进程。
sudo lsof /var/lib/apt/lists/lock
sudo lsof /var/lib/apt/dpkg/lock
sudo kill -9 PID

杀死后就可以安装ssh,接着ssh localhost登录,产生~/.ssh目录。接着exit退出。

配置免密登录

cd ~/.ssh
ssh-keygen -t rsa//这步生成密钥
cat ./id_rsa.pub >> ./authorized_keys//加入授权

接下来要把公钥传输给别的节点,这样可以免密访问别的节点
scp,用于在linux进行远程拷贝文件
//传输给slave1
sudo scp /home/hadoop1/.ssh/id_rsa.pub hadoop2@slave1:/home/hadoop2/
//传输给slave2
sudo scp /home/hadoop1/.ssh/id_rsa.pub hadoop3@slave2:/home/hadoop3/

在slave1节点和slave2节点,将ssh公钥加入授权
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
这样master节点就可以无密码ssh到各个slave节点。

这里遇到一个问题,不能直接ssh slave和ssh slave2,只能ssh hadoop2@slave1和ssh hadoop3@slave2

因为ssh slave,系统会默认用本节点的用户名登录,即hadoop1来登录slave1主机。那自然是错误的,slave1下没有hadoop1用户,所以要确定 用户名@主机名。

不知道后面会不会遇到因为用户名不一致而引发的问题。所以最好使用同一个用户名hadoop。

安装jdk

在虚拟机环境配置完后,就要安装软件。必须安装jdk才能使用Hadoop。推荐使用jdk1.8版本。

加压jdk到/usr/lib/jvm

sudo vim ~/.bashrc
添加以下内容
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_162
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
source ~/.bashrc

这样就能查看java版本,确认是否安装成功
java -version

master安装好jdk后,将jdk1.8.0_162目录发送给两个slave节点

这里要注意的是,需要对jvm有写入权限,否则会报拒绝传输。
sudo chmod 777 /usr/lib/jvm

sudo scp -r /usr/lib/jvm/* hadoop2@slave1:/usr/lib/jvm
sudo scp -r /usr/lib/jvm/* hadoop3@slave2:/usr/lib/jvm

安装Hadoop

首先,在master节点,解压安装hadoop。

sudo tar -zxvf hadoop-2.7.1.tar.gz -C /usr/local/
//改名
sudo mv ./hadoop-2.7.1 ./hadoop

完全分布式Hadoop需要对5个文件进行修改。slaves、core-site.xml、hdfs.site.xml、mapred-site.xml、yarn-site.xml

slaves

文件slaves,内容是作为DataNode的主机名,每行一个。master节点可以即做datanode,也做namenode。

//本次就把slave1和slave2作为Datanode节点
slave1
slave2
core-site.xml

配置HDFS中NameNode的地址端口和Hadoop运行时产生文件的存储目录。

<configuration>
        <property>
                <name>fs.defaultFS</name>
                <value>hdfs://master:9000</value>
        </property>
        <property>
                <name>hadoop.tmp.dir</name>
                <value>file:/usr/local/hadoop/tmp</value>
                <description>Abase for other temporary directories.</description>
        </property>
</configuration>
hdfs-site.xml

配置辅助名称节点的地址端口(通常不和NameNode一个主机)、副本数量(这里两个slave)、名称节点产生文件的目录、数据节点产生文件的目录。

<configuration>
        <property>
                <name>dfs.namenode.secondary.http-address</name>
                <value>slave2:50090</value>
        </property>
        <property>
                <name>dfs.replication</name>
                <value>2</value>
        </property>
        <property>
                <name>dfs.namenode.name.dir</name>
                <value>file:/usr/local/hadoop/tmp/dfs/name</value>
        </property>
        <property>
                <name>dfs.datanode.data.dir</name>
                <value>file:/usr/local/hadoop/tmp/dfs/data</value>
        </property>
</configuration>
mapred-site.xml

配置指定MapReduce运行在Yarn上。

<configuration>
        <property>
                <name>mapreduce.framework.name</name>
                <value>yarn</value>
        </property>
</configuration>

在mapred.env.sh增加JAVA_HOME

yarn-site.xml

配置Yarn的ResourceManager运行主机名、yarn.nodemanager.aux_services配置成mapreduce_shuffle才能运行mapreduce程序。

<configuration>
        <property>
                <name>yarn.resourcemanager.hostname</name>
                <value>master</value>
        </property>
        <property>
                <name>yarn.nodemanager.aux-services</name>
                <value>mapreduce_shuffle</value>
        </property>
</configuration>

也可以在yarn-env.sh文件里增加JAVA_HOME

export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_162
scp传输给别的节点

将master下的/hadoop目录传输给另外两台节点slave1和slave2

首先将slave1和slave2的/usr/local权限改为可写入,再把master的/hadoop目录权限改为777
sudo chmod 777 目录

scp传输给slave1 slave2
sudo scp -r ./hadoop hadoop2@slave1:/usr/local/
sudo scp -r ./hadoop hadoop3@slave2:/usr/local/

环境变量配置

在所有节点都安装好hadoop后,需要配置各自的环境变量。

修改~/.bashrc,添加以下变量
export HADOOP_HOME=/usr/local/hadoop
export HADOOP_INSTALL=$HADOOP_HOME
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin
//最后使环境变量生效
source ~/.bashrc

启动集群

首次启动,需要在master节点执行NameNode格式化,格式化的目的是NameNode确定元数据存储的目录路径,需要清空目录。

//在master主机下
hdfs namenode -format
日志显示初始化了一些块信息等配置信息。

启动Hadoop

在master节点启动全部节点

./sbin/start-all.sh
//启动的是两个组件,一个是start-dfs.sh,一个是start-yarn.sh

需要注意的是,如果ResourceManager没配置在master上的话,是不能在master上启动的,得在相应的主机上执行start-yarn.sh

用户不一致的问题

start-all.sh出现问题,默认访问的是hadoop1@slave1和hadoop1@slave2,而我slave1,slave2是没有hadoop1用户的。没有找到在可以配置登录用户的文件,因此只能对三台虚拟机建立相同的用户,相关配置都得对应配置。

有两个地方需要重新配置,也就是~下的所有操作都得重新操作,其他路径的配置对所有用户都是一致的。

  1. 是SSH免密访问,需要把master新用户hadoop的公钥发给slave1和slave2的用户hadoop,两个从节点再把公钥加入authorized_keys,实现master免密登录。
  2. 环境变量都没了,需要重新配置~/.bashrc,所要配置的环境变量如下。
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_162
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export HADOOP_HOME=/usr/local/hadoop
export HADOOP_INSTALL=$HADOOP_HOME
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin:${JAVA_HOME}/bin

再次执行,发现有拒绝连接的问题,需要给hadoop用户 hadoop目录的权限

在三个节点都要操作
sudo chown -R hadoop /usr/local/hadoop
启动成功

启动顺序:

  • 执行start-dfs.sh
  • 启动master节点的namenode
  • 启动slave1节点的datanode
  • 启动slave1节点的datanode
  • 在slave2启动辅助名称节点secondary namenodes
  • 执行start-yarn.sh
  • 启动master节点的resourcemanager
  • 启动slave1节点的nodemanager
  • 启动slave2节点的nodemanager
//master jps
有NameNode和ResourceManager
//slave1 jps
有DataNode和NodeManager
//slave2 jps
有DataNode和NodeManager和SecondaryNameNode

测试集群

./bin/hdfs dfs -mkdir -p /user/hadoop
//建立的这个目录就是用户hadoop在hdfs系统的用户目录,可以根据不同的用户创建不同的用户目录/user/用户名
./bin/hdfs dfs -mkdir input
//自从创建input目录在user/hadoop下
./bin/hdfs dfs -put /usr/local/hadoop/etc/hadoop/*.xml input
//把所有的.xml文件发送给HDFS系统。

通过网页访问localhost:50070,可以查看到DataNode的信息。有9个块,因为有9个文件。

也可以通过网页访问master:8088,可以查看到应用情况,比如每一个Job的运行时间,Job ID等情况。

hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar grep input output 'dfs[a-z.]+'

执行完以上命令,我们就可以看到Hadoop集群跑起来。过后在HDFS会多一个目录output,里面的信息就是我们所过滤后的信息。用cat查看。即对于input目录里的文件,将含有dfs开头,后面字符是a到z或.的行记录过滤出来。

Hadoop集群具体运行情况,文件存储位置,日志信息等将记录在下一个博客[https://www.cnblogs.com/chenshaowei/p/12633898.html]。
posted @ 2020-04-04 13:56  Tanglement  阅读(150)  评论(0编辑  收藏  举报