2. Spark 环境搭建:集群安装、配置、YARN 部署与 Shell 测试

在催收数据处理场景中,Spark 集群的稳定性和资源利用率直接影响每日千万级账单的跑批效率。本章将指导你完成从基础安装到生产级 Spark on YARN 部署的全流程,并通过 Spark Shell 验证环境可用性。

2.1 环境准备与版本选型

生产环境推荐使用以下组件版本组合,该组合在催收跑批场景中经过充分验证:

组件 推荐版本 说明
Apache Spark 3.3.2 支持动态资源分配与自适应查询,适合催收任务波峰波谷
Hadoop 3.3.4 提供 HDFS 存储与 YARN 资源调度
Java 8u202 或 11 Spark 3.x 对 Java 8/11 均支持,建议统一版本
Scala 2.12.17 与 Spark 3.3.x 默认 Scala 版本一致
操作系统 CentOS 7.9 / Ubuntu 20.04 生产环境建议使用 CentOS 7.9
催收场景提示: 如果集群需要处理包含中文备注的催收通话记录,请确保所有节点系统编码为 UTF-8,并在 spark-defaults.conf 中设置 spark.sql.session.timeZone 为业务所在时区(如 Asia/Shanghai)。

2.2 Spark 集群安装步骤

以下步骤以 3 节点集群(1 台 Master + 2 台 Worker)为例,主机名分别为 spark-master、spark-worker1、spark-worker2。

  1. 下载与解压
    wget https://archive.apache.org/dist/spark/spark-3.3.2/spark-3.3.2-bin-hadoop3.tgz
    tar -zxvf spark-3.3.2-bin-hadoop3.tgz -C /opt/
    ln -s /opt/spark-3.3.2-bin-hadoop3 /opt/spark
  2. 配置环境变量(所有节点)
    cat >> /etc/profile << 'EOF'
    export SPARK_HOME=/opt/spark
    export PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin
    EOF
    source /etc/profile
  3. 配置 Spark 环境文件($SPARK_HOME/conf/spark-env.sh)
    export JAVA_HOME=/usr/java/jdk1.8.0_202
    export SPARK_MASTER_HOST=spark-master
    export SPARK_MASTER_PORT=7077
    export SPARK_WORKER_CORES=4
    export SPARK_WORKER_MEMORY=8g
    export HADOOP_CONF_DIR=/opt/hadoop/etc/hadoop
  4. 配置 Worker 节点列表($SPARK_HOME/conf/workers)
    spark-worker1
    spark-worker2
  5. 分发 Spark 目录到所有 Worker 节点
    scp -r /opt/spark-3.3.2-bin-hadoop3 spark-worker1:/opt/
    scp -r /opt/spark-3.3.2-bin-hadoop3 spark-worker2:/opt/
  6. 启动集群
    $SPARK_HOME/sbin/start-all.sh
常见错误: 如果 Worker 节点无法注册到 Master,请检查 SPARK_MASTER_HOST 是否配置为可解析的主机名或 IP,并确保各节点 /etc/hosts 中已添加所有集群主机映射。

2.3 Spark 配置详解

催收业务对数据倾斜和内存稳定性要求较高,以下配置项需要重点关注:

配置项 推荐值 催收场景说明
spark.sql.shuffle.partitions 200 控制 Shuffle 分区数,催收大表 JOIN 时可适当调大至 400
spark.memory.fraction 0.75 统一内存管理比例,避免频繁 GC 导致催收任务超时
spark.serializer org.apache.spark.serializer.KryoSerializer Kryo 序列化可减少催收账单对象的内存占用
spark.dynamicAllocation.enabled true 根据催收任务队列长度动态调整 Executor 数量
spark.shuffle.service.enabled true 启用 Shuffle 服务,配合动态资源分配使用

2.4 Spark on YARN 部署模式

在催收生产环境中,Spark on YARN 是最主流的部署方式。它将 Spark 应用作为 YARN 任务运行,由 YARN 统一管理集群资源,避免 Spark Standalone 模式下的资源碎片问题。

部署前需确保 Hadoop 集群已启动,且 HADOOP_CONF_DIR 环境变量正确指向 Hadoop 配置目录。

2.4.1 两种运行模式对比

模式 Driver 位置 适用场景 催收推荐
yarn-client 提交任务的客户端 交互式开发、调试 开发测试阶段
yarn-cluster YARN 集群内部 生产作业、定时调度 催收跑批任务

2.4.2 提交催收任务示例

spark-submit \
  --master yarn \
  --deploy-mode cluster \
  --class com.collect.batch.CollectionBillJob \
  --num-executors 10 \
  --executor-cores 4 \
  --executor-memory 8g \
  --driver-memory 4g \
  --conf spark.sql.shuffle.partitions=400 \
  /data/jobs/collection-bill-job.jar \
  --date 2025-03-21
催收参数调优建议: 对于每日催收账单跑批任务,建议 executor-memory 不超过 8g,避免 YARN 容器内存碎片;num-executors 根据集群总核数按 1:2 比例分配(每核对应 2 个 Executor)。

2.5 Spark Shell 测试

完成部署后,使用 Spark Shell 验证环境是否正常工作。以下测试模拟催收场景中的简单数据统计:

# 启动 Spark Shell(YARN 模式)
spark-shell --master yarn --deploy-mode client

# 在 Scala Shell 中执行以下代码
val df = spark.read.option("header", "true").csv("/data/collection_sample.csv")
df.printSchema()
df.groupBy("status").count().show()

# 退出 Shell
:quit

如果能够正常打印 Schema 并显示分组统计结果,说明 Spark 环境搭建成功。

2.6 集群架构总览

下图展示了 Spark on YARN 模式下催收任务的整体运行架构:

Spark on YARN 催收任务运行架构 spark-submit YARN ResourceManager YARN NodeManager 集群 NM-1 NM-2 NM-3 ApplicationMaster Executor 1 Executor 2 Executor N HDFS 说明:催收任务通过 spark-submit 提交到 YARN,ResourceManager 分配 NodeManager 启动 ApplicationMaster 和 Executor 容器 Executor 从 HDFS 读取催收账单数据,计算结果写回 HDFS 或外部数据库

2.7 催收环境验证清单

完成部署后,建议按以下清单逐项验证,确保环境满足催收业务要求:

  • 连通性验证: 所有节点之间 ssh 免密登录正常,ping 主机名可通。
  • Spark UI 访问: 浏览器打开 http://spark-master:8080,确认所有 Worker 节点状态为 ALIVE。
  • YARN UI 访问: 浏览器打开 http://spark-master:8088,确认 YARN 集群资源总量正确。
  • 催收数据读取测试: 使用 Spark Shell 读取 HDFS 上的催收样本数据(CSV/Parquet),确认无乱码。
  • 简单聚合测试: 执行 groupBy 和 count 操作,观察 Spark UI 中 Stage 和 Task 分布是否均匀。
  • 内存稳定性测试: 连续提交 3 次催收跑批任务,观察 Executor 是否出现 OOM 或频繁 Full GC。
催收生产建议: 在正式上线前,建议使用催收历史数据(至少 7 天)进行压测,观察 Spark Shuffle 过程中是否存在数据倾斜。如果发现某个 Key 的数据量远超其他 Key(如某个催收员处理了 80% 的账单),需要在代码中引入 salting 或 repartition 策略。