Contents

Spark集群搭建

spark_build

写在前面

本文档是俩叫 nil 和 mark 的靓仔和 yyds 李传艺老师,在 yyds 的办公室倒腾一整个下午之后,总结出的血泪教训。

本文是在 manjaro 和 Ubuntu 两个 Linux 发行版的个人 PC 上,启动 hadoop hdfs 集群和 spark 集群的操作过程。涉及到不同 username 和不同 hostname 的物理机,在真实网络情况下 (宿舍路由器局域网) 的配置操作,仅供参考。

其中 DataNode 机器的配置如下(夹带私货,欢迎加入 manjaro 邪教)。本文档所有命令都可以在 manjaro/ArchLinux 下执行,Ubuntu 或其他系统请自行寻找对照命令

1
2
3
4
5
6
7
OS: Manjaro 20.1.1 Mikah
Kernel: x86_64 Linux 5.8.11-1-MANJARO
Shell: zsh 5.8
CPU: Intel Core i7-8550U @ 8x 4GHz
Disk: 196G / 482G (42%)
GPU: Mesa Intel(R) UHD Graphics 620 (KBL GT2)
RAM: 5227MiB / 15896MiB
机器类型局域网 IPhostnameusername
master/slaver192.168.1.103mark-pcmark
slaver192.168.1.104nil-PCnil

集群环境是

  • Hadoop 2.7.7
  • Spark version 3.0.1
  • Scala version 2.12.10
  • OpenJDK 64-Bit Server VM, Java 1.8.0_265

操作流程

  1. 创建镜像 or 还原点 (可选,推荐)
  2. 搭建 ssh 环境
  3. 修改 hosts 文件
  4. 安装 java 环境
  5. 安装 hadoop
  6. 安装 spark
  7. 启动集群,运行命令
  8. 开汽水庆祝

搭建 Ssh 环境

首先配置好自己的 ssh 环境

1
2
3
ssh-keygen -t rsa
chmod 600 ~/.ssh/authorized_keys
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
1
2
3
4
5
6
7
文件目录如下
.ssh
├── authorized_keys
├── config
├── id_rsa
├── id_rsa.pub
└── known_hosts

ifconfigip address show 查看 ip 地址后,ping 一下你要连接的电脑的 ip,保证网络通畅。

  • 免密登录:将其他机器的 id_rsa.pub 里的内容添加到本机的 authorized_keys 里 (用 cat >> 追加)

测试 ssh 连接。如果出现 ssh:connect to host port 22:Connection refused,那记得运行命令 systemctl start sshd 打开 sshd.service。

如果我在 nil-PC 上连接 mark-pc,直接 ssh 192.168.1.103 会失败,因为的登录用户名是 nil,而 mark-pc 里没有 nil 这个用户。正确做法是 ssh mark@192.168.1.103,接收对方 fingerprint 到 known_hosts 里后,就可以免密登录。

修改 Hosts 文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
这是个栗子
# Host addresses
# 127.0.0.1  localhost
# 127.0.1.1  nil-PC
::1        localhost ip6-localhost ip6-loopback
ff02::1    ip6-allnodes
ff02::2    ip6-allrouters

192.168.1.103 mark-pc
192.168.1.104 nil-PC

Notice:

  1. 将 127.0.0.1 和 127.0.1.1 的路径都去掉,否则在 hadoop 启动的时候,会优先在 localhost 提交出错
  2. 在 ip 后面,要写的是 hostname,可以执行 hostname 看到,不是 username
  3. 在修改完后,一定要刷新 hosts,运行命令 systemctl restart NetworkManager 或是注销重启

修改后检查:

  1. ping mark-pc 成功
  2. ssh mark@mark-pc 可以登录

安装 Java 环境

正常安装 java8,java home 不出意外在 /usr/lib/jvm/ 下,本机路径是 /usr/lib/jvm/java-8-openjdk/,可以在 bin 目录下执行 ./javac -version 看到 java 版本是 javac 1.8.0_265(好像 1.8.0 后的小小版本不影响,mark 是 261 也运行正常)

将 java 添加至环境变量,在/etc/profile 文件追加如下内容 (具体内容因人而异)

1
2
3
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk
export CLASSPATH=:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH

每一次修改后都要 source /etc/profile 刷新环境变量。在命令行输入 echo $JAVA_HOME 进行检验

安装 Hadoop

  1. 选择了 hadoop-2.7.7,也可以选最新文件。我将其解压在了/usr/lib/hadoop-2.7.7 下(这个随便,但是不建议放在/home 里面,涉及到用户权限)

notice:所有机器上,hadoop 和 spark 的绝对位置和内容要保持严格一致

  1. 将 hadoop 添加到环境变量,追加了(具体内容因人而异)
1
2
export HADOOP_HOME=/usr/lib/hadoop-2.7.7
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
  1. 验证安装,执行 hadoop version

修改配置文件

注意,这里的 mark-pc 都要改成期望作为 master 的电脑的 hostname绝对路径也要做相应的修改

  1. 在 $HADOOP_HOME 下添加目录 tmp, hdfs, hdfs/name, hdfs/data
  2. $HADOOP_HOME/etc/hadoop/core-site.xml

注意,在集群模式下,fs.defaultFS 要写集群里 namenode 的 ip 和端口

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<configuration>
  <!-- 指定namenode的地址 -->
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://mark-pc:9000</value>
  </property>
  <property>
    <!-- 用来指定使用hadoop时产生文件的存放目录 -->
    <name>hadoop.tmp.dir</name>
    <value>/usr/lib/hadoop-2.7.7/tmp</value>
  </property>
</configuration>
  1. $HADOOP_HOME/etc/hadoop/hdfs-site.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<configuration>
  <property>
    <name>dfs.namenode.secondary.http-address</name>
    <value>mark-pc:50090</value>
  </property>
  <property>
    <!-- 指定hdfs保存数据的副本数量 -->
    <name>dfs.replication</name>
    <value>1</value>
  </property>
  <property>
    <name>dfs.namenode.name.dir</name>
    <value>file:/usr/lib/hadoop-2.7.7/hdfs/name</value>
  </property>
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>file:/usr/lib/hadoop-2.7.7/hdfs/data</value>
  </property>
</configuration>
  1. $HADOOP_HOME/etc/hadoop/slaves

注意,只有这里是要写 用户名@主机名 的,否则 namenode 在登录 datanode 的时候,用的是 namenode 当前的用户名,造成出错

注意,slaves 文件只存 datanode 的 host,当然鉴于 namenode 都不干啥事,建议把 master 主机也作为 slaver 一起执行计算任务,符合社会主义核心价值观(雾)

1
2
mark@mark-pc
nil@nil-PC

验证 Hadoop 集群安装成功

  1. 格式化文件系统 hdfs namenode -format,看到最后几行有 ExitCode=0 这样的字眼就说明格式化成功了,如果有误,可以检查一下 xml 文件的配置
  2. 在 $HADOOP_HOME/sbin 下运行 start-all.sh,唤起 namenode 和 datanode,分别在 master 和 slaver 上执行 jps,如果看到以下内容就说明成功了

master 上看到:

1
2
3
4
5
6
xxxx Jps
xxxx SecondaryNameNode
xxxx NameNode
xxxx DataNode
xxxx NodeManager
xxxx ResourceManager (似乎这个是可有可无)

slaver 上看到

1
2
3
xxxx Jps
xxxx DataNode
xxxx NodeManager

这样就说明 hadoop 集群运行成功了

Notice:如果在 start-all 的时候发现 datanode 没有被唤起,大概率是 datanode 的 id 和 master 上的 id 不同,因为你执行 format 命令多次。解决方案是在所有的机器上都删除 $HADOOP_HOME/hdfs/data/current 文件夹,重新 format 即可。

验证 Hadoop 集群运行状态

  1. 访问 http://192.168.1.103:50070 (这里的 ip 是 master 的 ip 地址),看到 DataNodes 数量符合
  2. 在 master 上运行 hdfs dfs -mkdir /hadoop 后,可以在网页的文件管理页面上找到新建的目录,就大功告成了!

安装 Spark

  1. 先装一个 scala,配置好 SCALA_HOME,运行 scala 看到 repl 即可
1
2
export SCALA_HOME=/usr/lib/scala-2.13.3
export PATH=$PATH:$SCALA_HOME/bin
  1. 将 spark 一样的解压到/usr/lib 下,配置 SPARK_HOME
1
2
export SPARK_HOME=/usr/lib/spark-3.0.1-bin-hadoop2.7
export PATH=$PATH:$SPARK_HOME/bin
  1. $SPARK_HOME/conf/slaves

和 $HADOOP_HOME/etc/hadoop/slaves 内容是一样的

1
2
mark@mark-pc
nil@nil-PC
  1. **先启动 hadoop!**启动 Spark,在 SPARK_HOME 的 sbin 目录下执行 start-all.sh,会唤起所有的节点,此时 master 中运行 jps 在原有基础上新增了 Master,slaver 里新增了 Worker
  2. 进入 http://192.168.1.103:8080 看到 spark 监控网页,并且 slaver 数量正常,就说明正常启动

启动集群,运行命令

  1. 运行代码 $SPARK_HOME/bin/run-example SparkPi 10,能够正确执行计算出 $\pi$,说明本地运行是 ok 的
  2. 向集群提交任务,执行

./spark-submit --class org.apache.spark.examples.JavaSparkPi --master spark://mark-pc:7077 ../examples/jars/spark-examples_2.12-3.0.1.jar

在 8088 端口看到 application 和运行的机器,那就大功告成啦