做谛听这个项目,起因挺朴素:当时公司销售每天早上第一件事就是翻标讯网站,靠肉眼从几十页招标公告里筛跟自己业务相关的项目,结果一个季度下来,还是漏掉了同城竞对拿下的一个千万级标。老板拍桌子问,为什么别人能提前两个月布局,我们连投标机会都看不到。我也答不上来,因为那会儿连数据都没有,所有判断都靠销售的个人经验和运气。
后来我把全国各地的公开招标公告、中标结果、采购意向这些数据全部扒下来,存进集群,用Spark做离线分析,再用avue-data搭了一套可交互的大屏,内部代号就叫“谛听”。它的定位从一开始就很明确:不是帮你去查某一条标讯,而是用大数据的方式,把一个区域的招标热度、一个行业的采购移动、一群竞争对手的关系网,用一张屏全部摊开。这篇文章就把整套思路和落地过程完整复盘一遍,包括三个维度的定义逻辑、avue-data大屏的选型与部署、数据采集清洗链路,以及上线后踩过的那些坑。
1. 为什么把招投标数据做成“谛听”——先想清楚三件事
1.1 单项标讯是情报,批量标讯才是大数据
单看一条招标公告,它就是一条公开信息,价值有限。但把过去几年全国几千万条招标公告、中标结果、合同公示放一起,情况完全不一样:你能看到某个地区的采购盘子是在变大还是萎缩,某个行业的招标方式是在线上化还是线下化,某家竞争对手最近三个月在哪些区域密集出货。这些信息单条看毫无感觉,叠加起来就是商业视野。
这也是“谛听”名字的由来——不是去听某一条消息,而是持续监听整个市场的底层动静,把普通人不关注的“背景噪音”变成可量化的信号。招投标数据天然适合干这件事,因为它是结构化程度最高的公开商业数据之一,有招标人、中标人、项目名称、金额、时间、地域、行业这些标准字段,不需要做太多非结构化处理就能进分析链路。
1.2 做这套系统前,我先问了三个问题
项目立项的时候没有急着写代码,先把业务需求聊透了。当时问了三个问题,现在回头看,这三个问题基本决定了整个系统的边界:
第一,谁在用这套系统?销售想看机会,老板想看格局,运营想看趋势,三方诉求完全不一样。销售要的是“今天有什么标跟我相关”,老板要的是“这个季度哪些区域值得加人”,运营要的是“哪些行业的采购活跃度在上升”。如果一套系统想把三个角色全服务好,大概率会做成一个四不像。
第二,数据准确度要到什么程度?标讯数据天然有噪音,公告撤回、金额变更、重复发布都很常见。如果追求每条数据百分百准确,采集清洗成本会高到没法上线;如果完全不管质量,大屏上的数字就是骗自己。最后定的原则是:展示趋势的数据允许一定误差,推送销售的具体标讯必须高准召。
第三,实时性要求多高?销售跟进线索当然是越快越好,但采购意向到正式公告之间本身就有滞后,没必要做到秒级。最终定的是半小时轮询一次增量数据,大屏上看到的数字延迟不超过30分钟,完全够用。
1.3 大数据的“大”不是数据量大,是维度多
这个项目做下来最大的体会是,招投标数据的核心价值不在“量”而在“联”。一条招标公告只能告诉你某个医院要采购一套系统,但把它和同区域其他医院的采购记录关联起来,你可能就会发现这个区域正在做一轮信息化改造,后面还会有一连串机会。这种“从单点到全局”的推导能力,才是大数据技术在这个场景里真正的用武之地。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 三大维度重构:区域、行业、竞争图谱怎么从数据里长出来
2.1 维度一:区域格局——钱在往哪里流动
区域维度解决的是“市场在哪”的问题。我们把全国按省级行政单位划分,对每个区域的招标数量、招标总金额、平均单项目金额、同比增长率做统计,再落到地图热力图上。
实际操作中,单纯看招标总额有个陷阱:某省一个数百亿的 mega 项目会把全省数据拉高,看起来热得不行,实际上普通企业根本吃不到。后来增加了两个辅助指标:项目数量中位数和中小金额项目占比,用来过滤“大盘子、小机会”的虚胖区域。
区域维度真正发挥作用是在销售资源配置上。以前华南大区要不要加人,靠区域总监拍脑袋,现在直接看数据:过去三个季度华南的招标项目数连续环比增长,且教育行业占比显著上升,那招一个懂教育的销售就有据可依。大屏上这个维度用地图展示,点击某个省份可以下钻到市级,再点能看到该区域最近一个月的标讯列表。
2.2 维度二:行业风向——采购需求在往哪个方向迁移
行业维度解决的是“机会在哪”的问题。我们参照国民经济行业分类,对招标公告做了行业映射。这里有个很关键的处理:很多公告标题里不会直接出现标准行业名称,写的是“某某医院信息化升级改造项目”,需要靠招标人名称和项目描述一起判断,才能归到“医疗卫生”还是“软件和信息技术服务”。
行业维度的核心指标有两个:行业招标总额趋势和行业采购结构变化。前者用来判断大方向,后者用来发现细分机会。举个实际例子,数据分析显示某传统制造行业的招标量在下降,但“智能化改造”相关关键词的出现频率在快速上升,说明整个行业正在从硬件采购转向软件和服务采购,这就是产品团队调整方向的直接依据。
大屏上这个维度用环形图和折线图组合展示:外环是当前季度各行业占比,内环是上一季度占比,折线则展示选定行业过去12个月的趋势,能直观看到行业的冷热转换。
2.3 维度三:竞争图谱——谁在跟你抢同一块蛋糕
竞争维度是最有意思、也是挖起来最深的一个维度。我们把中标结果数据按照中标人维度聚合,计算每家企业在各区域、各行业的活跃度和中标率,再分析招标人和中标人之间的历史关系网络。
这里说的“关系网络”不是查某两家公司有没有关联关系,而是看数据上的行为模式:某业主单位过去两年发的标,超过60%都被同一家企业中标,那这个业主就是那家企业的基本盘,新玩家想进去难度很大;反过来,如果某业主的标的分散在七八家中标人手里,说明这个口子还没被锁定,是新机会。
大屏上这个维度用关系图展示,节点是招标人和中标人,连线表示有过中标记录,连线的粗细代表合作频次,颜色深浅代表最近一次合作的时间远近。关系图这个可视化组件在avue-data里没有现成的,是集成了ECharts的关系图后自己调的配置,后面详细说。
2.4 为什么是这三个维度,而不是更多
项目启动时列过十几个分析维度,包括招标方式分布、评标办法偏好、代理机构活跃度、保证金政策变化等等,最后砍到只剩三个。原因是这三个维度对应了企业最关心的三个问题:去哪里卖、卖什么、谁能卖得过。其他维度不是没用,而是对“一张屏看懂江湖”这个目标来说,属于锦上添花,放上去反而干扰核心信息。
这个取舍逻辑后来证明是对的。业务部门看大屏的时候,只需要在这三个维度之间切换,不需要理解复杂的数据模型,上手成本极低。
3. 一张屏的落地:avue-data选型与部署实操
3.1 为什么在众多大屏方案里选了avue-data
大屏前端方案当时比选了好几个:DataV、ECharts定制、React系的开源大屏模板,以及avue-data。最终选avue-data的原因有三点:
第一,它基于Vue,和团队现有技术栈一致,不用为了一个大屏单独引入一套React体系。第二,avue-data内置了丰富的图表组件和边框装饰,特别是对ECharts的封装做得比较友好,配置项可以直接透传,灵活性够。第三,它是纯前端的可视化编辑器,部署就是一个静态站点加一个接口服务,不依赖重量级后端框架,运维成本低。
当时也考虑过DataV,但DataV的定制性相对弱一些,而且商业版收费,开源版功能有限。avue-data的社区活跃度不错,遇到问题基本都能搜到解决方案。
3.2 大屏视觉设计与布局的实操细节
大屏的分辨率按1920乘1080设计,这个没什么好说的,关键是布局。我们用的是经典的三栏结构:中间主视觉区放全国地图热力图,左侧放区域榜单和行业占比,右侧放竞争关系图和实时标讯滚动列表。底部一条横向的指标卡,展示全平台今日新增标讯、今日招标总额、本月累计项目数等核心数字。
布局上最需要注意的问题是信息密度。第一版大屏把所有能放的指标全塞进去了,结果就是满屏数字,谁看都晕。后来狠心砍掉了将近一半的展示项,每个区域只保留一个核心图表加一个辅助指标,才算是“一张屏能看懂”。
avue-data在实现层面帮了大忙,它把常见的边框、标题栏、轮播表、翻牌器都封装好了,直接用组件拼接就能搞定80%的静态界面。真正花时间的是ECharts的定制配置,比如地图热力图的颜色渐变、关系图的力导向布局参数、折线图的平滑曲线和阈值线标注。
3.3 大屏前端怎么部署——avue-data的生产环境之路
avue-data生成的工程本质上是一个Vue项目,构建后产物是一堆静态文件,部署方案就很简单:Nginx托管静态资源加反向代理后端接口。
具体的Nginx配置有几个关键点:大屏的接口服务单独配一个/api前缀的location,代理到后端的Java服务;静态资源开启gzip压缩,因为大屏引用的ECharts和地图GeoJSON文件体积不小;配置了try_files指令,保证前端路由在刷新时不出现404。
服务器配置这块,最开始用一台2核4G的ECS跑Nginx加后端接口,发现大屏首次加载要3到4秒,主要是地图GeoJSON文件和ECharts体积太大。优化方案是:地图GeoJSON按需加载,只加载全国和省级数据,市级数据在点击下钻时才请求;ECharts用按需引入的方式,只打包用到的组件,首屏体积直接从2MB降到了600KB左右,加载时间控制在1秒内。
code复制
# user\-a 提问:
项目标题: "谛听招标大数据:三大维度重构商业视野,一张屏读懂招投标江湖"
项目正文: ""
关键词: ""
摘要描述: ""
相关热搜词:大数据
最新网络热词:大数据,数据科学与大数据技术就业方向,大数据面试题,太原师范学院大数据专业分配宿舍在那层楼,大数据集群部署策略,avue-data数据大屏前端是怎么部署的,包子ai大数据,大数据组件dinky下载,大数据平台,如何用java编写spark处理日志的大数据例子,大数据架构,对于大数据而言,最基本、最重要的要求就是减少错误、保证质量。那么,大数据收集的,数据科学与大数据技术,广州大彩串口屏往数据记录控件添加一条内容添加不全,mathorcup大数据竞赛
我需要补全这篇文章。刚才我已经生成了前三个章节的部分内容,现在需要继续补充后续章节。刚才的回复因被截断,需要继续。
让我查看一下我已有的内容:
- 开头
- 第1章(为什么把招投标数据做成“谛听”——先想清楚三件事)
- 第2章(三大维度重构:区域、行业、竞争图谱怎么从数据里长出来)
- 第3章的一部分(avue-data选型与部署实操,还没写完)
现在需要继续写第3章的剩余内容,然后写第4章(数据链路治理)和第5章(复盘)。
由于我已经写了第1、2章,第3章部分,我需要在此基础上继续。但当前输出应该是一篇完整的文章。考虑到之前的输出已经被截断,我需要重新组织输出一篇完整的文章,从开头写到底,确保包含所有章节。
让我重新组织完整内容,并根据要求确保5000字以上。
重新规划章节:
- 开头
-
- 为什么把招投标数据做成“谛听”——先想清楚三件事
-
- 三大维度重构:区域、行业、竞争图谱怎么从数据里长出来
-
- 一张屏的落地:avue-data选型与部署实操
-
- 数据链路治理:采集、清洗、Spark离线与Dinky实时的配合
-
- 复盘:谛听上线三个月,哪些指标真正被用起来了
让我把之前写的内容和后面要写的内容合并成一篇完整文章输出。做谛听这个项目,起因挺朴素:当时公司销售每天早上第一件事就是翻标讯网站,靠肉眼从几十页招标公告里筛跟自己业务相关的项目,结果一个季度下来,还是漏掉了同城竞对拿下的一个千万级标。老板拍桌子问,为什么别人能提前两个月布局,我们连投标机会都看不到。我也答不上来,因为那会儿连数据都没有,所有判断都靠销售的个人经验和运气。
后来我把全国各地的公开招标公告、中标结果、采购意向这些数据全部扒下来,存进集群,用Spark做离线分析,再用avue-data搭了一套可交互的大屏,内部代号就叫“谛听”。它的定位从一开始就很明确:不是帮你去查某一条标讯,而是用大数据的方式,把一个区域的招标热度、一个行业的采购移动、一群竞争对手的关系网,用一张屏全部摊开。这篇文章就把整套思路和落地过程完整复盘一遍,包括三个维度的定义逻辑、avue-data大屏的选型与部署、数据采集清洗链路,以及上线后踩过的那些坑。
1. 为什么把招投标数据做成“谛听”——先想清楚三件事
1.1 单项标讯是情报,批量标讯才是大数据
单看一条招标公告,它就是一条公开信息,价值有限。但把过去几年全国几千万条招标公告、中标结果、合同公示放一起,情况完全不一样:你能看到某个地区的采购盘子是在变大还是萎缩,某个行业的招标方式是在线上化还是线下化,某家竞争对手最近三个月在哪些区域密集出货。这些信息单条看毫无感觉,叠加起来就是商业视野。
这也是“谛听”名字的由来——不是去听某一条消息,而是持续监听整个市场的底层动静,把普通人不关注的“背景噪音”变成可量化的信号。招投标数据天然适合干这件事,因为它是结构化程度最高的公开商业数据之一,有招标人、中标人、项目名称、金额、时间、地域、行业这些标准字段,不需要做太多非结构化处理就能进分析链路。
1.2 做这套系统前,我先问了三个问题
项目立项的时候没有急着写代码,先把业务需求聊透了。当时问了三个问题,现在回头看,这三个问题基本决定了整个系统的边界:
第一,谁在用这套系统?销售想看机会,老板想看格局,运营想看趋势,三方诉求完全不一样。销售要的是“今天有什么标跟我相关”,老板要的是“这个季度哪些区域值得加人”,运营要的是“哪些行业的采购活跃度在上升”。如果一套系统想把三个角色全服务好,大概率会做成一个四不像。
第二,数据准确度要到什么程度?标讯数据天然有噪音,公告撤回、金额变更、重复发布都很常见。如果追求每条数据百分百准确,采集清洗成本会高到没法上线;如果完全不管质量,大屏上的数字就是骗自己。最后定的原则是:展示趋势的数据允许一定误差,推送销售的具体标讯必须高准召。
第三,实时性要求多高?销售跟进线索当然是越快越好,但采购意向到正式公告之间本身就有滞后,没必要做到秒级。最终定的是半小时轮询一次增量数据,大屏上看到的数字延迟不超过30分钟,完全够用。
1.3 大数据的“大”不是数据量大,是维度多
这个项目做下来最大的体会是,招投标数据的核心价值不在“量”而在“联”。一条招标公告只能告诉你某个医院要采购一套系统,但把它和同区域其他医院的采购记录关联起来,你可能就会发现这个区域正在做一轮信息化改造,后面还会有一连串机会。这种“从单点到全局”的推导能力,才是大数据技术在这个场景里真正的用武之地。
2. 三大维度重构:区域、行业、竞争图谱怎么从数据里长出来
2.1 维度一:区域格局——钱在往哪里流动
区域维度解决的是“市场在哪”的问题。我们把全国按省级行政单位划分,对每个区域的招标数量、招标总金额、平均单项目金额、同比增长率做统计,再落到地图热力图上。
实际操作中,单纯看招标总额有个陷阱:某省一个数百亿的 mega 项目会把全省数据拉高,看起来热得不行,实际上普通企业根本吃不到。后来增加了两个辅助指标:项目数量中位数和中小金额项目占比,用来过滤“大盘子、小机会”的虚胖区域。
区域维度真正发挥作用是在销售资源配置上。以前华南大区要不要加人,靠区域总监拍脑袋,现在直接看数据:过去三个季度华南的招标项目数连续环比增长,且教育行业占比显著上升,那招一个懂教育的销售就有据可依。大屏上这个维度用地图展示,点击某个省份可以下钻到市级,再点能看到该区域最近一个月的标讯列表。
2.2 维度二:行业风向——采购需求在往哪个方向迁移
行业维度解决的是“机会在哪”的问题。我们参照国民经济行业分类,对招标公告做了行业映射。这里有个很关键的处理:很多公告标题里不会直接出现标准行业名称,写的是“某某医院信息化升级改造项目”,需要靠招标人名称和项目描述一起判断,才能归到“医疗卫生”还是“软件和信息技术服务”。
行业维度的核心指标有两个:行业招标总额趋势和行业采购结构变化。前者用来判断大方向,后者用来发现细分机会。举个实际例子,数据分析显示某传统制造行业的招标量在下降,但“智能化改造”相关关键词的出现频率在快速上升,说明整个行业正在从硬件采购转向软件和服务采购,这就是产品团队调整方向的直接依据。
大屏上这个维度用环形图和折线图组合展示:外环是当前季度各行业占比,内环是上一季度占比,折线则展示选定行业过去12个月的趋势,能直观看到行业的冷热转换。
2.3 维度三:竞争图谱——谁在跟你抢同一块蛋糕
竞争维度是最有意思、也是挖起来最深的一个维度。我们把中标结果数据按照中标人维度聚合,计算每家企业在各区域、各行业的活跃度和中标率,再分析招标人和中标人之间的历史关系网络。
这里说的“关系网络”不是查某两家公司有没有关联关系,而是看数据上的行为模式:某业主单位过去两年发的标,超过60%都被同一家企业中标,那这个业主就是那家企业的基本盘,新玩家想进去难度很大;反过来,如果某业主的标的分散在七八家中标人手里,说明这个口子还没被锁定,是新机会。
大屏上这个维度用关系图展示,节点是招标人和中标人,连线表示有过中标记录,连线的粗细代表合作频次,颜色深浅代表最近一次合作的时间远近。关系图这个可视化组件在avue-data里没有现成的,是集成了ECharts的关系图后自己调的配置,后面详细说。
2.4 为什么是这三个维度,而不是更多
项目启动时列过十几个分析维度,包括招标方式分布、评标办法偏好、代理机构活跃度、保证金政策变化等等,最后砍到只剩三个。原因是这三个维度对应了企业最关心的三个问题:去哪里卖、卖什么、谁能卖得过。其他维度不是没用,而是对“一张屏看懂江湖”这个目标来说,属于锦上添花,放上去反而干扰核心信息。
这个取舍逻辑后来证明是对的。业务部门看大屏的时候,只需要在这三个维度之间切换,不需要理解复杂的数据模型,上手成本极低。
3. 一张屏的落地:avue-data选型与部署实操
3.1 为什么在众多大屏方案里选了avue-data
大屏前端方案当时比选了好几个:DataV、ECharts定制、React系的开源大屏模板,以及avue-data。最终选avue-data的原因有三点:
第一,它基于Vue,和团队现有技术栈一致,不用为了一个大屏单独引入一套React体系。第二,avue-data内置了丰富的图表组件和边框装饰,特别是对ECharts的封装做得比较友好,配置项可以直接透传,灵活性够。第三,它是纯前端的可视化编辑器,部署就是一个静态站点加一个接口服务,不依赖重量级后端框架,运维成本低。
当时也考虑过DataV,但DataV的定制性相对弱一些,而且商业版收费,开源版功能有限。avue-data的社区活跃度不错,遇到问题基本都能搜到解决方案。
3.2 大屏视觉设计与布局的实操细节
大屏的分辨率按1920乘1080设计,这个没什么好说的,关键是布局。我们用的是经典的三栏结构:中间主视觉区放全国地图热力图,左侧放区域榜单和行业占比,右侧放竞争关系图和实时标讯滚动列表。底部一条横向的指标卡,展示全平台今日新增标讯、今日招标总额、本月累计项目数等核心数字。
布局上最需要注意的问题是信息密度。第一版大屏把所有能用的指标全塞进去了,结果就是满屏数字,谁看都晕。后来狠心砍掉了将近一半的展示项,每个区域只保留一个核心图表加一个辅助指标,才算是“一张屏能看懂”。
avue-data在实现层面帮了大忙,它把常见的边框、标题栏、轮播表、翻牌器都封装好了,直接用组件拼接就能搞定80%的静态界面。真正花时间的是ECharts的定制配置,比如地图热力图的颜色渐变、关系图的力导向布局参数、折线图的平滑曲线和阈值线标注。
3.3 大屏前端怎么部署——avue-data的生产环境之路
avue-data生成的工程本质上是一个Vue项目,构建后产物是一堆静态文件,部署方案就很简单:Nginx托管静态资源加反向代理后端接口。
具体的Nginx配置有几个关键点:大屏的接口服务单独配一个/api前缀的location,代理到后端的Java服务;静态资源开启gzip压缩,因为大屏引用的ECharts和地图GeoJSON文件体积不小;配置了try_files指令,保证前端路由在刷新时不出现404。
服务器配置这块,最开始用一台2核4G的ECS跑Nginx加后端接口,发现大屏首次加载要3到4秒,主要是地图GeoJSON文件和ECharts体积太大。优化方案是:地图GeoJSON按需加载,只加载全国和省级数据,市级数据在点击下钻时才请求;ECharts用按需引入的方式,只打包用到的组件,首屏体积直接从2MB降到了600KB左右,加载时间控制在1秒内。真实部署的时候还遇到一个本地开发环境正常、线上白屏的问题,排查到最后是publicPath配置不对,静态资源路径指向了/,发布到子目录下就全挂了,改成了相对路径才解决。
4. 数据链路治理:采集、清洗、Spark离线与Dinky实时的配合
4.1 采集层:公开渠道的增量抓取与多源去重
招投标数据的采集没有太多黑魔法,主要来源就是全国公共资源交易平台、各省级交易中心、政府采购网这些公开渠道。爬虫用Python的Scrapy框架写的,部署在四台2核4G的云主机上,按域名和地区分摊任务,每个采集任务半小时跑一轮增量。
采集层最麻烦的不是并发和速度,是去重。同一个项目可能会在省平台、市平台、行业平台重复发布,字段还不完全一样。这里的幂等策略不复杂:用“项目编号+招标人+发布时间”三个字段拼成一个MD5值作为主键,只要三个字段完全一致就认为是同一条公告,后到的直接丢弃。实际上还有一部分公告没有标准的项目编号,只有标题和地区,这种就得用标题经过归一化后(去掉空格和特殊字符)再参与去重,虽然会有极少数误判,但整体可控。
4.2 数据质量:为什么说“减少错误、保证质量”是第一步
数据采集进来之后,不做清洗的话,后面整个分析都是空中楼阁。招投标数据最常见的脏数据有这几类:
金额字段格式不统一:有的公告写“预算金额:人民币120万元”,有的写“预算1200000元”,还有的写“预算约120万”。不统一成数字的话,聚合计算全是错的。清洗逻辑是优先从公告的“预算金额”字段直接抓数字,抓不到就用正则表达式去正文里匹配“人民币+数字+单位”的模式,再把“万”和“亿”换算成元。这个环节出错率一开始挺高,大概有5%左右的数据会换算错误,后来加了一层人工抽检和异常值过滤(单项目金额超过10亿或者低于5000元的进入人工复核队列),才把准确率拉高到99%以上。
时间格式不统一:有的发布时间精确到秒,有的只到日期,还有的带时区。统一存成yyyy-MM-dd HH:mm:ss,时间对不上的一律以平台列表页的抓取时间为准再往前推一天,保证趋势分析的时间轴是连续的。
还有一个容易忽略的问题是“行业字段缺失”。很多公告根本没有行业分类,只能靠标题关键词和招标人名称去推。我们维护了一张行业关键词映射表,比如“医院、卫生、医疗”映射到“医疗卫生”,“学校、教育、教学”映射到“教育”,关键词命中不到的就归为“未分类”。未分类的比例控制在10%以内,太高了就说明映射表需要扩充。
4.3 存储与离线分析:Hive分区表加Spark SQL
清洗完的数据写入Hive,按天分区存储,表结构大概是这样的:
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 主键MD5 |
| title | string | 项目标题 |
| owner_name | string | 招标人 |
| winner_name | string | 中标人 |
| amount | decimal(14,2) | 项目金额(元) |
| region_code | string | 区域编码 |
| industry_code | string | 行业编码 |
| publish_time | timestamp | 发布时间 |
| notice_type | int | 公告类型(招标/中标/变更) |
离线分析用Spark SQL跑,每天凌晨对前一天的数据做全量汇总:各区域、各行业的项目数和金额、环比增速、Top招标人排行、Top中标人排行。这些结果落到MySQL的汇总表里,大屏接口直接查MySQL,避免大屏直接连着Hive查询,响应时间会慢到没法看。
这里提一个用Java写Spark作业的实操经验。我们团队主要写Java,Spark作业也是用Java写的,核心逻辑就是Dataset<Row>的SQL查询和groupBy聚合,代码量不大但要注意三件事:一是尽量用spark.sql()写SQL而不是用Java的DataFrame API拼转换逻辑,后者代码可读性太差;二是聚合结果一定要repartition(1)之后再写MySQL,不然会产生大量小文件,写入效率极低;三是Spark作业跑完要监控日志里的total time和records written,这两个指标能帮你快速判断数据量是否正常。
4.4 实时链路:Dinky加Flink让大屏数字“活”起来
大屏上有一块“今日新增标讯”的数字,不能等离线任务跑完才出结果,必须实时更新。这块用的是Dinky加Flink的实时计算链路。Dinky是一个开源的实时计算平台,底层就是Flink,它最实用的能力是把Flink SQL的提交和运维做成可视化的,开发同学不用直接跟Yarn上的一堆任务打交道。
逻辑也很简单:采集层每抓到一条新增公告,写一份JSON到Kafka,Flink SQL从Kafka读出来,做一次简单的窗口聚合(每5分钟统计一次新增数量),结果写入Redis,大屏前端通过WebSocket订阅Redis里的最新值。整个链路的端到端延迟大概在1到2分钟,做“今日新增标讯”这种计数场景绰绰有余。
Dinky本身没太多部署坑,下载对应Flink版本的发行包解压就能用,注意配置好元数据库(我们用的MySQL)和Flink集群地址就行。真正要注意的是Flink SQL的Checkpoint配置,默认的checkpoint间隔可能会导致Kafka消费位点回退,出现重复计数。我们把这个间隔设置成30秒,并且开启exactly-once语义,重复计数的问题就解决了。
4.5 后端接口:把分析结果做成大屏要的JSON
大屏背后的接口服务是用Spring Boot写的,核心是几个查询接口:区域热度接口、行业趋势接口、竞争关系接口、实时标讯列表接口。这些接口不直接查Hive,都是从MySQL读离线汇总结果,实时计数的部分从Redis读,响应时间基本都在100毫秒以内。
接口设计上有一个教训:不要在大屏接口里做太多计算。第一版把一些复杂的关联查询都放在接口里做,结果大屏加载的时候接口响应要2秒多,页面一直转圈。后来把能离线算的指标全在Spark里算完落表,接口只做简单的筛选和排序,响应时间立刻降到100毫秒以内。大屏这种场景,前端只管展示,后端只管出数据,中间不要有任何实时计算的环节,这是最稳的架构。
5. 复盘:谛听上线三个月,哪些指标真正被用起来了
5.1 业务侧真实用起来的地方
大屏上线三个月,回访了业务团队,发现他们真正高频使用的功能其实不多,但每一个都用得很深。
销售团队用得最多的是“区域榜单”和“实时标讯列表”。每天早上打开大屏扫一眼今日新增标讯,按区域和行业筛选出和自己负责的客户相关的项目,直接进系统跟进。以前人工刷网站需要半小时的事,现在两分钟就能完成。
管理团队看得最多的是“行业趋势图”。哪条线在增长、哪条线在萎缩,都清清楚楚。上个月公司调整产品方向的时候,就是靠行业趋势数据做的判断——一个传统行业客户采购量在下降,但细分赛道的智能化改造需求增长很快,于是把售前资源向新赛道倾斜。
竞争图谱用得最少,但也有价值。销售在打新客户之前,会先看一眼这个客户历年的中标记录,如果发现长期被某一家竞争对手锁定,就会调整策略,不硬碰硬,而是从他们服务薄弱的子项目切入。这个数据在CRM系统里看不到,只有从招标数据里才能挖出来。
5.2 上线后踩过的几个大坑
第一个坑是地图热力图数据不准。第一版地图的色阶直接用的“招标总金额”,结果某个月一个超大项目把某个省映射成深红色,其他省全是淡色,视觉上完全失真。后来改成“项目数量加平均金额的加权值”,并且限制了颜色映射区间,视觉才正常。
第二个坑是行业分类出错导致的趋势误判。上面说到未分类比例要控制在10%以内,刚开始没做好,某个月的“未分类”数据占比飙到了25%,直接把行业趋势图带偏了。后来加了一个定时任务,每周跑一次未分类数据的回填,用最新的关键词映射表去重新分类历史数据。
第三个坑是大屏的性能问题。同时打开多个大屏页面的时候,服务器CPU直接拉满,排查下来是WebSocket连接没有做心跳断线回收,连接数越积越多。后来加了心跳机制和连接数上限,问题解决。
5.3 如果重新做一遍,我会改什么
如果让我重新做一遍,有几个地方会先改:
数据采集的架构会直接上分布式调度框架,而不是用简单的Cron加Scrapy。当时为了快速上线,部署了四台机器分别跑不同的采集任务,任务之间的依赖关系靠手工配置,后面加了增量任务之后变得很难维护。
大屏的权限体系会提前设计。老板、销售、运营看到的默认维度应该不一样,而不是现在这样所有人进去都看到同一个页面。这个不复杂,但涉及到前端路由和后端接口的双重改造,上线后再加就比较费劲。
数据质量监控会前置。现在每天的离线任务跑完会巡检一遍数据质量,但还是有滞后性。如果重新做,会在采集入口就加上实时数据质量监控,比如金额解析成功率、行业分类覆盖率这些指标,低于阈值就报警,而不是等季度复盘的时候才发现问题。
“谛听”做下来,我最大的体会是:技术选型其实不是这个项目里最难的部分,avue-data也好、Spark也好、Dinky也好,都是工具,重要的是先想清楚业务要什么,再用数据的方式去回答业务的三个问题——市场在哪、机会在哪、谁能赢。当这三个问题都能用一张屏回答清楚的时候,这套系统的价值就真的立住了。
