从 ClickHouse 到 Apache Doris:快成物流的数智化货运应用实践

news2024/11/18 0:33:01

导读:随着快成物流的大宗商品产业链的不断发展,货运轨迹规划和实时数据分析的需求日益迫切,为了保障数据报表更新、用户画像圈选与物流轨迹实时更新等大数据核心系统性能,快成物流引入 Apache Doris 实时数仓升级了大数据算法平台,目前已经部署在 2 套生产集群,存储数据总量达百亿规模,覆盖实时数仓、BI 多维分析、用户画像、货运轨迹信息系统等业务场景。

作者共创:快成物流大数据算法平台技术负责人 汪新禧 & SelectDB 内容团队

山西快成物流科技有限公司(简称“快成物流”)是一家以新一代信息技术为核心的“互联网 + 大宗物流产业链生态”的平台型科技企业,网络货运排名跻身全国前三。快成物流深耕“让大宗商品流通更美好”的企业使命,依托数字技术连接大宗物流全产业链,向产业参与主体提供全链路一体化物流解决方案,为行业降本、增效、提质持续助力。

目前快成物流服务卡车司机累计已破百万,货主数万家,在业务高峰期,单日新增数据量达到千万级别,大数据系统的数据处理能力面临巨大的挑战。快成物流已拥有多个数据业务线,其中核心业务包括:

  • 网络货运平台: 服务数万货主与百万卡车司机的大宗商品物流运输平台,业务流程复杂,实体货物种类多、服务周期长,对数据实时性要求高、数据分析维度复杂。
  • 快乐驾: 智慧物流车载终端系统,包括轨迹监控、安全驾驶等。
  • 快乐购: 后市场消费服务平台,包括加油加气、卡车零件销售等电商服务。

业务生态.png

随着业务规模的不断扩大,快成大数据算法平台在支撑上述业务产生海量数据存储的同时,也需应对多种多样的数据应用需求,包括基础业务支撑、BI 报表分析、可视化大屏、用户画像、智能风控、精准营销、AB 实验以及合规性监测等,这也对大数据平台提出了更高的技术要求:

  • 极速数据处理:平台需要支持高吞吐量的复杂数据分析,在海量数据中快速准确地提取有价值的信息。
  • 点查性能强:大数据平台需实现高 QPS 点查能力,确保在海量数据中快速定位并查询特定信息,以满足用户对数据实时性的高要求。
  • 运维管理成本低:在保障数据处理效率和质量的同时,大数据平台期望通过自动化、智能化的运维手段降低运营成本。
  • 运行稳定:系统需要高可靠、高可用,为业务持续发展提供有力保障。

业务诉求与技术选型

随着用户对数据分析的实时性与时效性需求的日益提升,快成物流在早期进行 OLAP 数据库技术选型时,核心诉求是寻找一款基于 MPP 架构、高性能、实时的分析型数据库。当时考察选型的数据库包括 Kylin、Druid、Doris、ClickHouse 等。经过评估后,我们先选择了已经拥有一定用户基础的 ClickHouse,其在千万级别的单表处理耗时往往在数秒内,基本满足业务需求。而此时的 Doris 仍在孵化阶段,功能与稳定性尚需时间验证,我们也在持续关注 Doris 的发版与功能升级,并定期进行性能测试。

随着业务深度使用,ClickHouse 在查询性能方面表现较好,帮助我们解决了不少业务问题,但痛点也开始显露出来:

  • 多表 Join 性能有限:ClickHouse 只有 Global Join 和 Local Join,在大表 Join 大表时的场景下,跨节点间数据 Shuffle 时容易导致 Join 性能大打折扣,甚至造成 OOM 。

  • 运维成本高:ClickHouse 的扩容缩容操作复杂,目前做不到自动在线操作;配置管理也相对繁琐,学习成本很高。

与此同时,Apache Doris 的功能正在不断升级完善, 我们发现 Doris 的多表 Join 能力与运维成本更加符合我们对 OLAP 数据库的预期,并且能够很好的解决 ClickHouse 出现的上述痛点,测试环境下的性能表现也十分出色。

经过一段时间的试用后,我们开始逐步替代 ClickHouse,目前快成物流大数据算法平台的主要 MPP 场景都基于 Doris 提供服务。

基于 Apache Doris 的大数据算法平台

为支撑快成多种多样的数据应用场景, 我们团队自建了相对完善的大数据算法平台,引入 Doris 后的架构如下:

基于 Apache Doris 的大数据算法平台.png

按照从左至右数据流向,数据处理架构可概括为以下主要环节:

数据源端主要包括来自 MySQL 等业务数据库的运单数据、物流车终端上报的物联网数据、埋点日志数据等,在数据采集环节会分别经由 Flink CDC、SeaTunnel、Sqoop 以及 Filebeat 等工具进行数据抽取。在数据清洗计算阶段,实时数据会通过 Kafka 采集和 Flink 进行计算并存储在实时数据仓库 Doris 中,而离线数据则通过 Spark 进行 ETL 后进入离线数据仓库 Hive 中。此外,特征数据还会存储在特征平台 Feathr 中,随后在分析建模环节进行数仓分层、建模,构建指标体系和标签体系,最终服务于数据应用,支持报表生成、BI 分析、业务支撑、调度匹配、风控以及合规等核心业务。

在以上架构中,Apache Doris 担任了实时数据仓库的关键定位,对上游承接了离线和实时数据的接入、对下游支持了 BI、报表、用户画像、风控、营销等数据应用的查询分析服务,在快成的大数据技术算法平台中发挥了至关重要的作用。下文将重点分享 Apache Doris 在快成物流的大数据应用与升级实践,希望对读者产生积极的借鉴意义。

Doris 在快成的应用实践

快成物流的货运业务复杂度高,业务节点多且链路周期较长,实时数仓建设难度较高,加之对接了大量微服务系统,数据库表较为分散,这使我们在建设实时数仓的过程中,面临着诸多挑战:

  • 保证复杂实体关系下的数据准确性;

  • 提升实时多流 Join 的处理效率;

  • 保障数据一致性;

  • 平衡数据数量、时效性与算力资源之间的关系。

01 实时数据接入

针对实时数据,我们又细分为实时与近实时两种情况:

  • 毫秒级实时(Real-time):实时数据处理指数据在产生后立即进行处理和响应,无延迟或延迟极小。实时处理对数据的处理速度要求非常高,通常需要在毫秒级别内完成,常用于需要即时反馈和实时决策的场景,例如实时风控等。

  • 秒级近实时(Near Real-time):近实时数据处理指数据产生后,经过一定延迟再处理,通常在秒级别内完成。近实时处理常用于对数据的快速分析和决策,例如实时报表生成、数据仪表盘等场景。

对于不同源数据的写入,Doris 提供了丰富的数据接入扩展工具,包括 Spark Doris Connector、Flink Doris Connector、Seatunnel Doris Sink 等,方便用户快速从 Hive、MySQL、Kafka 等源端系统中抽取数据并导入 Doris 中。

我们的整库同步和实时数据接入主要通过 Flink Doris Connector 进行,其依赖于 Flink CDC、Debezium 等技术底层实现。通过伪装 MySQL 等关系型数据库的从库实例,进而实时捕获到 Binlog(业务库表的数据变更日志),最后通过 Stream Load 的方式导入到 Doris 库中。

Flink Doris Connector 封装的较为易用,无需提前建表,就可以快速将上游业务库的表结构及数据接入到 Doris 中,轻松实现一键整库同步。其配置文件脚本如下:

<FLINK_HOME>/bin/flink run \
    -Dexecution.checkpointing.interval=5s \
    -Dparallelism.default=1 \
    -c org.apache.doris.flink.tools.cdc.CdcTools \
    lib/flink-doris-connector-1.17-1.6.1.jar \
    mysql-sync-database \
    --database ods \
    --table-prefix ods_ \
    --mysql-conf hostname=127.0.0.1 \
    --mysql-conf username=root \
    --mysql-conf password=123456 \
    --mysql-conf database-name=test_mysql_db \
    --including-tables "tbl1|test_.*" \
    --sink-conf fenodes=127.0.0.1:8030 \
    --sink-conf username=root \
    --sink-conf password=123456 \
    --sink-conf jdbc-url=jdbc:mysql://127.0.0.1:9030 \
    --sink-conf sink.label-prefix=label1 \
    --table-conf replication_num=3

实时数据接入.png

通过 Flink Doris Connector,5 秒内即可将 MySQL 的 CDC 日志采集到 Doris 的 ODS 层中,接着在 Doris 中构建实时数仓的下游层级。数据仓库分层架构遵循了常见的的四层架构(ODS 贴源层 - DWD 明细层 - DWS 汇总层 - ADS 应用层),以确保数据的高效管理、快速响应和便捷运维。

实时数据接入-1.png

02 报表服务与BI实践

面对需要同时处理高并发报表查询和海量数据分析的场景时,传统的大数据解决方案已经逐渐显露不足。我们基于 Doris 重新建设的大数据算法平台,针对离线与实时数据处理效率进行了深度优化,凭借 Doris 强大的宽表查询性能与并行数据处理能力,有效促进了数据报表与 BI 分析场景的功能升级与分析效率的大幅提升。

2-1 数据报表分析

实时数据报表属于数据高并发、大规模特征并存的典型场景,此前系统中使用的 Hive 和 Spark 在处理大规模数据集方面表现出色,然而面对高并发查询时,处理效率与我们的预期存在较大差距。此外,MySQL 对大规模数据进行查询时,效率显著下降,数据报表的更新速度也因此受限。

经测试,Doris 的数据实时写入和更新能力十分强大,能够实现快速及时的查询分析响应。在实时数仓建设阶段,我们把离线数据架构下 DIM 维度层、ADS 应用层的数据通过 SeaTunel 写入了 Doris 中,实现了结果表的查询加速, 从而实现每秒上万数量级的 QPS 并发查询,数据报表更新及时度大大提高。

2-2 BI 即席分析

即席查询(Ad-Hoc Query)是面向数据分析人员的自助分析应用,因其查询条件多样化,对系统的吞吐能力提出了较高的要求。Doris 提供了灵活丰富的 SQL 函数公式,并拥有高吞吐量的计算能力,数据分析师、产品经理等业务人员通过 Metabase(数据探索与可视化工具) + Doris 即可基本满足 BI 的数据探索需求,大部分查询响应速度都在秒级完成。

03 用户画像实践

用户画像在广告推荐系统、商业分析、用户增长、产品设计、数据化运营、精准营销、量化风控等领域得到广泛应用,依托于 Doris 强大的计算能力, 团队构建了快成物流的用户画像体系。

3-1 人群画像圈选

首先,大数据开发人员将离线数仓与实时数仓计算生产的标签,写入到 Doris 的标签表。产品运营通过人群圈选服务动态生成人群圈选 SQL,最后,通过 Doris 实时计算产生结果并返回给用户。

由于充分利用了 Doris 的 Bitmap 精准去重、倒排索引等特性,在数十个标签筛选组合条件下可以在亚秒级的返回圈选结果,用户“所圈即所得”,避免了长时间等待,极大地提高了运营与营销团队的工作效率。

人群画像圈选.png

3-2 个体画像查询

面向客户的个体画像需求同样属于高并发查询场景, 如司机个人画像、风控预警等。Doris 的前缀索引功能,即在排序基础上实现的根据给定前缀列,能够轻松支持上万 QPS,99 分位的查询延时在 150 毫秒以内,非常适合用户画像点查,很好地替代了之前 HBase + Redis 的点查加速方案。

04 轨迹存储与分析实践

GIS 地理信息系统(Geographic Information System) 作为物流运输平台的核心功能模块之一, 在车辆轨迹、司机 APP 轨迹等方面有着重要的应用, 例如车辆在途、轨迹预警、线路预警、司机驾驶安全等。平台有责任与义务在保证司机行车安全的同时,努力降低车主车辆、货主货品财产损失的风险。 然而,技术上也给平台带来海量轨迹存储、高性能查询与分析的硬性指标要求。

另一方面,监管部门也有“五流合一”合规性的政策要求,根据《网络平台道路货物运输经营管理暂行办法》,企业至少保存长达 3 年的轨迹数据。Doris 自 2.0 版本开始支持冷热分离,我们通过在 Partition 级别上设置 Freeze time,将 3 年前的冷数据存储在类似于 S3 的对象存储上,从而节省本地的磁盘空间,进而节省存储成本。

目前公司使用 Doris 支撑了百亿规模的轨迹存储,提供实时在线轨迹回放、轨迹风控预警等能力, 相比于之前 ES 的技术方案,同等规模数据所依赖的存储资源得到极大幅度节省。

05 湖仓一体实践

Doris 通过多源数据目录(Multi-Catalog)功能,支持了包括 Apache Hive、Apache Iceberg、Apache Hudi、Apache Paimon、Elasticsearch、JDBC(MySQL、Oracle、SQL Server) 等主流数据湖、数据库的连接访问。我们通过 Multi-Catalog 拓展了外部数据源的边界,其使用方法也较为简单, 创建 Hive 数据源的 SQL 语句可参考:

CREATE CATALOG hive PROPERTIES (
    'type'='hms',
    'hive.metastore.uris' = 'thrift://172.21.0.1:7004'
);

在前文提到的用户画像系统中,标签元数据存储在 MySQL, 而明细数据存储在 Doris 中。进行画像圈选服务时,需要分别在 MySQL 与 Doris 两个数据库进行查询,不仅增加了画像系统的复杂度,性能也存在很大的优化空间。我们利用数据湖分析的特性,在 Doris 创建画像元数据的 MySQL Catalog,并规划了两种技术方案:

  1. 使用 SQL Join 语法,直接通过 JDBC 协议关联 MySQL 中的元数据 (数据还在 MySQL 中);
  2. 通过create table as select * from 源表把画像标签元数据同步到 Doris 内部,从而加速查询,然后再通过调度引擎(如 Apache DolphinScheduler)进行周期性调度,

考虑到方式一在批量加载数据时对 MySQL 业务库可能造成的潜在影响,针对用户画像的场景我们最终选择了方案二。建表语句参考:

-- 从 MySQL 导入到 Doris DIM 临时表, 默认 3 副本
create table dim.temp_profile_lable_metadata
PROPERTIES("replication_num" = "3")
as select * from jm_bg_platform.kc_data_profile.profile_lable_metadata;

实践总结与规划

截至目前,基于 Apache Doris 的大数据算法平台已经接入了近 10 个物流大数据业务线,部署生产集群 2 套,存储数据总量达百亿级规模,覆盖实时数仓、BI 多维分析、用户画像、货运轨迹信息系统等业务场景,查询效率大幅提升,其简洁的开发架构与经济的资源存储方案,为业务与开发人员带来极大便利与效益增长。

基于上述应用场景,我们总结了 Doris 的核心优势,具体如下:

  • 查询性能优越: 无论是即席分析场景的多表复杂关联,还是用户画像、特征、实时报表场景的高 QPS 点查,都可以轻松支持;

  • 数据湖分析能力强大:可轻松与 Hive、Hudi、JDBC、ES 构建统一语法的联邦查询;

  • 功能开放:例如 Java UDF 可以复用 Hive UDF,减少重复造轮子;

  • 有效降本:运维方面,可以按需弹性扩缩容节省资源,方便集群数据迁移;开发方面,多表关联便利,不用再频繁改写 Join;

在业务实践环节,我们也记录了许多生产环境下基于 Doris 的开发经验,在此与诸位分享:

  1. MPP 数据库在 OLAP 场景虽然兼容 MySQL 协议,但是不建议当作 MySQL 使用,更适用于大批量的数据写入,而非高并发的单条数据写入;

  2. 构建轻量级数仓时,部分场景可以替代 Hive 数仓,尤其是中小规模的数据量并且相对简单的场景;

  3. GIS 物联网的场景下使用,可以支持存储 PB 数据级别;

  4. 分区表支持原子替换,支持对两个表进行原子的替换操作,不会中断表提供服务;

后续我们将持续深入使用 Apache Doris 的新版功能,并重点关注扩展以下方面:

  • 引入异步物化视图:Apache Doris 在 2.1 版本推出了基于多表的异步物化视图,支持透明改写加速、自动刷新、外表到内表的物化视图以及物化视图直查,此外,还可以用于数据仓库分层建模、作业调度和数据加工等场景。

  • 数据一体能力扩展:此前我们曾向社区提议增强数据集成能力,例如通过 JDBC Catalog 从 MySQL 直接同步数据至 Doris,意见已被社区采纳并改进完成,后续也期待更多的新功能。

  • 增强 GIS 地理信息系统功能:如经纬度距离实时刷新、区域范围搜索提速;

  • 期待整合 AI算法库:增加例如 Spark ML 类的机器学习算法库,整合特征平台与向量数据库。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1891724.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue2使用use注册自定义指令实现输入控制与快捷复制

使用场景 在一些form表单填写内容的时候&#xff0c;要限制输入的内容必须是数值、浮点型&#xff0c;本来el-input-number就可以实现&#xff0c;但是它本身带那个数值控制操作&#xff0c;等一系列感觉不舒服的地方。如果只是使用el-input该多好&#xff0c;只要监听一下输入…

docker安装ElasticSearchKibana

本文参考以下两篇文章 ✅ElasticSearch&Kibana 部署 云效 Thoughts 企业级知识库 (aliyun.com) docker安装ElasticSearch&Kibana - 飞书 安装elasticsearch 使用docker下载es&#xff1a; docker pull elasticsearch:8.13.0 挂载配置 创建挂在文件目录 mkdir…

AIGC在软件开发中的应用

目录 1. AIGC技术概述1.1 定义与背景1.2 发展历程 2. AIGC在软件开发中的应用2.1 代码生成2.2 错误检测与修复2.3 自动化测试 3. AIGC对开发者职业前景的影响3.1 助力与赋能开发者代码示例&#xff1a;自动化测试 3.2 技能需求转变与职业转型压力代码示例&#xff1a;AIGC辅助的…

云原生技术架构详解

云原生技术最全详解(图文全面总结) 容器技术 容器技术&#xff1a;是将应用程序、及其所有依赖项&#xff0c;打包到一个独立的、可移植的容器中。 如下图所示: 容器技术的实现&#xff0c;最典型的就是以Docker为代表的。 如下图所示&#xff1a; 主要解决&#xff1a; 1、…

#LinuxC高级 笔记一

linux命令 什么是嵌入式&#xff1f; 以应用为中心&#xff0c;以计算机技术为基础&#xff0c;软件硬件可裁剪&#xff0c;适用于对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统 计算机系统组成&#xff1f; 硬件、软件 操作系统&#xff1f; ios windows harmo…

Docker的架构原理

例子可以想象成一个买手机的场景 clien可以想象 你个人 docker deamon &#xff1a;店员 images&#xff1a; 样机 regisitry&#xff1a; 手机仓库 container: 使用的手机 首先我要在店员买一个手机&#xff0c;店员发现是样机&#xff0c;但是仓库有&#xff0c;&…

Zabbix 配置端口监控

Zabbix 端口监控简介 在Zabbix中配置端口监控&#xff0c;可以帮助你实时监控服务器或网络设备上的特定端口是否开放和可访问。Zabbix提供了多种方式来监控端口&#xff0c;主要包括简单的端口可用性检查和更复杂的服务监控。 在Zabbix中进行端口监控时&#xff0c;不一定需要…

小白尝试某程机票信息爬取

实训课需要机票数据集&#xff0c;网上没有&#xff0c;所以我选择爬取数据 此过程可谓经历的九九八十一难&#xff0c;也参考了不少大佬的文章&#xff0c;在此特别记录一下 弯路不多说&#xff0c;我直接讲成功的方法 找到请求url 通过控制台&#xff0c;最后确认下面的 …

C# 编程中互斥锁的使用

C# 中的互斥锁 互斥锁是 C# 中使用的同步原语&#xff0c;用于控制多个线程或进程对共享资源的访问。其目的是确保在任何给定时间只有一个线程或进程可以获取互斥锁&#xff0c;从而提供互斥。 C# 中互斥锁的优点 可以使用互斥锁 (Mutex) 并享受其带来的好处。 1. 共享资源…

使用 PCA 可视化数据的分类能力

使用 PCA 探索数据分类的效果&#xff08;使用 Python 代码&#xff09; 「AI秘籍」系列课程&#xff1a; 人工智能应用数学基础人工智能Python基础人工智能基础核心知识人工智能BI核心知识人工智能CV核心知识 主成分分析 (PCA) 是数据科学家使用的绝佳工具。它可用于降低特征…

LabVIEW自动探头外观检测

开发了一套基于LabVIEW的软件系统&#xff0c;结合视觉检测技术&#xff0c;实现探头及连接器外观的自动检测。通过使用高分辨率工业相机、光源和机械手臂&#xff0c;系统能够自动定位并检测探头表面的细微缺陷&#xff0c;如划痕、残胶、异色、杂物等。系统支持多种探头形态&…

机器学习简介--NLP(二)

机器学习简介 机器学习简介机器学习例子机器学习分类有监督学习有监督学习的应用 无监督学习 机器学习常见概念数据集k折交叉验证过拟合欠拟合评价指标 机器学习简介 机器学习例子 问题&#xff1a; 2&#xff0c;4&#xff0c;6&#xff0c;8&#xff0c;&#xff1f;&#…

智能语音门锁:置入NV170D语音芯片ic 打造便捷生活新体验

一、智能门锁语音芯片开发背景 随着科技的飞速发展&#xff0c;传统门锁的局限性日益凸显&#xff0c;无法满足现代人对高效、安全生活的需求。在这样的时代背景下&#xff0c;智能门锁应运而生&#xff0c;它不仅继承了传统门锁的基本功能&#xff0c;更通过融入先进的科技元素…

数据库安全:MySQL权限体系划分与实战操作

「作者简介」&#xff1a;冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础著作 《网络安全自学教程》&#xff0c;适合基础薄弱的同学系统化的学习网络安全&#xff0c;用最短的时间掌握最核心的技术。 这一章节我们需…

基于OpenMV识别数字及程序说明

OpenMV简介 OpenMV是一个开源、低成本且功能强大的机器视觉模块。它基于STM32F427CPU&#xff0c;集成了OV7725摄像头芯片&#xff0c;能在小巧的硬件模块上&#xff0c;用C语言高效地实现核心机器视觉算法&#xff0c;并提供了Python编程接口&#xff0c;使得图像处理的复杂度…

k8s_集群搭建_k8s管理前端_dashboard安装部署---分布式云原生部署架构搭建017

然后再去安装一下一个dashboard,有了这个以后,操作k8s集群就不用 一直敲命令了 可以看到上面的命令拿过来,然后 执行就可以了 然后如果执行慢,可以直接先去下载,使用wget,然后再去 也可以在浏览器访问,把内容拿到,然后 下面是内容: # Copyright 2017 The Kubernetes Author…

金融科技企业的数据治理与合规挑战

随着科技的发展&#xff0c;金融科技行业在我国得到了迅猛发展。金融科技创新不仅为消费者带来了便捷的金融服务&#xff0c;也极大地提高了金融行业的运营效率。然而&#xff0c;在金融科技发展的同时&#xff0c;数据治理与合规挑战也日益显现。本文将深入探讨金融科技企业在…

84 柱状图中最大的矩形

题目 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 输入&#xff1a;heights [2,1,5,6,2,3] 输出&#xff1a;10 解释&#xff1a;最大的矩…

华为OD机试 - 最长合法表达式 - 双指针(Java 2024 D卷 100分)

华为OD机试 2024D卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;D卷C卷A卷B卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测…

竞赛选题 交通目标检测-行人车辆检测流量计数 - 竞赛选题

文章目录 0 前言1\. 目标检测概况1.1 什么是目标检测&#xff1f;1.2 发展阶段 2\. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 毕业设计…