1. 环境准备与基础安装
在开始部署Spark集群之前,我们需要确保所有节点都具备基本运行环境。我建议使用三台配置相同的服务器,操作系统选择CentOS 7.x或Ubuntu 18.04 LTS,这些系统对Hadoop和Spark的兼容性最好。实际项目中遇到过不同系统版本导致的库依赖问题,所以统一环境很重要。
首先在所有节点上安装Java环境,这是Spark运行的基础。我习惯使用OpenJDK 8,因为它在资源占用和稳定性方面表现不错:
sudo yum install -y java-1.8.0-openjdk-devel # CentOS sudo apt-get install -y openjdk-8-jdk # Ubuntu验证Java安装是否成功:
java -version # 应该显示类似:openjdk version "1.8.0_322"接下来处理Spark安装包。从Apache官网下载时要注意版本匹配,特别是Hadoop支持版本。我推荐使用清华镜像站加速下载:
wget https://mirrors.tuna.tsinghua.edu.cn/apache/spark/spark-2.4.8/spark-2.4.8-bin-hadoop2.7.tgz解压安装包时有个小技巧:先创建统一目录结构再解压,可以避免后续路径混乱。我通常在/opt下建立module目录集中管理:
sudo mkdir -p /opt/module sudo tar -zxvf spark-2.4.8-bin-hadoop2.7.tgz -C /opt/module/ cd /opt/module && sudo mv spark-2.4.8-bin-hadoop2.7 spark-2.4.8环境变量配置是新手容易出错的地方。建议在/etc/profile.d/下单独创建spark.sh,这样更易于管理:
sudo tee /etc/profile.d/spark.sh <<-'EOF' export SPARK_HOME=/opt/module/spark-2.4.8 export PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin EOF source /etc/profile2. 关键配置文件详解
2.1 workers文件配置
workers文件(旧版叫slaves)决定了哪些节点会作为Worker加入集群。配置时建议使用主机名而非IP,这样即使IP变更也不影响集群运行。先修改master节点的workers文件:
cd $SPARK_HOME/conf cp workers.template workers vim workers内容示例(假设三台机器主机名分别是master、worker1、worker2):
worker1 worker2这里有个实际项目中的经验:如果Worker节点较多,可以使用动态主机名生成:
seq -f "worker%.0f" 1 10 > workers # 生成worker1到worker102.2 spark-env.sh深度配置
spark-env.sh是Spark的核心配置文件,我把它分为基础配置和性能调优两部分。先创建配置文件:
cp spark-env.sh.template spark-env.sh vim spark-env.sh基础配置部分必须包含:
# 基础环境 export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk export HADOOP_CONF_DIR=/opt/module/hadoop-3.1.4/etc/hadoop # 主节点设置 export SPARK_MASTER_HOST=master export SPARK_MASTER_PORT=7077 export SPARK_MASTER_WEBUI_PORT=8085 # 避免与Zookeeper冲突 # 资源分配 export SPARK_WORKER_CORES=2 export SPARK_WORKER_MEMORY=2g export SPARK_EXECUTOR_CORES=1 export SPARK_EXECUTOR_MEMORY=1g性能调优部分可以根据硬件调整:
# 网络配置 export SPARK_LOCAL_IP=$(hostname -i) export SPARK_PUBLIC_DNS=$(hostname) # 高级参数 export SPARK_WORKER_OPTS="-Dspark.worker.cleanup.enabled=true" export SPARK_DAEMON_MEMORY=1g2.3 spark-defaults.conf实战配置
这个文件控制Spark应用的默认行为。建议至少配置以下参数:
cp spark-defaults.conf.template spark-defaults.conf vim spark-defaults.conf关键配置示例:
# 集群基础 spark.master spark://master:7077 # 日志管理 spark.eventLog.enabled true spark.eventLog.dir hdfs://master:8020/spark-logs spark.history.fs.logDirectory hdfs://master:8020/spark-logs # 执行器配置 spark.executor.memory 1g spark.driver.memory 512m spark.executor.cores 1 # 动态分配(适合多任务场景) spark.dynamicAllocation.enabled true spark.dynamicAllocation.initialExecutors 1 spark.dynamicAllocation.minExecutors 1 spark.dynamicAllocation.maxExecutors 43. 集群部署与HDFS集成
3.1 HDFS目录准备
Spark与HDFS集成主要涉及日志存储。先在HDFS创建专用目录:
hdfs dfs -mkdir -p /spark-logs hdfs dfs -chmod 777 /spark-logs # 确保所有节点有写入权限遇到过权限问题导致日志写入失败的情况,所以权限设置很重要。如果启用了Kerberos认证,还需要配置keytab:
spark.kerberos.keytab /path/to/spark.keytab spark.kerberos.principal spark/master@YOUR.REALM3.2 安装包分发
将配置好的Spark安装包分发到Worker节点。我习惯用rsync替代scp,它能增量同步且保留文件属性:
rsync -avz $SPARK_HOME/ worker1:/opt/module/spark-2.4.8/ rsync -avz $SPARK_HOME/ worker2:/opt/module/spark-2.4.8/分发后记得在每个Worker节点上执行:
source /etc/profile3.3 端口冲突解决方案
Spark默认Web UI端口8080容易与其他服务冲突。除了修改spark-env.sh中的SPARK_MASTER_WEBUI_PORT,还需要检查:
netstat -tunlp | grep 8085 # 确认新端口未被占用如果端口仍被占用,可以尝试这些端口:
- 8181
- 8282
- 4040-4045
4. 集群启动与验证
4.1 启动流程详解
启动集群的正确顺序应该是:
- 确保HDFS正常运行
- 启动Master节点
- 启动Worker节点
具体命令:
# 在Master节点执行 $SPARK_HOME/sbin/start-master.sh # 在各个Worker节点执行 $SPARK_HOME/sbin/start-worker.sh spark://master:7077更简便的方式是使用start-all.sh脚本(在Master节点执行):
$SPARK_HOME/sbin/start-all.sh启动后立即检查日志是个好习惯:
tail -f $SPARK_HOME/logs/spark--org.apache.spark.deploy.master.Master-1-master.out4.2 Web UI验证
访问Master节点的Web UI(默认http://master:8085)应该能看到:
- 集群资源概览
- Worker节点列表
- 运行中的应用
如果无法访问,按这个流程排查:
- 检查防火墙
sudo firewall-cmd --list-ports # CentOS sudo ufw status # Ubuntu - 确认Master进程是否运行
jps | grep Master - 查看端口监听状态
netstat -tunlp | grep 8085
4.3 提交测试任务
运行Spark自带的示例程序验证集群:
spark-submit \ --class org.apache.spark.examples.SparkPi \ --master spark://master:7077 \ $SPARK_HOME/examples/jars/spark-examples_2.11-2.4.8.jar \ 100成功执行会输出类似结果: "Pi is roughly 3.1414156"
4.4 日常管理命令
常用管理命令汇总:
# 查看Master状态 $SPARK_HOME/bin/spark-class org.apache.spark.deploy.master.Master # 查看Worker状态 $SPARK_HOME/bin/spark-class org.apache.spark.deploy.worker.Worker # 优雅停止集群 $SPARK_HOME/sbin/stop-all.sh # 单独启停组件 $SPARK_HOME/sbin/start-history-server.sh $SPARK_HOME/sbin/stop-history-server.sh5. 常见问题排查
5.1 Worker节点无法注册
如果Worker没有出现在Web UI中,按以下步骤排查:
- 检查Worker日志:
tail -100 $SPARK_HOME/logs/spark--org.apache.spark.deploy.worker.Worker-1-worker1.out - 确认网络连通性:
ping master telnet master 7077 - 验证配置文件一致性:
diff $SPARK_HOME/conf/spark-env.sh worker1:$SPARK_HOME/conf/spark-env.sh
5.2 内存不足问题
Spark任务频繁失败可能是内存不足的表现。解决方法:
- 调整spark-env.sh中的内存设置:
export SPARK_WORKER_MEMORY=4g export SPARK_EXECUTOR_MEMORY=2g - 或者在spark-submit时指定:
spark-submit --executor-memory 2g --driver-memory 1g ... - 检查系统swap使用情况:
free -h
5.3 日志文件过大
长期运行的集群会产生大量日志,建议配置日志轮转:
# 修改log4j.properties cp $SPARK_HOME/conf/log4j.properties.template $SPARK_HOME/conf/log4j.properties vim $SPARK_HOME/conf/log4j.properties修改关键参数:
log4j.appender.rolling.maxFileSize=100MB log4j.appender.rolling.maxBackupIndex=106. 性能调优建议
6.1 资源配置黄金法则
根据实践经验,推荐以下资源配置比例:
- 每个Worker保留1-2核给操作系统
- Executor内存不超过Worker总内存的75%
- 每个Executor配置3-5个核心最佳
示例计算(8核32G服务器):
export SPARK_WORKER_CORES=8 export SPARK_WORKER_MEMORY=28g # 保留4G给系统 export SPARK_EXECUTOR_CORES=4 export SPARK_EXECUTOR_MEMORY=6g # 每个executor 6g6.2 关键性能参数
在spark-defaults.conf中添加这些参数可以提升性能:
# 序列化配置 spark.serializer org.apache.spark.serializer.KryoSerializer spark.kryoserializer.buffer.max 256m # 内存管理 spark.memory.fraction 0.8 spark.memory.storageFraction 0.3 # 网络超时 spark.network.timeout 300s spark.executor.heartbeatInterval 60s # 动态分配 spark.shuffle.service.enabled true spark.dynamicAllocation.executorIdleTimeout 60s6.3 监控与优化
建议部署Spark历史服务器便于性能分析:
$SPARK_HOME/sbin/start-history-server.sh访问地址:http://master:18080
结合Ganglia或Prometheus监控集群资源使用情况,重点关注:
- CPU利用率波动
- 内存GC频率
- 网络I/O负载
- 磁盘读写吞吐量