ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

高校微博舆情分析系统实战:Hadoop+Spark+Hive全链路解析

高校微博舆情分析系统实战:Hadoop+Spark+Hive全链路解析 1. 项目概述与整体设计思路这阵子帮学校信息中心做了一个高校微博舆情分析系统技术栈正好是Hadoop Spark Hive Flask这套经典大数据组合。整体跑下来从数据采集到分析展示全链路打通所以打算把这次的项目经验完整梳理一遍尤其是那些文档里不写、只有真跑过才会遇到的坑都一并分享出来。系统本身要解决的问题很具体围绕校园相关的公开话题比如学生反馈、校园活动、学术交流、生活服务这些内容自动采集公开微博数据清洗后落地到Hadoop生态里用Spark做情感分析和趋势预测最后用Flask框架提供可视化接口前端通过大屏展示舆情热度排行、情感分布、话题演化等核心指标。目标用户是学校宣传部门和信息中心的老师他们需要的是每天扫一眼就知道“今天校园里大家在关心什么、情绪偏向如何、哪些话题上升得快”。有一件事需要提前说明如果你想把这个系统直接用去抓取并监控真实用户账号数据那既不合规也不符合平台规则。我们项目里用的是脱敏后的演示数据集和平台明确开放的公共接口来验证工程链路真正落地时数据侧需要单独走合规渠道这一点要放在架构设计之前想清楚。技术本身是中性的但数据来源和管理边界必须提前划好。技术方案选型我权衡了很长时间。最开始想用MySQL Python脚本跑定时任务就完事但仔细想想微博数据是典型的半结构化文本字段多且乱历史数据会持续膨胀每天新增量虽然单看不大但一个月、一个学期攒下来也有几个GB。再加上要做全量历史回刷和复杂聚合MySQL在这种场景下并不合适。Hadoop负责廉价的分布式存储Hive负责把数据仓库的维度建模和SQL查询做起来Spark则扛住每天的分析计算任务三个组件各司其职。Flask作为最快的Web框架把结果数据暴露成HTTP接口配ECharts做可视化大屏。系统整体分成四层采集层用Python爬虫抓取公开数据并做初步清洗存储计算层基于Hadoop HDFS和Hive构建离线数仓分析引擎层跑Spark任务输出情感分数、话题热度、预警指标等结果展示层用Flask搭建Web服务配合前端可视化。这四层之间的数据流是单向的爬虫只负责写Spark只负责算Flask只负责读结果表耦合度控制得比较低后续替换任何一层都不会牵连其他模块。架构设计上还有一点值得提我特意在Spark和Flask之间加了一层MySQL同步。很多人不理解既然Spark能直接从Hive表出结果Flask通过HiveServer2查不就行了实际开发中这样做会很痛苦。Hive查询延迟一般几秒甚至几十秒放在可视化接口上用户体验很差而且Spark任务和Flask接口并发访问HiveServer2时经常会出现会话和连接资源竞争。让Spark每天把计算结果写到MySQLFlask只负责读MySQL接口响应时间能稳定压在100毫秒以内这也是很多实际项目的通用做法。2. 数据采集层爬虫设计的细节与反爬处理2.1 采集策略选择采集模块是整个项目数据流的源头这个环节如果设计不好后面数仓和分析全部变成空转。我的做法是先梳理数据需求再确定抓取目标。系统分析的是高校话题所以关键词集合围绕“校园、课程、食堂、宿舍、社团、考研、就业”等词族展开每个关键词作为一个采集任务。技术选型上我没有直接上Scrapy而是用requests库自己实现了一个轻量调度器。原因有三点第一单个采集任务的数据量不大每次请求就能拿到分页数据Scrapy的并发抓取能力在这里属于杀鸡用牛刀第二Scrapy的中间件体系写起来比裸requests复杂在需要频繁调整请求头的场景下反而拖节奏第三requests配合线程池完全能满足这个项目每分钟几百条的采集需求代码可读性和维护成本都更友好。采集的数据字段主要包含微博ID、用户昵称、用户粉丝数、文本内容、发布具体到分钟的时间、点赞数、评论数、转发数、关联话题词。这9个字段已经足够支撑后续的热度计算和情感分析不需要额外冗余字段。原始数据统一以JSON格式落盘到本地暂存目录每满一定量就上传一次HDFS避免频繁的小文件写入。2.2 Cookie管理与反爬策略公开数据爬取最头疼的问题就是账号校验和请求频率控制。移动端接口相对PC端限制少一些但我还是建议先在PC端完成登录态校验再通过Cookie维持会话。项目里我把Cookie做了本地缓存采集前先检测Cookie是否过期如果请求返回的状态码是403或者跳转到登录页就触发一次手动扫码登录流程更新Cookie让采集进程自动恢复。真正的反爬规避重点在四点请求头伪装、访问频率控制、User-Agent轮换、代理池备用。请求头里必须带全Referer、Accept、Accept-Language这些字段很多反爬策略只看某个头缺失就直接拒绝。访问频率控制在每5到10秒发一次请求再配合3到5秒的随机sleep实测跑一整天不会触发风控。User-Agent轮换我准备了20来个常见浏览器的UA字符串每次请求随机抽取降低指纹特征。代理池是在单IP被限流时才需要的方案我给系统预留了代理池接口。具体实现是用一个队列维护代理IP列表请求失败时自动切换下一个代理重试连续失败3次就暂停采集任务并告警等一段时间再恢复。这里有个经验值得记下来不要试图用大并发去对抗限制舆情分析要的是持续稳定的数据流不是一次性把某天的数据抓完把采集任务平均分散到全天每个小时反而更不容易触发反爬数据的时间分布也更均匀。2.3 数据清洗与上传流程采集到的原始数据是很脏的特别是文本内容里充满了HTML标签、用户、短链接、表情符号和重复转发标记。清洗这一步放在Python里做而不是Spark里做能把实时处理压力前置消化掉。清洗流程包含去HTML标签与URL、过滤长度小于15的无意义文本、按发布时间的“小时”和“日期”生成分区字段、删除同一微博ID的重复记录。清洗完成后每5分钟做一个批次文件按日期和小时写入HDFS路径/data/weibo/raw/dt2025-01-15/hour08/这种格式。之所以要按dt小时双层分区是为了后续Hive查询能够做分区裁剪只扫描指定时间段的数据避免每次全表扫描。上传用HDFS自带的命令行工具即可也可以在Python代码里调用pyarrow但考虑到集群运维简单性最终选了Shell脚本加Crontab调度的方式。爬虫模块运行中有一个容易忽略的问题增量识别。同一关键词每次翻页接口返回的数据会有部分重叠如果不去重会导致Hive表里堆积大量重复数据。做法是启动时从Hive表查询最近一条已抓取微博ID只抓取晚于该ID时间线的增量数据。如果采集进程崩溃重启这个机制能保证不重不漏。3. 存储与数仓设计Hadoop集群搭建与Hive建模3.1 Hadoop集群搭建要点这里不推荐你在单机上用伪分布式跑整个系统因为Spark任务一旦跑起来单机的内存和磁盘很快会成为瓶颈。我们用的集群配置是1台Master节点加3台Worker节点每台机器8核16G内存500G磁盘。这套配置跑我们每天约200万条的数据量绰绰有余如果数据量再涨一个量级可以横向加Worker节点。集群搭建需要注意几个关键步骤。JDK版本选择OpenJDK 1.8不要用JDK 11以上版本很多Hadoop生态组件对高版本JDK兼容性并不好。Hadoop选择3.3.x版本这个版本对NameNode性能和RPC机制做了不少优化。配置core-site.xml时要重点关注fs.defaultFS指向NameNode的RPC地址hdfs-site.xml里设置3副本dfs.namenode.name.dir和dfs.datanode.data.dir必须指定独立的数据盘目录不要放在系统盘yarn-site.xml需要配置yarn.nodemanager.resource.memory-mb和yarn.scheduler.maximum-allocation-mb这两个参数决定Yarn能调度给Spark任务多少内存配置不对会直接导致Spark任务提交失败。初始化集群时有一个经典坑NameNode格式化后如果因为配置修改导致NameNode进程启动失败很多人会反复执行hdfs namenode -format这会清空所有元数据如果你的DataNode节点已经注册过格式化后会出现clusterID不一致DataNode进程起不来。正确做法是先检查日志确认报错原因确需重新初始化时要把各节点的data目录都清干净再统一格式化。3.2 Hive数仓建模实践Hive层分三张核心表遵循标准数仓的分层思路。ODS层直接映射HDFS原始数据表名ods_weibo_raw按日期分区存储原始文本和字段DWD层做清洗过滤表名dwd_weibo_clean剔除了无效数据ADS层是给分析和可视化直接用的结果表包括话题日统计、情感聚合等。DWD层建表我重点说一下Hive建表的几个关键设计。存储格式选Parquet而不是纯文本Parquet是列式存储在后续Spark按content字段做扫描时能减少大量I/O压缩格式选Snappy压缩比和编解码速度比较均衡。表按dt字符串字段做静态分区表结构通过PARTITIONED BY (dt STRING)声明。这里有个细节很多人踩过坑把分区字段写进普通字段列表里导致表数据写入时分区值错乱。分区字段必须在PARTITIONED BY中声明不要出现在常规列里。Hive执行引擎方面虽然没有强制要求但我建议用Tez引擎而不是默认的MapReduce。在hive-site.xml中设置hive.execution.enginetez配合hive.vectorized.execution.enabledtrue复杂查询速度能提升差不多3倍。Tez引擎对内存的消耗比MR稳定出现问题排查起来也容易定位。3.3 Hive优化手段实际运维中碰到最多的问题是数据倾斜和分区下小文件过多导致的NameNode压力。对每日采集的数据如果直接按小时分区写入每个小时分区只有几百MB但文件数却有几百个小文件。解决方案是在每次写入任务完成后手动执行一次文件合并把每个分区的文件合并成不超过5个左右的大文件。INSERT OVERWRITE TABLE dwd_weibo_clean PARTITION (dt${hiveconf:dt}) SELECT /* REPARTITION(4) */ weibo_id, user_name, content, publish_time, likes, comments, reposts, topic FROM ods_weibo_raw WHERE dt${hiveconf:dt};这段SQL里的REPARTITION(4)其实就是临时把数据重分区成4个文件输出数据量不大时这个方法比哪种高级方案都简单粗暴有效。执行完后检查一下分区文件数通常能控制在个位数。4. 核心计算引擎Spark分析与实操细节4.1 读取Hive表与数据预处理Spark分析任务是整个系统的核心增值点。我使用的是Spark SQL来接数仓的Hive表一个spark.read.table(dwd_weibo_clean)就能把表数据加载成DataFrame然后在Spark中完成分词、情感打分、热度计算和话题聚合。Spark能直接无缝读Hive表的原因在于Spark Session构建时启用了Hive支持注意提交任务时要把hive-site.xml和Hive依赖的jar打包进classpath否则会报无法解析表名的错误。数据预处理这一步主要是中文分词。词库我选的是HanLP它比jieba的功能更完整支持自定义词库和词性标注。由于接入的是校园场景语料需要先收集一批校园相关的专业词加入自定义词典比如“绩点、抢课、自习室、校园卡”这些词避免被分词器拆得支离破碎。分词完成后还需要做停用词过滤把“的、了、吗、啊”以及微博特有的“转发微博”这类无意义短语全部清洗掉。4.2 情感分析模型实现情感分析是整个系统中最能体现“舆情”价值的模块。我用的是词典打分 机器学习模型训练双路方案。词典方案速度快、可解释性强适合作为基础保底机器学习模型准确率更高适合对结果质量有要求时使用。词典方案的第一步是构建情感词库。网上有很多开源的中文情感词典比如知网情感词典和大连理工情感本体库把正负向情感词整理成两个集合。打分逻辑是将文本分词后计算每个句子中正向词数和负向词数的加权和再考虑否定词和程度副词的修饰。比如“不赞同”这个表达光是“赞同”一个正向词会被误判为积极情绪所以必须对否定词和程度副词做窗口检测。实现时用向前向后各三个词的窗口来扫描窗口内出现否定词就翻转词权出现“很、非常、极其”这类程度副词就对原始情绪得分加权倍数一般是1.5到2倍。词典方案是情感值范围映射到0到1之间的百分比得分大于0.6算正面小于0.4算负面中间为中性。对每条微博算完情感分数后按话题维度做聚合得到每个话题的正向占比、负向占比和整体情感倾向。如果希望情感判断更准一点可以引入机器学习模型。我把已经完成人工标注的约5万条微博文本拿来训练了一个逻辑回归分类器使用TF-IDF做特征向量嵌入到Spark MLlib的Pipeline里。逻辑回归虽然简单但在这个场景下确实够用准确率能到八成以上。训练流程是Tokenizer - HashingTF - IDF - LogisticRegression整个Pipeline保存后每次新数据流入就可以加载模型做批量预测。4.3 舆情预警与热度趋势预测光看情感还不够系统还要具备“预测”能力。这里说的预测分两层单条负面微博的扩散预测以及话题未来一天热度走势预测。第一层相对简单对负面情感分数超过阈值的微博结合其转发增速和评论增速计算一个预警分值。第二层我用了Spark MLlib的线性回归模型把过去14天每一天的话题热度值作为特征预测未来一天的热度值。虽然线性回归的精度在长周期预测上并不高但在短期趋势判断上它的稳定性足够支撑日常舆情监测需求。Spark SQL在里面发挥了一个非常关键的作用话题热度的计算逻辑极其依赖窗口函数。我定义热度 0.5 * 归一化(微博发布量) 0.3 * 归一化(互动量) 0.2 * 归一化(情感波动值)计算过程中需要对每条微博按话题分组再按时间排序计算参与人数和互动增量。这些操作直接用DataFrame API的窗口函数做效率远高于把数据抽出来用Python逐条处理。from pyspark.sql import SparkSession from pyspark.sql.functions import col, count, sum, row_number, concat, lit spark SparkSession.builder \ .appName(weibo_evaluation) \ .enableHiveSupport() \ .config(spark.sql.shuffle.partitions, 80) \ .getOrCreate() df spark.table(dwd_weibo_clean).filter(col(dt) partition_date) df.createOrReplaceTempView(weibo_temp) topic_stat spark.sql( SELECT topic, count(1) AS weibo_cnt, sum(likes comments reposts) AS interaction_cnt, avg(sentiment_score) AS avg_sentiment, dt FROM weibo_temp GROUP BY topic, dt ) topic_stat.write.mode(overwrite) \ .format(jdbc) \ .option(url, jdbc:mysql://localhost:3306/weibo_analysis) \ .option(dbtable, topic_daily_stat) \ .save()4.4 Spark任务提交与参数调优Spark任务提交的参数调优是一个项目从能跑到跑得稳的关键。下面是我经过多次调试后的一个稳定提交命令spark-submit \ --master yarn \ --deploy-mode client \ --driver-memory 2g \ --executor-memory 4g \ --executor-cores 2 \ --num-executors 6 \ --conf spark.sql.shuffle.partitions80 \ --conf spark.memory.offHeap.enabledtrue \ --conf spark.memory.offHeap.size2g \ --jars /opt/hive/lib/mysql-connector-java.jar \ /data/analysis_job.py这里参数确定的逻辑要说透。“executor-memory 4gexecutor-cores 2”意味着每个Executor上同时跑两个任务每个任务稳定获得约2G内存。如果数据量特别大shuffle阶段会需要额外内存所以开启offHeap并配置2G堆外内存能有效规避Executor内存溢出的问题。“spark.sql.shuffle.partitions”建议配置为核心数的10倍以上过小会导致每个任务处理的数据量过大过大则会产生大量小任务调度开销直接拖垮运行时间。我实测过一个数据量在200GB左右的分析任务用默认参数跑会出现偶发的Container killed把Executor内存提升到4G、开启堆外内存后任务运行稳定执行时间还缩短了将近四分之一。4.5 Spark读取Redis做实时缓存项目在后期发现每天有部分相同的热门话题会被多次重复查询频繁读写Hive很浪费资源。解决方案是把热话题Top100在每天分析完成后写入Redis缓存Flask查询时先查Redis如果命中就返回不命中再查MySQL。话虽如此这里必须注意不要在Spark任务内部直接对某个具体业务频繁写Redis因为Spark是分布式的不同Executor同时操作Redis会导致连接风暴。正确的方式是先用Spark的collectAsList()把Top100结果收集到Driver端再由Driver端统一使用Jedis连接池写入Redis。连接数控制在20个以内每条数据用一个管道命令批量发送写入时间非常短。同理读取侧由Flask线程维护自己的Redis连接不与Spark任务共享否则会连接数打满。5. 可视化服务Flask框架与前端大屏展示5.1 Flask后端接口设计Flask在整条链路中扮演轻量级数据服务角色它自己不用做任何分析计算只负责从MySQL或Redis读结果数据并按固定格式返回JSON。接口设计遵循RESTful风格按资源拆分接口路径方法功能说明/api/topic/rankGET查询当天话题热度TopN/api/emotion/trendGET查询近7天情感趋势数据/api/emotion/pieGET查询指定话题的正负情感占比/api/hotword/cloudGET获取词云接口数据/api/forecast/trendGET获取未来热度预测数据/api/alert/listGET查询预警记录列表接口统一带时间范围参数start_date、end_date和话题参数topic返回JSON结构固定包含code、message、data三层。Flask用Blueprint把路由模块化每个接口文件控制在100行左右这样后期加接口时不会整个文件变得臃肿。跨域问题用Flask-CORS解决在蓝图注册后统一加上CORS配置即可。写接口时有一个规范值得坚持不要在路由函数里直接拼SQL字符串而是把所有查询参数通过参数化查询的方式传入既是安全考量也让代码更好维护。所有接口的数据库连接要复用连接池不要在每次请求时新建连接用SQLAlchemy的连接池配置即可。5.2 可视化大屏方案前端展示部分我没有单独写前端项目而是用HTML ECharts直接嵌入到Flask的模板目录中。ECharts的折线图、饼图、柱状图、散点图和大屏适配刚好覆盖需求。核心页面一共四张大屏综合总览大屏展示当天话题Top10热度柱状图、24小时话题趋势折线图和整体情感饼图话题详情页展示单话题的情绪走势和关键词词云预警监控页用表格展示预警记录趋势预测页用双折线图展示历史实际值与未来预测值的对比。大屏和图表的数据不再是前端mock而是点击后通过fetch调用后端接口实时获取。页面初始化时加载当天数据定时器每隔10分钟自动刷新一次保证舆情监测的时效性。词云图我用了ECharts的wordcloud扩展包直接从接口返回的词语和权重对象数组渲染。词云图的关键在于后端返回的词语要预先做频次归一化前端直接用归一化后的值映射字体大小效果才好看。5.3 可视化过程中的响应性能优化开发期间遇到一个典型性能问题话题详情页的7天趋势接口在后端返回原始数据量较大时响应时间超过1秒。排查后发现MySQL没有为topic、dt这两个高频查询字段建联合索引。优化后加上索引接口响应时间降到100毫秒以下。另外Flask默认使用的是werkzeug的开发服务器并发能力差正式运行时我换成了gunicorn启动多个worker进程配合nginx做反向代理算是小型系统的标准部署方案。提示可视化层如果进一步优化还可以在Redis里为Top10话题的统计结果做缓存设置60秒过期让热点数据不会频繁打到MySQL上算是性价比很高的优化手段。6. 常见问题与排查技巧实录6.1 Hadoop相关故障Hadoop集群跑了一段时间后会遇到DataNode进程无故退出。最直接的排查方式是查看日志文件看是否出现磁盘空间不足或者是DataNode与NameNode的心跳中断。曾经遇到一次HDFS磁盘使用率达到95%之后系统进入安全模式不再接受新的数据写入。当时紧急扩容了DataNode的数据盘清理掉一部分临时文件和Spark作业的中间shuffle数据集群才恢复正常。Hadoop还有一个非常经典的元数据问题文件数过多导致NameNode内存溢出。这在小文件场景下特别容易出现。建议在Hive写入后强制做小文件合并同时设置HDFS的归档策略将超过30天的原始分区文件统一存储到冷目录。这些优化在项目上线两周后就要开始执行否则文件数增长会让NameNode越来越吃力。6.2 Spark常见报错处理Spark任务最常见的是OOM报错。如果报的是Executor OOM优先检查executor内存和shuffle分区数配置如果报的是Driver OOM通常是因为执行了collect操作把大量数据拉到本地这时要检查代码里是不是对超大DataFrame做了collect尽量改成分区级别的聚合操作。另一个高频问题是数据倾斜导致的某个task运行极慢。在我们项目中某个热门话题产生的数据占了全表的四成执行join操作时出现明显倾斜。解决办法是在join键后面加一个随机前缀把热点数据打散到多个reduce任务中处理然后再做一次二次聚合。虽然代码复杂度增加了但任务执行时间从48分钟下降到了9分钟效果立竿见影。6.3 Hive查询与执行问题Hive查询慢的最常见原因是默认全表扫描。如果在WHERE条件里没有过滤分区字段即使分区表设计得再好也会全表扫描。排查时可以用EXPLAIN查看执行计划确认是否命中了分区裁剪。还有一个容易忽略的是Hive中Map类型的Size函数使用问题。我们有一个字段存的标签用map格式查询某些标签的数量时直接访问map字段会报错。需要先使用size(kv_map_col)获取键值对数量再用map_keys获取key列表。类似这种复杂类型的操作在SQL里写起来不直观建议在Spark SQL里完成Python API对复杂类型的支持更友好。6.4 爬虫与Flask联调时的坑爬虫模块采集频率过快会导致后台采集IP被封从而影响整个数据链路的数据完整性。解决方式是加入熔断机制如果连续30分钟内同一关键词没有任何成功抓取记录自动追加更长的等待时间并给运维人员发送告警消息。Flask部分最容易出问题的是在开发调试时端口被占用。排查时用lsof -i :5000找出占用进程后kill掉再启动即可。另一个高频问题是MySQL连接数被耗尽因为每个接口都会新建连接没有显式关闭。统一改造成SQLAlchemy连接池后这个问题彻底解决。7. 系统部署与实际运行效果7.1 环境部署清单再详细梳理一下部署时需要准备的环境变量和依赖包照着这个清单检查能少走很多弯路组件版本备注JDKOpenJDK 1.8多版本共存时注意JAVA_HOMEHadoop3.3.4配置HDFS和YarnHive3.1.3使用Tez引擎Spark3.3.0开启Hive支持Python3.8爬虫与PySparkFlask2.2.x配合Gunicorn启动MySQL5.7存储结果表Redis6.x做查询缓存真正线上部署时建议把Hadoop集群部署成Ambari管理这样可以通过Web界面统一查看集群各节点状态做配置变更和告警管理也方便。但如果是学习环境或实验用途手动搭建一遍对理解各组件之间的关系更有帮助。7.2 运行指标分析系统跑通后曾经用一周的真实数据验证了整个链路。每天的转录数据量约120万条HDFS上一天产生约4GB原始数据。Spark从读取、清洗到情感分析、结果入库每日任务总耗时稳定在25分钟到35分钟之间。最耗时的环节是情感词典打分因为需要对整周的文本做全量扫描。如果将计算频率从日更改成小时更就需要考虑用Kafka构建实时处理链路这属于后续扩展方向。可视化的维度很关键。我根据用户反馈逐渐把页面收敛成“洞察”导向不只是堆数字而是将情感趋势的异常波动和高热度负向话题高亮突出再配上前一天的对比升降幅。这种“能快速回答所谓舆情的现在和下次要关注什么”的业务功能才是真正被高频使用的模块。8. 实操心得与进一步扩展建议这个项目从零开始到核心功能跑通大概用了一个多月。梳理下来我想提炼几个对做同类项目的人有实际帮助的开发心得。第一个心得大数据项目的价值不在于用多先进的组件而在于把每层组件的职责边界划清楚。Hadoop管存储、Hive管仓库建模、Spark管算力、Flask管服务每一层都只做自己最擅长的事。过度设计是我在整个过程中反复提醒自己的点比如明明不需要实时流处理就没必要强行引入Kafka和Flink。第二个心得日志和监控体系必须在项目初期就搭建不要等项目跑通了再补。我在每个关键环节都打印了统计日志DataX同步文件数、Hive写入行数、Spark聚合后的条数、Flask接口响应耗时统统记录下来。否则数据出了问题只能从头排查效率特别低。第三个心得对于情感词库打分模型不要期望它一次就达到满意的效果。要根据校园语料的实际情况持续扩充专有词库比如一些网络新词和校园梗如果不及时收录模型对相关内容的判断就会失准。建议每周固定一个时间段从当周新增的负面内容中抽出误判样本做迭代效果提升很快。这个系统其实还有不少可以扩展的方向。架构上预留的Kafka接入位置可以引入实时采集通道把舆情监控的粒度从每日提前到分钟级。分析层面可以引入BERT之类的预训练模型做更细粒度的情感分类。可视化上也可以接入更多高校的公开数据做横向对比。不过这些都是项目稳定之后的事了。最后说一个长远的数据存储策略日增量数据在HDFS上保留近90天即可超过90天的历史数据可以用Hive的归档功能压缩存储保留一年以上。分析任务如果只查最近7天就直接走MySQL结果表只有做学期级对比研究时才会回刷Hive历史数据。这个分层访问模式既能控制成本也能保持查询效率算是我在实际运维中总结出来的最佳平衡。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进