Spark 2.3.4 StandAlone 集群模式部署
文档目录
- Spark 官方文档 - Spark 介绍:Apache Spark - A Unified engine for large-scale data analytics;
- Spark 官方文档 - 集群模式介绍:Cluster Mode Overview;
- Spark 官方文档 - StandAonle 模式介绍:Spark Standalone Mode。
服务架构
Spark 作为独立的进程集运行,由主程序(Driver Program)
中的 SparkContext
进行协调。
具体而言,为了能在集群上运行 Spark,SparkContext 可以连接多种不同的集群管理器(Cluster Manager)
,以使其能够使用被分配的资源。当连接完成后,Spark 会在被分配的节点上获得执行器(executors)
,用它来对应用程序进行计算和数据存储;随后,SparkContext 会先将应用代码发送给执行器,后将任务(task)
也发给执行器。使执行器能够通过任务和代码,完成特定的计算操作。
上述架构中,有如下几个特征:
- 每个应用程序有各自独立的执行器。它们会在整个应用程序生命周期内保持运行,且在多线程中运行任务;
- 优点:良好的隔离性。无论是调度,还是执行器自身操作都有良好的隔离性,不会产生彼此的干扰;
- 缺点:无法共享数据。由于相互隔离,导致在不同的应用程序之间,无法共享数据,除非将其写入都可访问的外部存储中。例如:HDFS。
- 良好的集群管理器兼容性。Spark 无需知道底层集群管理器的类型,只需保证能够在它所分配的资源上获取执行器,并且保证这些执行器能够相互通信即可;
- 主程序必须与工作节点在同一网络内。由于在整个应用程序的生命周期内,主程序需要监听和获取来自执行器的信息,所以必须保证在
工作节点(Worker Node)
上,能够通过网络访问主程序; - 主程序与工作节点尽量靠近。由于主程序需要在集群上调度任务,所以若远离工作节点,可能会导致不必要的任务超时或失败。
集群管理器
- Spark StandAlone:Spark 自身提供的集群管理器;
- Mesos:通用集群管理器。还可运行 MapReduce 和服务应用程序;
- YARN:Hadoop 提供的集群管理器;
- Kubernetes:自动化部署、扩展和管理容器化应用程序的开源系统;
- Nomad:非 Spark 官方支持,由第三方支持的集群管理器。
节点分布
在进行 Spark 部署之前,现有环境中已部署上述表格中的 JDK、Scala、ZooKeeper 和 Hadoop。具体步骤,可查看相关操作文档:
- Hadoop-HDFS:Linux 7.9 部署 Hadoop 3.1.1 HDFS 集群;
- ZooKeeper:Linux 7.9 部署 ZooKeeper 3.5.10 集群。
所以本文档只说明 Spark StandAlone 的部署流程。
主机名 | IP 地址 | 依赖-JDK 版本 | 依赖-Scala 版本 | 依赖-ZooKeeper 版本 | 依赖-Hadoop 版本 | Spark 版本 | Spark 角色 |
---|---|---|---|---|---|---|---|
hadoop1 | 10.10.10.131 | 1.8.0_333 | 2.13.1 | 3.5.10 | 3.1.1 | 2.3.4 | Master/Worker/History Server |
hadoop2 | 10.10.10.132 | 1.8.0_333 | 2.13.1 | 3.5.10 | 3.1.1 | 2.3.4 | Master/Worker |
hadoop3 | 10.10.10.133 | 1.8.0_333 | 2.13.1 | 3.5.10 | 3.1.1 | 2.3.4 | Worker |
创建服务目录
此处创建了两个 Spark 数据目录:spark_data1 和 spark_data2,目的是为了实现单节点多路径的数据目录冗余配置。
在实际生产中,建议将 Spark 的数据目录至少分配到 2 个不同的磁盘存放,其目的在于增加数据的安全性,但不会起到负载均衡的效果。
按节点分布,每个节点都进行如下操作。
mkdir -p /data/service/spark/{spark_data1,spark_data2,spark_logs,spark_tmp}
存放介质
1. 下载介质
基于 Spark 官方介质下载路径:Spark Medium URL,完成 Spark 源码安装包下载。
按节点分布,每个节点都进行如下操作。
wget https://archive.apache.org/dist/spark/spark-2.3.4/spark-2.3.4-bin-hadoop2.7.tgz -O /data/service/spark/
2. 解压介质
tar -zxf /data/service/spark/spark-2.3.4-bin-hadoop2.7.tgz -C /data/service/spark
服务部署
1. 节点免密
1.1. 生成密钥
按节点分布,每个节点都进行如下操作。
ssh-keygen -t rsa
1.2. 汇总密钥
将所有密钥汇总至 hadoop1。
ssh root@hadoop1 "cat id_rsa.pub" >> /root/.ssh/authorized_keys
ssh root@hadoop2 "cat id_rsa.pub" >> /root/.ssh/authorized_keys
ssh root@hadoop3 "cat id_rsa.pub" >> /root/.ssh/authorized_keys
1.3. 分发密钥
将 hadoop1 上的密钥集分发给所有节点。
scp /root/.ssh/authorized_keys root@hadoop2:/root/.ssh/authorized_keys
scp /root/.ssh/authorized_keys root@hadoop2:/root/.ssh/authorized_keys
2. 主机名解析
若节点未配置 DNS 解析,则可通过配置 /etc/hosts 的方式,实现节点间的主机名解析。
按节点分布,每个节点都进行如下操作。
cat > /etc/hosts << EOF
10.10.10.131 hadoop1
10.10.10.132 hadoop2
10.10.10.133 hadoop3
EOF
3. 参数优化
按节点分布,每个节点都进行如下操作。
3.1. 关闭 Selinux
# 调整配置。
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
# 重启操作系统。
reboot
# 查看状态。
getenforce
# 输出结果。
# Disabled 表示已关闭 Selinux。
Disabled
3.2. 关闭防火墙
systemctl stop firewalld && systemctl disable firewalld && systemctl status firewalld
# 输出结果。
# inactive 表示已关闭服务;
# Loaded 行的第二个字段,表示是否开机自启。disabled 表示关闭。
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:firewalld(1)
3.3. 部署时钟同步服务
# 安装服务。
yum install chrony -y
# 配置服务。
cat > /etc/chrony.conf << EOF
server redis1 iburst
driftfile /var/lib/chrony/drift
logdir /var/log/chrony
log measurements statistics tracking
EOF
# 重启服务并设置开机自启。
systemctl enable chronyd && systemctl restart chronyd
# 查看状态。
chronyc sources -v
# 输出结果。
# 有时钟服务器的开头是 ^* ,表示此服务器已正常工作。
210 Number of sources = 1
.-- Source mode '^' = server, '=' = peer, '#' = local clock.
/ .- Source state '*' = current synced, '+' = combined , '-' = not combined,
| / '?' = unreachable, 'x' = time may be in error, '~' = time too variable.
|| .- xxxx [ yyyy ] +/- zzzz
|| Reachability register (octal) -. | xxxx = adjusted offset,
|| Log2(Polling interval) --. | | yyyy = measured offset,
|| \ | | zzzz = estimated error.
|| | | \
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* redis1 4 6 377 5 -73us[ -32us] +/- 57ms
3.4. 关闭 Swap
# 临时关闭。
swapoff -a
# 永久关闭。
sed -i '/\s\+swap\s\+/s/^/#/' /etc/fstab
# 查看状态。
free -g
# 输出结果。
# swap 行都为 0,表示已关闭所有 swap 分区。
total used free shared buff/cache available
Mem: 9 2 0 0 6 6
Swap: 0 0 0
3.5. 优化 vm.swapiness
# 添加配置。
echo "vm.swappiness = 0" >> /etc/sysctl.conf
# 刷新配置。
sysctl -p
# 查看状态。
sysctl -a | grep "vm.swappiness"
# 输出结果。
vm.swappiness = 0
3.6. 优化 transparent_hugepage
# 临时生效。
echo never > /sys/kernel/mm/transparent_hugepage/enabled && echo never > /sys/kernel/mm/transparent_hugepage/defrag
# 永久生效。
# 在 GRUB_CMDLINE_LINUX 行中添加 "transparent_hugepage=never"。
cat > /etc/default/grub << EOF
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap net.ifnames=0 biosdevname=0 rhgb quiet transparent_hugepage=never"
GRUB_DISABLE_RECOVERY="true"
EOF
# 重新生成 grub.cfg 文件。
grub2-mkconfig -o /boot/grub2/grub.cfg
# 重启生效。
reboot
3.7. 优化最大连接数
cat > /etc/security/limits.d/20-nproc.conf << EOF
* - nofile 655350
* - nproc 655350
EOF
4. JDK 部署
进行下述操作之前,已通过 JDK 的官方介质路径,下载了 jdk1.8.0_333 介质,并已存放至每个节点的 /data/service/jdk 目录下。
按节点分布,每个节点都进行如下操作。
# 添加配置。
cat > /etc/profile << EOF
# Oracle JDK 1.8.0_333
export JAVA_HOME=/data/service/jdk/jdk1.8.0_333
export CLASSPATH=$:CLASSPATH:$JAVA_HOME/lib/
export PATH=$PATH:$JAVA_HOME/bin
EOF
# 刷新配置。
source /etc/profile
# 查看状态。
java -version
# 输出结果。
# java version 与所配置 JDK 版本一致,则表示配置正常。
java version "1.8.0_333"
Java(TM) SE Runtime Environment (build 1.8.0_333-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.333-b02, mixed mode)
5. 添加环境变量
建议在进行 Spark 部署之前,先将 Spark 的服务目录添加至全局环境变量中,以便后续的部署和使用中,可直接通过变量来指定 Spark 服务目录。
但不进行环境变量配置,不会影响 Spark 服务的运行和使用。
按节点分布,每个节点都进行如下操作。
cat >> /etc/profile << EOF
# Spark 2.3.4
export SPARK_HOME=/data/service/spark/spark-2.3.4-bin-hadoop2.7
export PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin:$SPARK_HOME/lib
EOF
6. 调整配置文件
Spark 所有的配置文件都以 template 结尾。需将 template 后缀删除,才会被服务识别,所以此处无需备份配置文件,只需新建同名文件即可。
按节点分布,除 hadoop2 节点外,都进行如下操作。
$SPARK_HOME/conf/spark-env.sh
cat > $SPARK_HOME/conf/spark-env.sh << EOF
# 指定依赖服务路径。
export JAVA_HOME="/data/service/jdk/jdk1.8.0_333"
export SCALA_HOME="/data/service/scala/scala-2.13.1"
export HADOOP_HOME="/data/service/hadoop/hadoop-3.1.1"
export HADOOP_CONF_DIR="/data/service/hadoop/hadoop-3.1.1/etc/hadoop"
# 指定 Spark 数据路径。
export SPARK_LOG_DIR="/data/service/spark/spark_logs"
export SPARK_PID_DIR="/data/service/spark/spark_tmp"
export SPARK_LOCAL_DIRS="/data/service/spark/spark_data1,/data/service/spark/spark_data2"
# 指定 Master 配置。
export SPARK_MASTER_HOST=hadoop1
export SPARK_MASTER_PORT=7077
export SPARK_MASTER_WEBUI_PORT=8080
# 指定 WORK 配置。
export SPARK_WORKER_CORES=2
export SPARK_WORKER_MEMORY=4g
export SPARK_WORKER_INSTANCES=1
# 指定所有角色 JVM 大小。
# 只能指定所有角色的统一大小。
exporter SPARK_DAEMON_MEMORY=512m
# 开启 Master HA 模式。
export SPARK_DAEMON_JAVA_OPTS="$SPARK_DAEMON_JAVA_OPTS -Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=hadoop1:2181,hadoop2:2181,hadoop3:2181"
EOF
按节点分布,hadoop2 也是 Master 节点,所以 hadoop2 节点上的配置需修改为如下配置。
cat > $SPARK_HOME/conf/spark-env.sh << EOF
# 指定依赖服务路径。
export JAVA_HOME="/data/service/jdk/jdk1.8.0_333"
export SCALA_HOME="/data/service/scala/scala-2.13.1"
export HADOOP_HOME="/data/service/hadoop/hadoop-3.1.1"
export HADOOP_CONF_DIR="/data/service/hadoop/hadoop-3.1.1/etc/hadoop"
# 指定 Spark 数据路径。
export SPARK_LOG_DIR="/data/service/spark/spark_logs"
export SPARK_PID_DIR="/data/service/spark/spark_tmp"
export SPARK_LOCAL_DIRS="/data/service/spark/spark_data1,/data/service/spark/spark_data2"
# 指定 Master 配置。
export SPARK_MASTER_HOST=hadoop2
export SPARK_MASTER_PORT=7077
export SPARK_MASTER_WEBUI_PORT=8080
# 指定 WORK 配置。
export SPARK_WORKER_CORES=2
export SPARK_WORKER_MEMORY=4g
export SPARK_WORKER_INSTANCES=1
# 指定所有角色 JVM 大小。
# 只能指定所有角色的统一大小。
exporter SPARK_DAEMON_MEMORY=512m
# 开启 Master HA 模式。
export SPARK_DAEMON_JAVA_OPTS="$SPARK_DAEMON_JAVA_OPTS -Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=hadoop1:2181,hadoop2:2181,hadoop3:2181"
EOF
$SPARK_HOME/conf/spark-defaults.conf
cat > $SPARK_HOME/conf/spark-defaults.conf << EOF
spark.eventLog.enabled true
spark.eventLog.dir hdfs://hdfscluster/spark_history_logs
spark.history.fs.logDirectory hdfs://hdfscluster/spark_history_logs
spark.history.retainedApplications 5
EOF
$SPARK_HOME/conf/slaves
cat > $SPARK_HOME/conf/slaves << EOF
hadoop1
hadoop2
hadoop3
EOF
启动服务
按节点分布,hadoop1 节点进行如下操作。
$SPARK_HOME/sbin/start-all.sh
$SPARK_HOME/sbin/start-history-server.sh
按节点分布,hadoop2 节点进行如下操作。
$SPARK_HOME/sbin/start-master.sh
验证服务
- 访问 Spark Web UI:http://10.10.10.21:8080
- 访问 Spark History Server Web UI:http://10.10.10.21:18080