Ubuntu 16.04 搭建 Spark & Hadoop集群的详细步骤及报错填坑

在Ubuntu 16.04 安装 Spark & Hadoop分布式集群的记录

环境配置

如下设置默认都在每一台机器上都要进行。

配置hadoop用户

首先是在每个机器上创建hadoop用户,设置密码(方便起见建议都设置一样的),并赋予其root权限

1
2
3
sudo useradd -m hadoop -s /bin/bash
sudo passwd hadoop
sudo adduser hadoop sudo

固定IP

为防止重启导致IP变化,需要固定Ip方法参考Ubuntu16.04 固定IP与设置DNS | 不正经数据科学家

配置hosts

为方便部署,可配置hosts名,方便输入地址,如下

1
2
3
4
5
vim /etc/hosts
192.168.1.113 czn.shise.com
192.168.1.102 czm.shise.com
192.168.1.120 wwj.shise.com
192.168.1.123 bas.shise.com

测试能否ping通
ping czn.shise.com -c 3

配置 ssh 无密码访问集群机器

每台机器之间以及每台机器与自己的localhost都需配置ssh免密码登录。
如未安装ssh需 sudo apt install openssh-server

1
2
3
4
ssh localhost
exit # 退出刚才的 ssh localhost
cd ~/.ssh/ # 若没有该目录,请先执行一次ssh localhost
ssh-keygen -t rsa # 会有提示,都按回车就可以

再用ssh-copy-id来设置免密码登录,如

1
2
3
4
ssh-copy-id localhost
ssh-copy-id czn.shise.com
ssh-copy-id czm.shise.com
ssh-copy-id bas.shise.com

在每个机器上都如此设置与其它机器的免密码登录。
这里默认都是hadoop用户,所以不需带用户名,如果不是则需要带用户名如
ssh-copy-id hadoop@czn.shise.com

Java环境

统一使用openjdk-8,sudo apt-get install openjdk-8-jre openjdk-8-jdk
会默认安装在/usr/lib/jvm/java-8-openjdk-amd64

Hadoop集群配置

我们先登录至作为master的机器,配置好之后再将hadoop环境复制至各slave即可,非常方便。
首先是Hadoop集群的配置,下载Index of /apache/hadoop/common,我们选择2.7.3版本。
放置

1
2
3
4
sudo tar -zxf ~/Downloads/hadoop-2.7.3.tar.gz -C /usr/local    # 解压到/usr/local中
cd /usr/local/
sudo mv ./hadoop-2.7.3/ ./hadoop # 将文件夹名改为hadoop
sudo chown -R hadoop:hadoop ./hadoop # 修改文件权限

各文件配置

配置hadoop/etc/hadoop文件夹下的各文件,

hadoop-env.sh里添加

1
2
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export HADOOP_PREFIX=/usr/local/hadoop

core-site.xml里添加

1
2
3
4
5
6
7
8
9
10
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://wwj.shise.com:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>file:/usr/local/hadoop/tmp</value>
</property>
</configuration>

yarn-site.xml里添加

1
2
3
4
5
6
7
8
9
10
<configuration>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>wwj.shise.com</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>

改写slaves

1
2
3
4
czn.shise.com
czm.shise.com
wwj.shise.com
bas.shise.com

改写mapred-site.xml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>wwj.shise.com:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>wwj.shise.com:19888</value>
</property>
</configuration>

hdfs-site.xml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<configuration>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>wwj.shise.com:50090</value>
</property>
<property>
<name>dfs.replication</name>
<value>3</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>

复制配置好的hadoop至各机器

在master上压缩文件

1
2
3
4
5
6
7
8
cd /usr/local
sudo rm -r ./hadoop/tmp # 删除 Hadoop 临时文件
sudo rm -r ./hadoop/logs/* # 删除日志文件
tar -zcf ~/hadoop.master.tar.gz ./hadoop # 先压缩再复制
cd ~
scp ./hadoop.master.tar.gz czn.shise.com:/home/hadoop # 复制至各机器
scp ./hadoop.master.tar.gz czm.shise.com:/home/hadoop
scp ./hadoop.master.tar.gz bas.shise.com:/home/hadoop

再登录至复制过去的每个slave

1
2
3
sudo rm -r /usr/local/hadoop    # 删掉旧的(如果存在)
sudo tar -zxf ~/hadoop.master.tar.gz -C /usr/local
sudo chown -R hadoop /usr/local/hadoop

各机器环境变量

sudo vim ~/.profile
我的环境变量设置如下

1
2
3
4
5
6
7
8
9
# Java Env
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$JRE_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin

# Hadoop Env
export HADOOP_HOME=/usr/local/hadoop
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

source ~/.profile

启动检查

登录master机器,执行 NameNode 的格式化:hdfs namenode -format
先dfs、再yarn

1
2
3
start-dfs.sh
start-yarn.sh
mr-jobhistory-daemon.sh start historyserver

验证hadoop安装

可以通过jps命令查看各个节点启动的进程是否正常。在 master 上应该有以下几个进程:

1
2
3
4
5
$ jps  #run on master
3407 SecondaryNameNode
3218 NameNode
3552 ResourceManager
3910 Jps

在每个slave上应该有以下几个进程:

1
2
3
4
$ jps   #run on slaves
2072 NodeManager
2213 Jps
1962 DataNode

Spark分布式配置

下载及安置

官网下载,Downloads | Apache Spark ,这里我们选择2.2.1版本, 及Pre-build with user-provided Apache Hadoop,

1
2
3
4
sudo tar -zxf ~/Downloads/spark-2.1.1-bin-without-hadoop.tgz -C /usr/local/
cd /usr/local
sudo mv ./spark-2.1.1-bin-without-hadoop/ ./spark
sudo chown -R hadoop:hadoop ./spark # 此处的 hadoop 为你的用户名

配置Spark

1
2
3
cd /usr/local/spark/conf    #进入spark配置目录
cp spark-env.sh.template spark-env.sh #从配置模板复制
vim spark-env.sh #添加配置内容

spark-env.sh末尾添加以下内容(这是我的配置,你可以自行修改):

1
2
3
4
5
6
7
#export SCALA_HOME=/home/spark/workspace/scala-2.10.4
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export HADOOP_HOME=/usr/local/hadoop
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
SPARK_MASTER_IP=wwj.shise.com
SPARK_LOCAL_DIRS=/usr/local/spark
SPARK_DRIVER_MEMORY=1G

参考Using Spark’s “Hadoop Free” Build - Spark 2.2.0 Documentationspark-env.sh还需加上
export SPARK_DIST_CLASSPATH=$(/usr/local/hadoop/bin/hadoop classpath)

vim slaves在slaves文件下填上slave主机名:

1
2
3
4
czn.shise.com
czm.shise.com
wwj.shise.com
bas.shise.com

复制配置好的Spark至各机器

1
2
3
4
5
tar -zcf ~/spark.master.tar.gz ./spark   # 先压缩再复制
cd ~/
scp ./spark.master.tar.gz czn.shise.com:/home/hadoop #传输数据
scp ./spark.master.tar.gz czm.shise.com:/home/hadoop #传输数据
scp ./spark.master.tar.gz bas.shise.com:/home/hadoop #传输数据

启动Spark

sbin/start-all.sh
用jps检查,在 master 上应该有以下几个进程:

1
2
3
4
5
6
7
$ jps
7949 Jps
7328 SecondaryNameNode
7805 Master
7137 NameNode
7475 ResourceManager

在 slave 上应该有以下几个进程:

1
2
3
4
5
6
$jps
3132 DataNode
3759 Worker
3858 Jps
3231 NodeManager

报错及解决

Python in worker has different version 2.7 than that in driver 3.6, PySpark cannot run with different minor versions.Please check environment variables PYSPARK_PYTHON and PYSPARK_DRIVER_PYTHON are correctly set.
出现这个错误的原因是为worker与driver设置了不同的Python版本,解决方法是(以anaconda3.6为例):

vim /usr/local/spark/conf/spark-env.sh
添加

1
2
3
export ANACONDA_ROOT=/home/hadoop/anaconda3
export PYSPARK_DRIVER_PYTHON=$ANACONDA_ROOT/bin/python
export PYSPARK_PYTHON=$ANACONDA_ROOT/bin/pythonexport PYSPARK_PYTHON=$ANACONDA_ROOT/bin/python

值得注意的是,很多教程会让你在.bashrc里设置,这不是推荐的方法。参考自pyspark - How do I set the driver’s python version in spark? - Stack Overflow

参考自