天气预测系统实战:从爬虫到Hadoop+Spark+Hive的机器学习全流程
做大数据课程设计或者毕业设计,很多人都会选天气预测这个方向。但真正动手的时候才发现,从数据采集到模型上线,中间隔着好几座山:爬虫怎么写才不会封IP,Hadoop集群怎么搭才稳定,Hive怎么建表才高效,Spark的机器学习库到底怎么调用——每一步都是坑。我最近刚好完整做完了一个基于Hadoop+Spark+Hive的天气预测系统,从数据爬虫到可视化大屏走通了全流程,这里把整个项目的技术选型、架构设计、核心代码和踩坑记录完整整理出来,希望能给正在做类似项目的朋友一些参考。
这个系统做的事情并不复杂:定时从公开气象网站爬取历史气象数据,存储到Hadoop HDFS上,用Hive做数据清洗和特征宽表构建,再用Spark MLlib的线性回归算法训练模型,预测未来某一天的最高温度、最低温度、降雨概率等指标,最后把预测结果和真实数据放到大屏上做可视化对比。整套系统跑通了离线数仓的完整链路,也可以当作一个mini版的气象数据平台来理解。
1. 整体架构设计与技术选型思路
1.1 系统架构全景
这个项目本质上就是一个完整的大数据离线处理链路。数据从外部采集进来,经过存储、清洗、建模、训练、预测、展示六个环节。我画了一张架构图(基于常见离线数仓标准架构实现),整个链路如下:
- 数据采集层:Python爬虫定时抓取气象数据,包括逐小时温度、湿度、气压、风速、风向、降水量、天气现象等原始数据,同时把爬虫采集到的数据实时写入HDFS指定目录。
- 数据存储层:Hadoop HDFS作为底层分布式存储,存放所有原始日志和清洗后的中间数据。Hive建立在HDFS之上,以SQL方式管理数据仓库表。
- 数据计算层:Hive负责ETL和数据清洗,Spark负责特征工程和模型训练。两个引擎通过Hive元数据服务共享同一个数据仓库。
- 数据应用层:Spring Boot提供后端服务,ECharts做可视化大屏展示,展示历史数据趋势、预测曲线和模型评估指标。
设计这套方案的时候,我特意把数据采集和数据处理拆开,爬虫进程和Spark任务互不干扰,即使某个环节挂了,其他模块照常运行。这也是工程化项目比较稳妥的做法——模块解耦,故障隔离。
1.2 为什么选线性回归而不是更复杂的算法
标题里明确要求用线性回归,这里也顺便解释一下这个选择的合理性。气象预测领域,虽然深度学习模型(LSTM、Transformer)效果更好,但线性回归依然有它的价值:
- 可解释性强:线性回归的每个特征对应一个权重系数,可以直观看出温度、湿度、气压对预测结果的影响方向,对初学者理解机器学习非常有帮助。
- 训练成本低:Spark MLlib实现线性回归只用了不到20行代码,模型训练在本地伪分布式集群上几分钟就能出结果。
- 基线模型价值:在实际工程项目里,先跑一个线性回归做baseline,再决定要不要上更复杂的模型,这是非常标准的流程。
1.3 数据流向设计
整个系统的数据流是单向串行的。每天凌晨2点,调度器触发当天的数据采集任务;采集完成后,Hive定时任务开始执行ETL,把原始数据从ODS层清洗到DWD层;接着Spark任务读取DWD层数据做特征工程;最后模型训练完成,预测结果写回Hive的ADS层。这个流程清晰简单,也是离线数仓最经典的层次划分——ODS原始数据层、DWD明细数据层、ADS应用数据层。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与大数据组件安装
2.1 Hadoop集群搭建与伪分布式部署
这里给新手一个建议:如果你的机器配置一般(8G内存以下),先不要折腾三节点集群,伪分布式足够跑通全流程。我用的就是单机伪分布式模式,Hadoop版本选的3.3.6,安装路径放在/usr/local/hadoop,JAVA_HOME配置好之后,主要操作就三步:配置core-site.xml、hdfs-site.xml、yarn-site.xml三个核心文件,然后执行hdfs namenode -format初始化,最后用start-dfs.sh和start-yarn.sh启动即可。
xml复制<!-- core-site.xml -->
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
</configuration>
<!-- hdfs-site.xml -->
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/usr/local/hadoop/tmp/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/usr/local/hadoop/tmp/data</value>
</property>
</configuration>
注意:伪分布式模式下dfs.replication必须设为1,否则数据块会一直处于等待副本的状态。我第一次搭的时候忘了改这个参数,上传文件后等了半天副本数一直是1/3,后来检查才发现问题出在这里。
启动完成后执行jps命令,能看到NameNode、DataNode、SecondaryNameNode、ResourceManager、NodeManager五个进程说明Hadoop跑起来了。这一步也是面试高频考点,我在hadoop面试题库里见过无数次——Hadoop启动后有哪些进程,各自的作用是什么。
2.2 Hive安装与MySQL元数据库配置
Hive的安装相对简单,只需要把Hive解压到指定目录,配置hive-site.xml。关键点在于元数据存储方式。默认的Derby内嵌模式只适合测试,无法支持多用户并发访问,而且元数据存在临时目录里,重启就丢了。我直接用了MySQL存储元数据,配置步骤如下:
sql复制-- 在MySQL中创建hive用户和数据库
CREATE DATABASE hive_metastore DEFAULT CHARACTER SET utf8;
CREATE USER 'hive'@'%' IDENTIFIED BY 'hive123';
GRANT ALL PRIVILEGES ON hive_metastore.* TO 'hive'@'%';
FLUSH PRIVILEGES;
然后把mysql-connector-java的jar包放到Hive的lib目录下,在hive-site.xml里配置好连接地址。有个细节注意:Hive 3.x版本不再自动初始化数据库表结构,需要手动执行schematool -dbType mysql -initSchema完成初始化。
启动Hive之后,可以通过hive命令进入交互式终端,也可以直接用beeline连接HiveServer2。实际项目里我是用beeline方式,因为调度脚本里可以通过JDBC方式连接Hive执行SQL,更方便自动化。
2.3 Spark环境配置与Hive集成
Spark是这套系统里最关键的组件。我用的Spark版本是3.4.1,需要注意的坑是:如果Hadoop是3.x,必须用Spark 3.0以上版本,否
