这些天入门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更好
虚拟机配置不用太高,同时开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会直接切成对方机器名:
完成到这一步,可以尝试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:
需要建立的文件夹有/data/hadoop_data/hdfs/namenode,/data/hadoop_data/hdfs/datanode, /data/hadoop_data/hadoop_tmp(放secondarynamenode的文件),但其实主机中没有设定datanode,从机中没有设定namenode,所以主机只需要创建两个文件夹,从机只需要一个文件夹。
这里我们可以尝试一下先用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。
执行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都无法开启,最后一一排查发现一个是权限问题,一个是路径错误,折磨了好几周。