完全分布式Hadoop集群搭建
学习了这么久hadoop,都没有搭过集群,是不合格的。这次搭建完,细扣具体的Job运行情况,日志信息,对Hadoop了解更深了。后面也要陆续搭建分布式flume,kafka,hbase,mysql来完成最终的离线批处理分析项目。
搭建步骤
- 虚拟机环境准备(IP地址、主机名、新用户、防火墙、SSH免密访问)
- 安装jdk
- 安装hadoop
- 配置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?
问题应该是有一个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用户的。没有找到在可以配置登录用户的文件,因此只能对三台虚拟机建立相同的用户,相关配置都得对应配置。
有两个地方需要重新配置,也就是~下的所有操作都得重新操作,其他路径的配置对所有用户都是一致的。
- 是SSH免密访问,需要把master新用户hadoop的公钥发给slave1和slave2的用户hadoop,两个从节点再把公钥加入authorized_keys,实现master免密登录。
- 环境变量都没了,需要重新配置~/.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或.的行记录过滤出来。