Spark安装记录

一、使用的软件

软件 版本 下载地址
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安装

1、创建hadoop用户

所有的节点均创建一个名为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用户

2、配置网络环境

2.1 修改主机名

修改 /etc/hostname文件,每个节点都要修改。

  • 主节点修改为:Master
  • 从节点分别修改为:Slave01,Slave02,…

注意:如果是桌面版直接修改/etc/hostname文件即可,服务器版还需要修改/etc/cloud/cloud.cfg文件,修改如下:

# This will cause the set+update hostname module to not operate (if true)
preserve_hostname: true  #这里是将false改成true

2.2 添加IP与主机名的映射关系

/etc/hosts文件里添加如下内容(每个节点都要修改,根据实际情况修改ip)

192.168.233.200  Master
192.168.233.201  Slave01
192.168.233.202  Slave02

检查各个节点是否能相互ping通。

2.3 设置SSH无密码登录节点

让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'

3、启动Hadoop集群

3.1、首先格式化NameNode

注意:如果格式化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目录下生成元数据信息。

3.2、输入 start-all.sh 启动

[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

3.3、执行 jps 验证集群是否启动成功

[root@hadoop hadoop]# jps #显示以下几个进程说明启动成功
96662 Jps
95273 DataNode #可有可无
95465 SecondaryNameNode #重要
95144 NameNode #重要
95900 NodeManager #可有可无
95775 ResourceManager #非常重要

3.4、关闭hadoop集群

[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

3.5、登录HDFS管理界面(NameNode):http://ip:50070

3.6、登录MR管理界面: http://ip:8088

3.7、一些问题

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 
...

三、安装scala

1、下载

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

2、配置文件

[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.

四、spark安装

4.1 下载包及解压

我们将压缩包放到 /opt/spark 目录下,然后将其解压。

解压命令

tar -xvf spark-2.4.3-bin-hadoop2.7.tgz

4.2 配置环境变量

大同小异,在 /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

4.3 配置 Spark

首先进入到解压文件的 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

在这我们可以看到已经执行成功。

4.4 启动 Spark Shell

跟上面一样也是在 /opt/spark/spark-2.4.3-bin-hadoop2.7 目录下,执行:

./bin/spark-shell

我们可以看到以下结果:

top