软件 | 版本 | 下载地址 |
---|---|---|
centos | 8.0.1905 | http://mirrors.aliyun.com/centos/8.0.1905/isos/x86_64/CentOS-8-x86_64-1905-dvd1.iso |
java | openjdk1.8.0-230 | yum install -y java-1.8.0-openjdk.x86_64 java-1.8.0-openjdk-devel.x86_64 |
hadoop | hadoop-2.7.7 | http://mirror.bit.edu.cn/apache/hadoop/common/hadoop-2.7.7/hadoop-2.7.7.tar.gz |
spark | spark-2.4.3-bin-hadoop2.7 | https://www.apache.org/dyn/closer.lua/spark/spark-2.4.3/spark-2.4.3-bin-hadoop2.7.tgz |
scala | scala-2.12.5 | http://www.scala-lang.org/download/ |
Anaconda | Anaconda3-2019.03-Linux-x86_64.sh | https://www.anaconda.com/distribution/ |
所有的节点均创建一个名为hadoop
的用户,并添加管理员权限。
注意:这里这是单纯为了方便管理,创建的用户名,也可以使用其他用户名,或者使用系统之前的用户,主要有管理员权限即可
$ sudo useradd -m hadoop -s /bin/bash #创建用户
$ sudo passwd hadoop #修改密码 had@oop5856
$ sudo adduser hadoop sudo #添加管理员权限
为hadoop增加管理员权限(即拥有和root一样的权限),执行指令:visudo
找到root ALL= (ALL) ALL这一行(一般在99行附近),然后在这一行下面增加下面指令:
hadoop ALL= (ALL) ALL
添加之后,保存退出。然后通过指令:su hadoop,切换到hadoop用户
修改 /etc/hostname
文件,每个节点都要修改。
注意:如果是桌面版直接修改/etc/hostname文件即可,服务器版还需要修改/etc/cloud/cloud.cfg文件,修改如下:
# This will cause the set+update hostname module to not operate (if true)
preserve_hostname: true #这里是将false改成true
在/etc/hosts
文件里添加如下内容(每个节点都要修改,根据实际情况修改ip)
192.168.233.200 Master
192.168.233.201 Slave01
192.168.233.202 Slave02
检查各个节点是否能相互ping通。
让Master能够通过SSH无密码登录各个Slave节点
如果修改过主机名,需要重新生成的新的公钥。
在Master上执行如下命令:
$ cd ~/.ssh # 如果没有该目录,先执行一次ssh localhost
$ rm ./id_rsa* # 删除之前生成的公匙(如果已经存在)
$ ssh-keygen -t rsa # 执行该命令后,遇到提示信息,一直按回车就可以
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
接着将Master中的id_rsa.pub文件复制到各个Slave节点中
$ scp ~/.ssh/id_rsa.pub hadoop@Slave01:/home/hadoop/
$ scp ~/.ssh/id_rsa.pub hadoop@Slave02:/home/hadoop/
在各个Slave节点中执行如下命令:
$ mkdir ~/.ssh # 如果不存在该文件夹需先创建
$ cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
$ rm ~/id_rsa.pub # 用完以后就可以删掉
在Master中验证是否可以无密码登录,各个Slave节点。
如:
$ ssh Slave01 #如果成功登录,则配置完成
$ ssh Slave02 #如果成功登录,则配置完成
3、解压包,给目录授权
3.1安装Hadoop。
上传Hadoop安装包到/usr/local/目录下,然后解压缩,重命名,配置环境变量
tar zxvf hadoop-2.7.7.tar.gz
mv hadoop-2.7.7 hadoop
chown -R hadoop:hadoop ./hadoop
3.2配置文件
export HADOOP_HOME=/usr/local/hadoop
#export HADOOP_OPTS="-Djava.library.path=$HADOOP_PREFIX/lib:$HADOOP_PREFIX/lib/native"
export LD_LIBRARY_PATH=$HADOOP_HOME/lib/native
export HADOOP_COMMON_LIB_NATIVE_DIR=/usr/local/hadoop/lib/native
export HADOOP_OPTS="-Djava.library.path=/usr/local/hadoop/lib"
#export HADOOP_ROOT_LOGGER=DEBUG,console
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/sbin:$HADOOP_HOME/bin
3.3修改hadoop的5个配置文件。非常重要。。。
现在先看一下hadooped目录。我们可以看到,hadoop下一共有7个目录,bin和sbin是可执行文件的目录,etc是放配置文件的目录,include、lib和libexec均是放一些类库的,share是放一些共享类库和jar包的。
首先,进入cd /usr/local/hadoop/etc/hadoop目录,这5个配置文件均在此目录中。
第一个:hadoop-env.sh
[root@hadoop hadoop]# vi hadoop-env.sh #添加如下一行变量
#hadoop-3.1.0是第54行,hadoop-2.7.7是第25行
#可以使用 :set number来显示行数
export JAVA_HOME=/usr/lib/jvm/java
第二个:core-site.xml(HADOOP-HDFS系统内核文件)
[root@hadoop hadoop]# vi core-site.xml #添加如下几行
<configuration>
<!--指定HADOOP所使用的文件系统schema(URI),HDFS的老大(NameNode)的地址-->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop:9000</value>
</property>
<!--指定HADOOP运行时产生文件的存储目录-->
<property>
<name>hadoop.tmp.dir</name>
<value>/var/hadoop/tmp</value>
</property>
</configuration>
注意:在hadoop安装目录的文档中有所有配置文件的默认参数表,用户可以查看后,根据实际情况进行修改。
比如:在D:/hadoop-3.1.0/share/doc/hadoop/hadoop-project-dist/hadoop-common/core-default.html文档中可以看到:
hadoop.tmp.dir的默认值是/tmp/hadoop-${user.name}。/tmp/是Linux系统的临时目录,如果我们不重新指定的话,默认Hadoop工作目录在Linux的临时目录,一旦Linux系统重启,所有文件将会清空,包括元数据等信息都丢失了,需要重新进行格式化,非常麻烦。
第三个:hdfs-site.xml
[root@hadoop hadoop]# vi hdfs-site.xml #添加如下几行
<configuration>
<!--指定HDFS副本的数量-->
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<!--设置默认端口,这段是我后来加的,如果不加上会导致启动hadoop-3.1.0后无法访问50070端口查看HDFS管理界面,hadoop-2.7.7可以不加-->
<property>
<name>dfs.http.address</name>
<value>192.168.42.134:50070</value>
</property>
</configuration>
在D:\hadoop-3.1.0\share\doc\hadoop\hadoop-project-dist\hadoop-hdfs\hdfs-default.xml文档中可以看到:
dfs.replication的默认值是3,由于HDFS的副本数不能大于DataNode数,而我们此时安装的hadoop中只有一个DataNode,所以将dfs.replication值改为1。
dfs.namenode.http-address在hadoop-3.1.0版本上的默认值是 0.0.0.0:9870 ,在hadoop-2.7.7版本上的默认值是0.0.0.0:50070,所以不同版本可以通过不同端口访问NameNode。
第四个:mapred-site.xml
[root@hadoop hadoop]# mv mapred-site.xml.templete mapred-site.xml #重命名,hadoop-3.1.0系统中就是mapred-site.xml不需要改名,hadoop-2.7.7需要改名
[root@hadoop hadoop]# vi mapred-site.xml #添加如下几行,指定hadoop运行在哪种计算框架上,这里指定yarn框架。
<!--指定mr运行在yarn上-->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
第五个:yarn-site.xml
[root@hadoop hadoop]# vi yarn-site.xml #添加如下几行
<configuration>
<!-- 指定YARN的老大(ResourceManager)的地址-->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop</value>
</property>
<!-- 指定reducer获取数据的方式-->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
其实还有第6个文件slaves,内容为localhost,不需要修改。slaves这个文件指定DataNode在哪台机器上。这个文件在hadoop-2.7.7中存在,但是在hadoop-3.1.0里没有这个文件,我怀疑是该文件改名为workers了。当搭建分布式hadoop集群时,需要修改这个文件,配置DataNode在哪台机器上。
旧版本中貌似有个masters文件用来配置SecondaryNameNode在哪台机器上(最好不要跟NameNode放在同一台机器上),但是我在新版本目录中没找到这个文件,不知道新版本如何配置SecondaryNameNode?
3.解决互信问题。
主要是目的是当hadoop集群有多台机器时,我们可以在任意一台机器上输入start-all.sh命令启动集群中的所有节点,方便快捷。如果不配置免密码登录的话,那么我们需要一台一台机器输入密码登录后分别启动各个节点,非常麻烦。
方式一:配置ssh,生成密钥,使ssh可以免密码连接localhost
[root@hadoop rpms_yum]# cd /root
[root@hadoop ~]# ssh-keygen -t rsa #生成ssh密钥对
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): #直接回车
Enter passphrase (empty for no passphrase): #直接回车
Enter same passphrase again: #直接回车
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:9NevFFklAS5HaUGJtVrfAlbYk82bStTwPvHIWY7as38 root@hadoop
The key's randomart image is:
+---[RSA 2048]----+
| +*O*=.|
| .o=+=o+|
| . ..O +=|
| . . * *.%o|
| S o o %o+|
| . + +.|
| . + .|
| . +E|
| o.o|
+----[SHA256]-----+
[root@hadoop ~]# cd .ssh/
[root@hadoop .ssh]# ls #id_rsa为私钥,id_rsa.pub为公钥
id_rsa id_rsa.pub known_hosts
[root@hadoop .ssh]# cp id_rsa.pub authorized_keys #使主机之间可以免密码登录
[root@hadoop .ssh]# ssh xysokohost date #查看(不需要输入密码,直接输出结果,说明免密成功)
Mon Jul 16 05:02:27 EDT 2018
方式二:采用sshUserSetup.sh脚本去解决互信问题(sshUserSetup.sh是Oracle自带的一个快速配置互信的脚本程序,我们可以拿来借用一下)
将sshUserSetup.sh上传到/root目录,执行命令搭建本机互信(因为本机有2个节点,NameNode和DataNode)
[root@hadoop ~]# cd /root/
[root@hadoop ~]# ls
anaconda-ks.cfg sshUserSetup.sh
[root@hadoop ~]# sh sshUserSetup.sh -user root -hosts "hadoop" -advanced -noPromptPassphrase
#这个文件我是从网上找的,执行命令后总是报错:syntax error near unexpected token `else'
注意:如果格式化NameNode之后运行过hadoop,然后又想再格式化一次NameNode,那么需要先删除第一次运行Hadoop后产生的VERSION文件,否则会出错,详情见第四部分问题4。
[root@hadoop ~]# hdfs namenode -format #中间没有报错并且最后显示如下信息表示格式化成功
...
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at hadoop/192.168.42.134
************************************************************/
格式化完成后,系统会在dfs.data.dir目录下生成元数据信息。
[root@hadoop hadoop]# start-all.sh
Starting namenodes on [hadoop]
Last login: Mon Jul 16 05:02:39 EDT 2018 from hadoop on pts/1
Last failed login: Mon Jul 16 05:51:35 EDT 2018 from 192.168.42.131 on ssh:notty
There was 1 failed login attempt since the last successful login.
Starting datanodes
Last login: Mon Jul 16 05:57:58 EDT 2018 on pts/1
localhost: Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
Starting secondary namenodes [hadoop]
Last login: Mon Jul 16 05:58:01 EDT 2018 on pts/1
2018-07-16 05:58:41,527 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Starting resourcemanager
Last login: Mon Jul 16 05:58:20 EDT 2018 on pts/1
Starting nodemanagers
Last login: Mon Jul 16 05:58:44 EDT 2018 on pts/1
[root@hadoop hadoop]# jps #显示以下几个进程说明启动成功
96662 Jps
95273 DataNode #可有可无
95465 SecondaryNameNode #重要
95144 NameNode #重要
95900 NodeManager #可有可无
95775 ResourceManager #非常重要
[root@hadoop hadoop]# stop-all.sh
Stopping namenodes on [hadoop]
Last login: Mon Jul 16 05:58:46 EDT 2018 on pts/1
Stopping datanodes
Last login: Mon Jul 16 06:19:41 EDT 2018 on pts/1
Stopping secondary namenodes [hadoop]
Last login: Mon Jul 16 06:19:49 EDT 2018 on pts/1
2018-07-16 06:20:25,023 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Stopping nodemanagers
Last login: Mon Jul 16 06:20:13 EDT 2018 on pts/1
Stopping resourcemanager
Last login: Mon Jul 16 06:20:25 EDT 2018 on pts/1
1.我们可以看到不管是启动还是关闭hadoop集群,系统都会报如下错误:
WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
解决方式:先看看我们安装的hadoop是否是64位的
[root@hadoop hadoop]# file /usr/local/hadoop/lib/native/libhadoop.so.1.0.0 #出现以下信息表示我们的hadoop是64位的
/usr/local/hadoop/lib/native/libhadoop.so.1.0.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=8d84d1f56b8c218d2a33512179fabffbf237816a, not stripped
永久解决方式:
[root@hadoop hadoop]# vi /usr/local/hadoop/etc/hadoop/log4j.properties #在文件末尾添加如下一句,保存退出
log4j.logger.org.apache.hadoop.util.NativeCodeLoader=Error
2.hadoop-3.1.0启动hadoop集群时还有可能可能会报如下错误信息:
[root@hadoop ~]# start-all.sh
Starting namenodes on [hadoop]
ERROR: Attempting to operate on hdfs namenode as root
ERROR: but there is no HDFS_NAMENODE_USER defined. Aborting operation.
Starting datanodes
ERROR: Attempting to operate on hdfs datanode as root
ERROR: but there is no HDFS_DATANODE_USER defined. Aborting operation.
Starting secondary namenodes [hadoop]
ERROR: Attempting to operate on hdfs secondarynamenode as root
ERROR: but there is no HDFS_SECONDARYNAMENODE_USER defined. Aborting operation.
2018-07-16 05:45:04,628 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Starting resourcemanager
ERROR: Attempting to operate on yarn resourcemanager as root
ERROR: but there is no YARN_RESOURCEMANAGER_USER defined. Aborting operation.
Starting nodemanagers
ERROR: Attempting to operate on yarn nodemanager as root
ERROR: but there is no YARN_NODEMANAGER_USER defined. Aborting operation.
解决方式:
[root@hadoop hadoop]# vi /etc/profile #添加如下几行
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root
[root@hadoop hadoop]# source /etc/profile
3.启动hadoop后发现无法访问50070端口?
解决方式参考这里
4.Hadoop集群启动后,使用jps查看没有DataNode进程?
原因:在第一次格式化dfs后,启动并使用了hadoop,后来又重新执行了格式化命令(hdfs namenode -format),这时namenode的clusterID会重新生成,而datanode的clusterID 保持不变。因此就会造成datanode与namenode之间的id不一致。
解决方法:删除dfs.data.dir(在core-site.xml中配置了此目录位置)目录里面的所有文件,重新格式化,最后重启。
[root@hadoop ~]# stop-all.sh
...
[root@hadoop ~]# rm -rf /var/hadoop/tmp/
[root@hadoop ~]# hdfs namenode -format
...
[root@hadoop ~]# start-all.sh
...
https://downloads.lightbend.com/scala/2.13.1/scala-2.13.1.tgz
cd /usr/local
wget https://downloads.lightbend.com/scala/2.13.1/scala-2.13.1.tgz
tar zxvf scala-2.13.1.tgz
[root@xysokohost local]# vim /etc/profile
export SCALA_HOME=/usr/local/scala-2.13.1
export PATH=$PATH:$SCALA_HOME/bin
[root@xysokohost local]# source /etc/profile
[root@xysokohost local]# scala -version
Scala code runner version 2.13.1 -- Copyright 2002-2019, LAMP/EPFL and Lightbend, Inc.
我们将压缩包放到 /opt/spark
目录下,然后将其解压。
解压命令
tar -xvf spark-2.4.3-bin-hadoop2.7.tgz
大同小异,在 /etc/profile
中添加环境变量,添加 export SPARK_HOME=/opt/spark/spark-2.4.3-bin-hadoop2.7
并在 path
中加入 ${SPARK_HOME}/bin:
。
下面是我的环境变量。
export JAVA_HOME=/usr/local/java/jdk1.8.0_221
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export SCALA_HOME=/opt/scala/scala-2.12.2
export SPARK_HOME=/opt/spark/spark-2.4.3-bin-hadoop2.7
export PATH=${JAVA_HOME}/bin:${SPARK_HOME}/bin:${SCALA_HOME}/bin:$PATH
首先进入到解压文件的 conf
目录下,也就是是 /opt/spark/spark-2.4.3-bin-hadoop2.7/conf/
,我们可以看到有一个模板文件,我们 copy
一份。
cp spark-env.sh.template spark-env.sh
我们对拷贝的文件进行编辑,加入以下内容:
export JAVA_HOME=/usr/local/java/jdk1.8.0_221
export SCALA_HOME=/opt/scala/scala-2.12.2
export SPARK_HOME=/opt/spark/spark-2.4.3-bin-hadoop2.7
export SPARK_MASTER_IP=learn
export SPARK_EXECUTOR_MEMORY=1G
同样我们拷贝一份 slaves
cp slaves.template slaves
编辑 slaves
,内容为 localhost
:
localhost
然后我们可以进行测试,/opt/spark/spark-2.4.3-bin-hadoop2.7
在这个目录下执行:
./bin/run-example SparkPi 10
在这我们可以看到已经执行成功。
跟上面一样也是在 /opt/spark/spark-2.4.3-bin-hadoop2.7
目录下,执行:
./bin/spark-shell
我们可以看到以下结果: