用 Spark Shell 做交互式数据分析从入门到自包含应用

为什么用 Spark Shell?

Spark Shell 既是学习 API 的最短路径 ,也是探索数据的强大交互工具。你可以在 Shell 里反复尝试、立即验证,然后把验证过的代码拷进正式作业或应用。

  • 支持 Scala(运行在 JVM,上手 Java 生态很方便)
  • 支持 Python(PySpark)(语法简洁、数据科学生态友好)

环境与启动方式

方式 A:使用 Spark 自带脚本

bash 复制代码
# Python
./bin/pyspark

# Scala
./bin/spark-shell

方式 B:已通过 pip 安装 PySpark(推荐给数据科学/本地开发)

bash 复制代码
pip install pyspark
pyspark

小贴士:

  • 指定 Python 解释器:

    bash 复制代码
    export PYSPARK_PYTHON=python3
  • 指定 Spark 路径(必要时):

    bash 复制代码
    export SPARK_HOME=/path/to/spark

Spark 的核心抽象:Dataset / DataFrame

  • Dataset:分布式元素集合。
  • Python 中,由于动态类型特性,实际使用的是 Dataset[Row] ,通常直接称为 DataFrame(与 Pandas/R 的 DataFrame 概念一致)。

读取文本为 DataFrame

python 复制代码
textFile = spark.read.text("README.md")  # 每行一条记录,列名为 "value"

常用 action

python 复制代码
textFile.count()   # 行数
textFile.first()   # Row(value='...')

过滤与链式调用

python 复制代码
linesWithSpark = textFile.filter(textFile.value.contains("Spark"))
linesWithSpark.count()  # 例如 15

# 链式:过滤后直接计数
textFile.filter(textFile.value.contains("Spark")).count()

复杂一点:统计"每行最大词数"

关键修正 :在 PySpark.alias("...")(而非 .name("...")),并使用原始字符串 表达正则 r"\s+",避免转义歧义。

python 复制代码
from pyspark.sql import functions as F

result = (
    textFile
      .select(F.size(F.split(F.col("value"), r"\s+")).alias("numWords"))
      .agg(F.max(F.col("numWords")).alias("max_numWords"))
      .collect()
)
result  # [Row(max_numWords=15)]

MapReduce 风格:做一次词频统计(Word Count)

python 复制代码
from pyspark.sql import functions as F

wordCounts = (
    textFile
      .select(F.explode(F.split(F.col("value"), r"\s+")).alias("word"))
      .where(F.col("word") != "")         # 可选:剔除空字符串
      .groupBy("word")
      .count()
)

# 看看 Top 20
wordCounts.orderBy(F.col("count").desc()).show(20, truncate=False)

# 也可以落到磁盘/HDFS
# wordCounts.write.mode("overwrite").csv("/tmp/wordcounts")

缓存与性能:cache / persist

当数据会被重复访问 (比如小而热的数据集,或 PageRank 这类迭代算法),把它放进集群级内存缓存会极大提高效率。

python 复制代码
linesWithSpark.cache()   # 默认 MEMORY_ONLY
linesWithSpark.count()   # 触发计算并物化缓存
linesWithSpark.count()   # 再次访问会更快

# 指定存储级别(当数据较大时有用)
from pyspark.storagelevel import StorageLevel
linesWithSpark.persist(StorageLevel.MEMORY_AND_DISK)

实用调试:

python 复制代码
linesWithSpark.explain()              # 物理/逻辑执行计划
wordCounts.explain("formatted")       # 更友好的格式(Spark 3+)

自包含应用:用 PySpark 编写并运行

如果你在做打包的 PySpark 应用/库 ,可以在 setup.py 里声明依赖:

python 复制代码
install_requires = [
    "pyspark==4.0.1"  # 按你的实际版本固定
]

示例:SimpleApp.py

python 复制代码
# SimpleApp.py
from pyspark.sql import SparkSession
from pyspark.sql import functions as F

def main():
    logFile = "YOUR_SPARK_HOME/README.md"  # 替换为实际文件路径
    spark = SparkSession.builder.appName("SimpleApp").getOrCreate()

    df = spark.read.text(logFile).cache()

    numAs = df.filter(F.col("value").contains("a")).count()
    numBs = df.filter(F.col("value").contains("b")).count()

    print("Lines with a: %i, lines with b: %i" % (numAs, numBs))

    spark.stop()

if __name__ == "__main__":
    main()

运行方式

首选:spark-submit

bash 复制代码
$ ${SPARK_HOME}/bin/spark-submit \
  --master "local[4]" \
  SimpleApp.py

# 输出示例:
# Lines with a: 46, lines with b: 23

如果已用 pip 安装 PySpark(可直接用 Python 运行):

bash 复制代码
$ python SimpleApp.py
# Lines with a: 46, lines with b: 23

引入第三方代码/依赖时,可用 --py-files 传入 zip 包;引入连接器/JAR 时可用:

bash 复制代码
spark-submit --packages groupId:artifactId:version SimpleApp.py

去哪里继续深入?

  • RDD 编程指南Spark SQL 编程指南:系统理解 API 与最佳实践

  • 部署指南:把应用跑在真实集群(Standalone / YARN / Kubernetes)

  • examples 目录 含多语言示例:

    bash 复制代码
    # Python
    ./bin/spark-submit examples/src/main/python/pi.py
    
    # Scala / Java
    ./bin/run-example SparkPi
    
    # R
    ./bin/spark-submit examples/src/main/r/dataframe.R

常见坑与实战建议(强烈建议一读)

  1. PySpark 别用 .name(...) → 用 .alias("...")
  2. 正则用原始字符串r"\s+",避免 "\s" 被当作普通 s
  3. 谨慎 collect() → 仅用于小结果;大结果用 show()/take(n) 或直接写出到存储。
  4. 只缓存"热数据" → 先 explain() 看执行计划、用 UI 观察 DAG 与缓存命中,不要"见谁 cache 谁"。
  5. 路径要清晰 → 本地绝对路径 vs HDFS/S3 URI(hdfs://s3a://)。
  6. 并行度与分区repartition(n) 提升 shuffle 后并行度;小结果落盘可 coalesce(1) 合并为单文件(仅适用于小数据)。
  7. 版本统一 → PySpark 版本与集群 Spark 版本尽量匹配,避免协议/计划不兼容。
相关推荐
JZC_xiaozhong40 分钟前
主数据同步失效引发的业务风险与集成架构治理
大数据·架构·数据一致性·mdm·主数据管理·数据孤岛解决方案·数据集成与应用集成
T06205141 小时前
【数据集】全国各地区教育139个相关指标数据集(2000-2024年)
大数据
故乡de云1 小时前
Vertex AI 企业账号体系,Google Cloud 才能完整支撑
大数据·人工智能
汽车仪器仪表相关领域1 小时前
AI赋能智能检测,引领灯光检测新高度——NHD-6109智能全自动远近光检测仪项目实战分享
大数据·人工智能·功能测试·机器学习·汽车·可用性测试·安全性测试
木头程序员1 小时前
大模型边缘部署突破:动态推理技术与精度-延迟-能耗帕累托优化
大数据·人工智能·计算机视觉·自然语言处理·智能手机·数据挖掘
DX_水位流量监测1 小时前
无人机测流之雷达流速仪监测技术分析
大数据·网络·人工智能·数据分析·自动化·无人机
鹿衔`1 小时前
Hadoop HDFS 核心机制与设计理念浅析文档
大数据·hadoop·hdfs
萤丰信息2 小时前
开启园区“生命体”时代——智慧园区系统,定义未来的办公与生活
java·大数据·运维·数据库·人工智能·生活·智慧园区
TDengine (老段)2 小时前
TDengine Rust 连接器进阶指南
大数据·数据库·物联网·rust·时序数据库·tdengine·涛思数据
YangYang9YangYan2 小时前
中专大数据技术专业学习数据分析的价值分析
大数据·学习·数据分析