Spark学习笔记

搭建spark集群环境

  • 目 标:

搭建Spark集群环境,一台做为master(192.168.1.195),2台做为slave(192.168.1.122,192.168.1.195)

  • 需要准备环境并且已经完成环境变量设置:
    1
    2
    jdk 1.8
    scala scala-2.12.5
1. 修改hostname和hosts文件
  • 修改hostname
    在这两台机器上修改hostname,centos直接修改
    1
    2
    3
    #vim /etc/hostname

    m0.unicom

mac电脑参照Mac OS X 中 hostname 的设置

  • 修改hosts文件
    1
    2
    3
    4
    5
    #vim /etc/hosts

    192.168.1.195 m0.unicom # 主节点
    192.168.1.195 s0.unicom # slave节点
    192.168.1.122 s1.unicom # slave节点
2. 配置免密登录

配置ssh就是为了能够实现免密登录,这样方便远程管理Hadoop并无需登录密码在Hadoop集群上共享文件资源,并且可以方便spark能方便的管理worker slave。

可以参照我的这篇文章 Mac电脑开启root账号,以及配置免密登录

3 下载安装hadoop

在master节点安装hadoop,配置环境变量

1
2
3
export HADOOP_HOME=/Users/daren/devtool/hadoop-3.0.0
export HADOOP_HOME_WARN_SUPPRESS=1
export PATH=$PATH:$HADOOP_HOME/bin

3.1 配置hdfs地址和端口
进入hadoop目录/Users/daren/devtool/hadoop-3.0.0/etc/hadoop,修改core-site.xml内容为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<configuration>
<property>
<name>hadoop.tmp.dir</name>
<value>/Users/daren/devtool/hadoop-3.0.0/hadoop_data/temp</value>
<description>A base for other temporary directories.</description>
</property>
<property>
<name>fs.defaultFS</name>
<value>hdfs://m0.unicom:9000</value>
</property>
<property>
<name>io.file.buffer.size</name>
<value>131072</value>
</property>

<property>
<name>fs.hdfs.impl.disable.cache</name>
<value>true</value>
</property>

<property>
<name>io.compression.codecs</name>
<value>
org.apache.hadoop.io.compress.GzipCodec,
org.apache.hadoop.io.compress.DefaultCodec,
org.apache.hadoop.io.compress.BZip2Codec,
org.apache.hadoop.io.compress.SnappyCodec
</value>
</property>

</configuration>

3.2 修改mapred-site.xml 内容为

1
2
3
4
5
6
7
8
9
10
11
12

<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapred.hosts.exclude</name>
<value>/usr/unidata/hadoop/etc/hadoop/excludes</value>
<final>true</final>
</property>
</configuration>

3.3 修改hdfs-site.xml为如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.permissions</name>
<value>false</value> <!--关闭防火墙-->
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///Users/daren/devtool/hadoop-3.0.0/hadoop_data/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///Users/daren/devtool/hadoop-3.0.0/hadoop_data/data</value>
</property>
<property>
<name>dfs.balance.bandwidthPerSec</name>
<value>10485760</value>
<description>Specifies the maximum bandwidth that each datanode can utilize for the balancing purpose in term of the number of bytes per second. </description>
</property>

<property>
<name>dfs.http.address</name>
<value>m0.unicom:50070</value>
<description>Secondary get fsimage and edits via dfs.http.address</description>
</property>

<property>
<name>dfs.namenode.secondary.http-address</name>
<value>m0.unicom:50090</value>
</property>

<property>
<name>dfs.namenode.checkpoint.dir</name>
<value>file:/usr/unidata/hadoop/tmp/namesecondary</value>
<description>Determines where on the local filesystem the DFS secondary
name node should store the temporary images to merge.
If this is a comma-delimited list of directories then the image is
replicated in all of the directories for redundancy.
</description>
</property>

<property>
<name>dfs.namenode.checkpoint.edits.dir</name>
<value>file:/usr/unidata/hadoop/tmp/namesecondary</value>
<description>Determines where on the local filesystem the DFS secondary
name node should store the temporary edits to merge.
If this is a comma-delimited list of directories then the edits is
replicated in all of the directories for redundancy.
Default value is same as dfs.namenode.checkpoint.dir
</description>
</property>

<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600</value>
<description>The number of seconds between two periodic checkpoints.
</description>
</property>

<property>
<name>dfs.hosts.exclude</name>
<value>/usr/unidata/hadoop/etc/hadoop/excludes</value>
</property>
</configuration>

3.4 格式化HDFS

这个操作相当于一个文件系统的初始化,执行命令hdfs namenode -format

3.5 启动关闭Hadoop服务

1
2
./start-dfs.sh          
./stop-dfs.sh

3.6 验证hadoop是否启动成功

4 下载安装Spark

去官网下载相应版本的spark,注意scala版本
下载地址 https://spark.apache.org/downloads.html
4.1 配置环境变量

1
2
3
4
5
6
#创建软连接
ln -s /Users/daren/devtool/spark-2.4.4-bin-hadoop2.7 spark

#设置环境变量
export SPARK_HOME=/Users/daren/devtool/spark
export PATH=$PATH:$SPARK_HOME/bin

4.2 配置spark-env.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/Users/daren/devtool/hadoop-3.0.0/lib/native

export SPARK_HISTORY_OPTS="-Dspark.history.ui.port=18080 -Dspark.history.retainedApplications=30 -Dspark.history.fs.logDirectory=hdfs://localhost:9000/history"
#export SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=m0.unidata:2181,m1.unidata:2181,s0.unidata:2181,s1.unidata:2181,s2.unidata:2181 -Dspark.deploy.zookeeper.dir=/spark"
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_91.jdk/Contents/Home
export SCALA_HOME=/Users/daren/devtool/scala
export SPARK_MASTER_IP=s0.unicom
export SPARK_MASTER_PORT=7077
export SPARK_WORKER_CORES=2
export SPARK_WORKER_MEMORY=4g
export HADOOP_CONF_DIR=/Users/daren/devtool/hadoop-3.0.0/etc/hadoop
export SPARK_CLASSPATH=$SPARK_CLASSPATH
#export SPARK_EXECUTOR_MEMORY=1G
#export SPARK_DRIVER_MEMORY=2G

4.3 配置slaves

1
2
s0.unicom
#s1.unicom

4.4 启动spark

1
./start-all.sh

在浏览器查看spark工作 http://192.168.1.195:8080/

遇到的坑

  • 问题1: Spark集群,通过master节点执行start-all.sh启动slave报错
    如下错误
    1
    2
    3
    4
    starting org.apache.spark.deploy.master.Master, logging to /Users/daren/devtool/spark/logs/spark-daren-org.apache.spark.deploy.master.Master-1-m0.unicom.out
    s1.unicom: bash: 第 0 行:cd: /Users/daren/devtool/spark: 没有那个文件或目录
    s1.unicom: bash: /Users/daren/devtool/spark/sbin/start-slave.sh: 没有那个文件或目录
    s0.unicom: starting org.apache.spark.deploy.worker.Worker, logging to /Users/daren/devtool/spark/logs/spark-daren-org.apache.spark.deploy.worker.Worker-1-m0.unicom.out

主要原因是想在master节点上启动所有的节点,而spark集群中需要各个节点中的spark home 的路径和master上spark home节点的路径必须一样,这样在slave节点中就找不到相应的spark home路径,所以报错了。

关键点:路径找不到,是192.168.1.122报的。因为master机器只配了各slave的ip,并不知道他们的spark安装路径,所以我猜测master是按本机的路径去调,但可惜spark在另外两台的目录和master并不一样,因此就找不到指定的路径了。

解决方法两种,第一种是将所有slave机器的spark路径改成和master一致,便可解决,第二种是单独启动master和slave节点

我这里采用第二种方法:
启动master节点,进入master spark home路径下的sbin目录中,

1
./start-master.sh -h 192.168.3.207(master ip) --host 192.168.3.207(master ip)

启动slave节点,进入slave spark home路径下的sbin目录中,执行

1
./start-slave.sh spark://192.168.3.207(master ip):7077

  • 问题2: master节点用户非root用户,slave节点用root节点,如何解决免密登录问题

原因分析:在本地开发环境想要搭建spark集群,我本地电脑用的是mac电脑作为master节点,没开启root账号,用的是“daren”账号,而slave(s1.unicom)节点用的是root账号,在开启了免密登录之后使用start-all.sh启动spark集群的时候,显示一直无法登录,报权限失败,无法登录,发现是ssh登录的时候,使用的时候/etc/hosts中配置的地址就行登录的,如下:

1
2
3
192.168.1.195  m0.unicom
192.168.1.195 s0.unicom
192.168.1.122 s1.unicom

当通过

1
ssh s1.unicom

登录的时候,其实想当于

1
ssh daren@192.168.1.122

而对于slave节点来说,是不存在daren用户的,所以我们需要修改ssh登录使用的用户名,刚开始以为可以在spark-env中进行配置,最后发现修改ssh config就可以,如下:

1
2
3
4
5
vim ~/.ssh/config
Host s1.unicom
HostName 192.168.1.122
User root
IdentityFile ~/.ssh/122_rsa

这样我们在使用ssh s1.unicom登录的时候会修改为

1
ssh root@192.168.1.122

这样就满足了我们的需要。

知识点:

Spark中map和flatMap的区别详解
Spark笔记:RDD基本操作(上)
Spark笔记:RDD基本操作(下)

参考资料

分享到