Centos6.8+Hadoop3.2+jdk1.8分布式集群安装全过程(真实)

这些天入门hadoop,结果视频里连装hadoop分布式集群都没提,直接开始讲概念,我琢磨了几周还是搞定了,小问题太多,资料又比较乱,各个博客讲的都不一样,还得汇总去搞,出了问题解决方法也千奇百怪,所以这里把我成功的经历记录下,希望对新搞的人有所帮助

参考博客:
https://blog.csdn.net/xiaoxsen/article/details/80462271
https://www.shangmayuan.com/a/28f8b1571406445aabd579d6.html

虚拟机装系统这部分网上资料很多,不细说了可以参考https://blog.csdn.net/wu_zeqin/article/details/79833046
安装一个主机,复制三个从机,打开共享文件夹,能装vmtool更好

Centos6.8+Hadoop3.2+jdk1.8分布式集群安装全过程(真实)
Centos6.8+Hadoop3.2+jdk1.8分布式集群安装全过程(真实)
虚拟机配置不用太高,同时开4个虚拟机容易崩溃,尽量少用vmtool复制大文件,也容易崩溃,复制一些命令就行,没装vmtool的话就用远程连接软件操作,切换机器比较快,重复命令也可以复制。

一、设置新用户、安装jdk以及hadoop

进入centos系统时使用root账户,然后通过

gourpadd hduser
useradd hduser -g hduser
这里可以同时设置hduser的密码
passwd hduser
然后输入密码两次

添加一个专门使用hadoop的用户和其所属的用户组,添加这个用户的作用是便于集群互相调用的安全(我编的 ),而且后面ssh免密登录的配置中关闭了root用户的连接权限,所以只能用其他用户进行连接。

jdk下载和hadoop就在官网下,也有很多镜像链接,下来之后放Vmvare的共享文件夹里供虚拟机使用。
首先安装jdk,其实也就是解压到一个你记得住的路径,修改环境变量,让系统找得到这个jdk的bin路径就行,即:

JAVA_HOME=~/jdk1.8
PATH=$PATH:$JAVA_HOME/bin
export JAVA_HOME
export PATH

然后hadoop同样也是解压,这时,需要先用root权限修改hadoop文件的拥有者为新用户hduser,即:

chown hduser:hduser hadoop-3.2
mv hadoop-3.2 /usr/local/hadoop

这样ssh连接进来再使用hadoop时就没有权限不足的问题了,比一个个文件改成777更省事吧。
修改环境变量和jdk就不同了,因为仅有hduser使用hadoop文件,这次修改变量就只写在hduser用户的/home/hduser/.basrc下,即:

su - hduser
vim .basrc
#变量信息
export JAVA_HOME=/home/hduser/jdk1.8
export HADOOP_HOME=/usr/local/hadoop 
export PATH=$PATH:$HADOOP_HOME/bin 
export PATH=$PATH:$HADOOP_HOME/sbin 
export PATH=$PATH:$HADOOP_HOME/etc/hadoop
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_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 HADOOP_OPTS="-Djava.library.path=$HADOOP_HOME/lib" 
export JAVA_LIBRARY_PATH=$HADOOP_HOME/lib/native:$JAVA_LIBRARY_PATH

其实基本就是jdk的路径和hadoop的路径,省得以后调用hadoop的命令还要跑回安装路径下执行。

到此,jdk和hadoop安装部分完成,但更为重要的是环境配置操作,也是最容易出错的一部分,我们将在第三部分详细介绍。

二、ssh免密

集群之间的互相连接这里借助的是ssh连接,总不能每次连接输入密码吧,所以要通过密钥共享搭建免密连接。
首先设置hostname,也就是本机名称:

vim /etc/sysconfig/network
主机修改为hostname=hadoopm
从机修改为haotname=hadoop01    hadoop02    hadoop03

然后重启生效,接着修改每一个机器的host:

vim /etc/hosts
写入主机从机的对应ip
192.1.2.3   hadoopm
192.1.2.4   hadoop01
192.1.2.5   hadoop02
192.1.2.6   hadoop03

ip地址可以用ifconfig看,也可以在系统网络连接上面右键看information。
最后关闭防火墙,service iptables stop暂时关闭,重启恢复。chkconfig iptables off永久关闭,服务器不建议,但虚拟机可以用,比较方便。
最后关闭SELINUX

vim /etc/sysconfig/selinux
SELINUX=disabled

ssh连接是在hduser用户下的,所以要su - hduser后设定密钥并发送:

ssh-keygen -t rsa
回车回车回车
如果之前生成过会问是否覆盖(y/n)这里回车没有用,要输入y

cd ~/.ssh
cat id_rsa.pub >> authorized_keys   

到这一步应该可以自己ssh自己了,可以ssh自己的host名来试试

主机操作:
ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop01
ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop02
ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop03
从机01操作:
ssh-copy-id -i ~/.ssh/id_rsa.pub hadoopm
ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop02
ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop03

从机依次设置好即可,如果ssh免密连接成功的话,hostname会直接切成对方机器名:
Centos6.8+Hadoop3.2+jdk1.8分布式集群安装全过程(真实)

完成到这一步,可以尝试ssh各个机子,会出现各种各样的问题,我就只解释下我遇到的几个棘手问题:
1、ssh直接permission denied,这个基本是密钥的权限问题

chmod 700 /home/hduser/.ssh
chmod 600 authorized_keys

修改完一个机器即可尝试用其他机器ssh它,如果弹出输入密码就基本成功

2、出现Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password),这就需要修改每个机器的ssh配置文件,参考https://phoenixnap.com/kb/ssh-permission-denied-publickey:

进入root权限
su root
输入密码
vim /etc/ssh/sshd_config
更改
PermitRootLogin no
PubkeyAuthentication yes
GSSAPIAuthentication yes 
GSSAPICleanupCredentials no
UsePAM yes
systemctl restart sshd或者service sshd restart  

修改完成后重新分发密钥,再试试ssh能否免密

ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop01

三、修改配置文件

主机和从机的区分就是依靠配置文件,所以主机和从机的配置文件变量不同,这些配置文件在hadoop安装路径下的/etc/hadoop里

主机:
hadoop-env.sh

/**/
export JAVA_HOME=/home/hduser/jdk1.8
/**/

core-site.xml

/**/
<configuration>
    <property>
        <name>fs.default.name</name>
        <value>hdfs://hadoopm:9000</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/data/hadoop_data/hadoop_tmp</value>
    </property>
</configuration>
/**/

hdfs-site.xml

/**/
<configuration>
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:/data/hadoop_data/hdfs/namenode</value>        #建立真实的路径用来存放名称节点
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:/data/hadoop_data/hdfs/datanode</value>        #建立真实的路径用了存放数据
    </property>
</configuration>
/**/

mapred-site.xml

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

yarn-site.xml

/**/
<configuration>
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>hadoopm</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
        <value>org.apache.hadoop.mapred.ShuffleHandler</value>
    </property>
    <property>
        <name>yarn.resourcemanager.address</name>
        <value>hadoopm:8050</value>
    </property>
    <property>
        <name>yarn.resourcemanager.scheduler.address</name>
        <value>hadoopm:8030</value>
    </property>
    <property>
        <name>yarn.resourcemanager.resource-tracker.address</name>
        <value>hadoopm:8025</value>
    </property>
    #使用hadoop yarn运行pyspark时,不添加下面两个参数会报错
    <property>
        <name>yarn.nodemanager.pmem-check-enabled</name>
        <value>false</value>
    </property>
    <property>
        <name>yarn.nodemanager.vmem-check-enabled</name>
        <value>false</value>
    </property>
</configuration>
/**/

worker

hadoop01
hadoop02
hadoop03

slaves


hadoop01
hadoop02
hadoop03

从机:
hadoop-env.sh

/**/
export JAVA_HOME=/home/hduser/jdk1.8
/**/

core-site.xml

/**/
<configuration>
    <property>
        <name>fs.default.name</name>
        <value>hdfs://hadoopm:9000</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/data/hadoop_data/hadoop_tmp</value>
    </property>
</configuration>
/**/

hdfs-site.xml

/**/
<configuration>
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:/home/data/hadoop_data/hdfs/datanode</value>
    </property>
</configuration>
/**/

mapred-site.xml

/**/
<configuration>
    <property>
        <name>mapred.job.tracker</name>
        <value>hadoopm:54311</value>
    </property>
</configuration>
/**/

yarn-site.xml

/**/
<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
        <value>org.apache.hadoop.mapred.ShuffleHandler</value>
    </property>
    <property>
        <name>yarn.resourcemanager.address</name>
        <value>hadoopm:8050</value>
    </property>
    <property>
        <name>yarn.resourcemanager.scheduler.address</name>
        <value>hadoopm:8030</value>
    </property>
    <property>
        <name>yarn.resourcemanager.resource-tracker.address</name>
        <value>hadoopm:8025</value>
    </property>
    #使用hadoop yarn运行pyspark时,不添加下面两个参数会报错
    <property>
        <name>yarn.nodemanager.pmem-check-enabled</name>
        <value>false</value>
    </property>
    <property>
        <name>yarn.nodemanager.vmem-check-enabled</name>
        <value>false</value>
    </property>
</configuration>
/**/

然后所有机器执行vim log4j.properties添加以下行

log4j.logger.org.apache.hadoop.util.NativeCodeLoader=ERROR

到这里搞定了一个主机和一个从机的配置文件,剩下的两个从机可以通过第一个从机复制配置文件

rsync -av 你的hadoop路径/etc   hadoop02:你的hadoop路径/

即将etc文件夹复制到2号从机上去,也可以用此方法直接传整个hadoop,注意要在hduser用户下执行,root无法连接ssh,但hduser的权限较少,导致传输权限不足,尽量传输owner为hduser的文件。

四、启动及相关错误

按照上述的配置文件修改完毕后,我们需要创建一个文件夹作为namenode,路径在配置文件hdfs_site.xml中的:/data/hadoop_data/hdfs/namenode,hadoop不会自动帮我们生成这个文件夹,所以我们要自己建,注意要用hduser用户建立,否则启动集群后没办法在这里创建文件、写入文件。如果已经用root用户创建,也可以直接在文件夹属性里修改owner:
Centos6.8+Hadoop3.2+jdk1.8分布式集群安装全过程(真实)

需要建立的文件夹有/data/hadoop_data/hdfs/namenode,/data/hadoop_data/hdfs/datanode, /data/hadoop_data/hadoop_tmp(放secondarynamenode的文件),但其实主机中没有设定datanode,从机中没有设定namenode,所以主机只需要创建两个文件夹,从机只需要一个文件夹。
Centos6.8+Hadoop3.2+jdk1.8分布式集群安装全过程(真实)

Centos6.8+Hadoop3.2+jdk1.8分布式集群安装全过程(真实)

这里我们可以尝试一下先用root权限建立这个目录,直接进路径新建文件夹即可,不用命令行了,然后我们cd到/data/hadoop_data/hdfs/namenode这个路径,执行hadoop namenode -format进行格式化,这个时候如果弹出找不到hadoop命令,则需要source ~/.basrc。
如果出现hadoopm: ssh: connect to host hadoopm port 2112: Connection refused,我们想把端口号改成常用的22口,但配置文件在哪呢,就可以在hadoop/etc/hadoop/用find . | xargs grep '2112’来查询,查到在/etc/hadoop/hadoop-env.sh中可以修改ssh的port号,vim进去/2112定位,改成22。
Centos6.8+Hadoop3.2+jdk1.8分布式集群安装全过程(真实)

执行hadoop namenode -format后我们在输出的结果中可以看到这一句:

2021-10-08 21:00:38,053 WARN namenode.NameNode: Encountered exception during format: 
java.io.IOException: Cannot create directory /data/hadoop_data/hdfs/namenode/current
	at org.apache.hadoop.hdfs.server.common.Storage$StorageDirectory.clearDirectory(Storage.java:447)

无法创建current文件夹,这里就应该能想到是权限的问题了,更改权限后重来:

2021-10-08 21:05:54,356 INFO namenode.FSImage: Allocated new BlockPoolId: BP-1995783002-192.168.52.142-1633698354342
2021-10-08 21:05:54,371 INFO common.Storage: Storage directory /data/hadoop_data/hdfs/namenode has been successfully formatted.
2021-10-08 21:05:54,446 INFO namenode.FSImageFormatProtobuf: Saving image file /data/hadoop_data/hdfs/namenode/current/fsimage.ckpt_0000000000000000000 using no compression
2021-10-08 21:05:54,924 INFO namenode.FSImageFormatProtobuf: Image file /data/hadoop_data/hdfs/namenode/current/fsimage.ckpt_0000000000000000000 of size 398 bytes saved in 0 seconds .
2021-10-08 21:05:54,948 INFO namenode.NNStorageRetentionManager: Going to retain 1 images with txid >= 0
2021-10-08 21:05:54,952 INFO namenode.FSImage: FSImageSaver clean checkpoint: txid=0 when meet shutdown.
2021-10-08 21:05:54,952 INFO namenode.NameNode: SHUTDOWN_MSG: 
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at hadoopm/192.168.52.142
************************************************************/

这样namenode格式化就完成了,就可以启动集群服务了,在主机上执行start-all.sh即可开启全部服务,

[hduser@hadoopm namenode]$ start-all.sh
WARNING: Attempting to start all Apache Hadoop daemons as hduser in 10 seconds.
WARNING: This is not a recommended production deployment configuration.
WARNING: Use CTRL-C to abort.
Starting namenodes on [hadoopm]
Starting datanodes
Starting secondary namenodes [hadoopm]
Starting resourcemanager
Starting nodemanagers

[hduser@hadoopm namenode]$ jps
42034 SecondaryNameNode
42567 Jps
42250 ResourceManager
41802 NameNode

切到从机输入jps发现只有nodemanager,没有datanode,这是因为我的hadoop格式化了两次,主机集群ID有两个,旧的被覆盖了,而从机保留的是旧的ID,二者不对应,无法开启datanode

[hduser@hadoop03 ~]$ jps
9686 Jps
9578 NodeManager

可以通过找到主机namenode路径下的current文件夹里的version文件复制出CID,然后粘贴到从机datanode文件夹的current下的version中强制同步就ok了。经尝试,直接把从机的datanode清空,然后重新执行start-all.sh也可以。
最终从机输入jps,出现了datanode:

[hduser@hadoop03 ~]$ jps
10322 DataNode
10552 Jps
10444 NodeManager

搭建成功。
其实总体搭建不算困难,只是较为繁琐,各种文件夹路径主机名太多,一步出错就会导致无法开启,不过除了在命令行中观察外,在hadoop开启之后,也可以在logs文件夹下面查看日志寻找错误,一开始我连datanode和namenode都无法开启,最后一一排查发现一个是权限问题,一个是路径错误,折磨了好几周。

上一篇:hadoop3.3.1简单的两节点集群


下一篇:ZKFailoverController的作用