暑假生活周报8

这周总算把学习重心从Hadoop的MapReduce转移到了Spark上,这一对比,感觉像是从绿皮火车换成了高铁,开发效率的提升不是一点半点,但新框架带来的新挑战也一点没少。

时间上还是花了大概三十多个小时,其中差不多十个小时都耗在了搭建环境和跑通第一个Spark应用上。虽然Spark能跑在之前搭好的Hadoop YARN上,省去了独立部署集群的麻烦,但光是把Spark包下载下来,配置SPARK_HOME、HADOOP_CONF_DIR这些环境变量,就反复确认了好几遍,生怕路径写错导致提交任务时找不到依赖。第一次用spark-submit往YARN上提交一个简单的WordCount任务时,控制台报了一堆看不懂的错,什么Exit code: 13,什么Unable to load native-hadoop library,翻了好久日志和文档才发现是本地装的Hadoop和Spark版本有点兼容性问题,最后重新下载了匹配的版本才解决。

剩下的二十多个小时主要花在了理解和实践Spark的核心概念上。最大的惊喜是Spark SQL,用DataFrame API操作数据真的太流畅了。同样一个按用户分组统计访问次数的需求,之前用Hive写SQL或者用MapReduce写Java代码都得折腾一会儿,现在用Spark Scala版几行代码就搞定了:
val df = spark.read.orc("hdfs://path/to/logs")
df.groupBy("user_id").count().show()

这种开发体验上的提升让人印象深刻,尤其是链式调用的写法,写起来非常顺手。不过,性能调优的复杂性一点也没减少。虽然不用再手动管Map和Reduce任务了,但得开始琢磨RDD的持久化(persist) 应该选MEMORY_ONLY还是MEMORY_AND_DISK_SER,得关注shuffle时的分区数设置合不合理,spark.sql.shuffle.partitions这个参数调大了容易产生大量小任务,调小了又可能让个别任务负载过重。有一次因为没做好持久化,同一个中间RDD在同一个作业里被重复计算了三次,作业运行时间直接翻倍,直到看了Spark UI的DAG图才恍然大悟。

遇到的问题也很“经典”。首先是API的学习曲线,虽然比MapReduce简单,但RDD、DataFrame、DataSet这几个概念的关系和转换一开始还是有点绕,什么时候该用map,什么时候该用select,得反复试。其次是资源调优,在YARN上跑Spark,不光要设Spark自己的executor-memory、executor-cores,还得和YARN的yarn.scheduler.maximum-allocation-mb等参数匹配,不然资源申请可能直接被YARN拒绝。最头疼的依然是调试,虽然Spark UI比MapReduce的UI直观多了,能清晰看到每个Stage的耗时、数据倾斜在哪,但一旦遇到数据序列化错误或者OOM,堆栈信息依然又长又难懂,得慢慢扒日志。

总的来说,这周的学习让我彻底明白了为什么Spark能成为大数据领域的主流选择——开发体验和执行效率的提升是实实在在的。虽然深入下去同样复杂,但至少写代码的时候更愉快了。下一步打算继续深入Spark,看看Structured Streaming是怎么做流处理的,再试试能不能把它和Kafka连起来,实现一个更实时的数据处理流程。

posted @ 2025-09-06 20:06  仙人兵马俑  阅读(9)  评论(0)    收藏  举报