news 2025/12/14 11:42:22

大数据架构 _ 从传统数据管理到数据产品的转变

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
大数据架构 _ 从传统数据管理到数据产品的转变

大数据架构 | 从传统数据管理到数据产品的转变

引言:为什么传统数据管理“失效”了?

2018年,我在某零售企业做数据架构咨询时,遇到一个典型的困境:

  • 业务团队要做“618大促用户留存分析”,需要从5个系统(ERP、CRM、APP日志、线下POS、微信小程序)取数据;
  • 数据团队花了3天时间协调各系统负责人导出数据,再用Hadoop做ETL清洗,最后用Tableau生成报表;
  • 等报表送到运营手中,大促已经结束2天——数据的价值,在漫长的“管理流程”中过期了

这不是个例。传统数据管理的核心是“管数据”:保证数据准确、安全、可存储,但忽略了最关键的问题——数据如何为用户创造价值。当业务从“离线分析”转向“实时决策”、从“看报表”转向“用数据直接解决问题”时,传统架构的弊端暴露无遗:

  1. 数据孤岛:各系统数据分散存储,调用需跨团队协调,效率极低;
  2. 价值传递低效:输出的是“数据集”或“报表”,而非“可行动的结论”;
  3. 实时性缺失:批处理为主,无法应对实时推荐、实时监控等需求;
  4. 缺乏用户思维:数据团队以“技术合规”为目标,而非“用户体验”。

转折点来了:当我们把“数据”当作“产品”来设计——从用户需求出发,用产品化思维包装数据,让业务方“像用APP一样用数据”,一切都变了。

一、数据产品:重新定义“数据的价值”

1.1 什么是数据产品?

数据产品的核心定义是:以数据为核心,解决特定业务问题,具备用户体验设计的系统化输出

它不是“报表的升级”,而是从“输出数据”到“输出解决方案”的跃迁——比如:

  • 传统数据管理输出“用户行为日志表”;
  • 数据产品输出“用户行为分析工具”(能直接看“注册→购买”的转化率,按渠道筛选,甚至自动生成“留存低的原因”)。

1.2 数据产品 vs 传统数据管理:核心区别

维度传统数据管理数据产品
核心目标数据准确、安全、可存储解决业务问题,创造用户价值
用户视角“我们有什么数据”“用户需要什么价值”
输出形式数据集、报表、API可视化工具、嵌入式功能、智能结论
迭代模式一次性交付持续运营(根据用户反馈优化)
团队协作数据团队主导业务+技术+设计共同主导

1.3 数据产品的“用户分层”

数据产品的用户不是“泛泛的业务方”,而是明确的角色

  • 终端用户:比如APP中的“个性化推荐”(用户看不到数据,直接用结果);
  • 业务运营:比如“用户留存分析工具”(运营用它优化策略);
  • 算法工程师:比如“用户画像API”(算法用它训练推荐模型);
  • 管理层:比如“公司核心指标仪表盘”(老板用它做战略决策)。

二、从管理到产品:大数据架构的演进路径

传统数据架构的核心是“数据仓库(EDW)+ 批处理”,而数据产品的架构需要湖仓一体+流批融合+数据服务化——用一张图概括:

graph TD A[业务系统(ERP/CRM/APP日志/传感器)] --> B[数据湖Raw Zone(S3/HDFS)] B --> C[流批融合计算(Flink/Spark)] C --> D[湖仓Curated Zone(Delta Lake/Iceberg)] D --> E[数据服务层(REST API/GraphQL)] E --> F[数据产品(可视化工具/推荐引擎/仪表盘)] F --> G[业务方(运营/产品/算法)] F --> H[终端用户(APP用户/消费者)]

2.1 存储层:从“数据仓库”到“湖仓一体”

传统数据仓库(EDW)的痛点是只支持结构化数据,且扩展成本高。而数据产品需要处理**结构化(用户表)、半结构化(JSON日志)、非结构化(图片/视频)**等全类型数据——**湖仓一体(Lakehouse)**应运而生。

2.1.1 湖仓一体的核心逻辑

湖仓一体是“数据湖的扩展性 + 数据仓库的ACID特性”的结合:

  • Raw Zone(原始区):存储未经处理的原始数据(比如APP日志、数据库备份),保留数据的“原始样貌”;
  • Clean Zone(清洗区):对原始数据做去重、脱敏、格式转换,得到“干净的数据”;
  • Curated Zone(聚合区):存储聚合后的指标(比如DAU、留存率)、维度表(比如用户画像、商品分类),直接支撑数据产品。
2.1.2 技术选型:Delta Lake vs Iceberg vs Hudi

三个主流湖仓框架的对比:

特性Delta LakeApache IcebergApache Hudi
ACID支持强支持强支持强支持
流批融合好(Flink/Spark兼容)较好好(实时写入)
Schema Evolution支持(添加字段)支持支持
社区活跃度高(Databricks主导)高(AWS/Netflix主导)中(Uber主导)

2.2 计算层:从“批处理”到“流批融合”

传统批处理(Hadoop MapReduce、Spark Batch)的延迟是“小时级”,无法满足数据产品的“实时需求”(比如实时推荐、实时监控)。流批融合是解决之道——用一套代码处理“实时流”和“历史批”数据。

2.2.1 流批融合的演进:Lambda → Kappa → Unified Streaming
  • Lambda架构:同时维护批处理和流处理两条链路,批处理处理历史数据,流处理处理实时数据,最后合并结果。痛点是维护成本高(两套代码、两套存储)。
  • Kappa架构:用流处理统一处理所有数据(历史数据通过“重放Kafka日志”处理),解决了Lambda的维护问题。但不支持复杂的批处理逻辑(比如多表关联)。
  • Unified Streaming(统一流处理):以Flink/Spark Structured Streaming为代表,用“流处理”模拟“批处理”——把批数据当作“有限流”,用一套API处理所有场景。
2.2.2 代码示例:用Flink实现流批统一计算

比如计算“最近1小时的订单总金额”,无论是实时流还是历史批数据,都用同一套代码:

importorg.apache.flink.table.api.*;importstaticorg.apache.flink.table.api.Expressions.*;publicclassUnifiedStreamingExample{publicstaticvoidmain(String[]args){// 1. 创建表环境(支持流/批)TableEnvironmentenv=TableEnvironment.create(EnvironmentSettings.inStreamingMode());// 2. 注册源表(实时流:Kafka;历史批:Parquet文件)StringcreateSourceTable=""" CREATE TABLE orders ( order_id BIGINT, amount DOUBLE, ts TIMESTAMP(3), WATERMARK FOR ts AS ts - INTERVAL '5' SECOND -- 水位线,处理延迟数据 ) WITH ( 'connector' = 'kafka', -- 实时流用Kafka;历史批用'filesystem' 'topic' = 'orders_topic', 'properties.bootstrap.servers' = 'localhost:9092', 'format' = 'json' ) """;env.executeSql(createSourceTable);// 3. 计算最近1小时的订单总金额(滑动窗口)Tableresult=env.from("orders").window(Slide.over(lit(1).hour()).every(lit(10).minute()).on($("ts")).as("window")).groupBy($("window")).select($("window").start().as("window_start"),$("window").end().as("window_end"),$("amount").sum().as("total_amount"));// 4. 输出结果(实时流:Kafka;历史批:Parquet文件)StringcreateSinkTable=""" CREATE TABLE order_amount ( window_start TIMESTAMP(3), window_end TIMESTAMP(3), total_amount DOUBLE ) WITH ( 'connector' = 'kafka', 'topic' = 'order_amount_topic', 'properties.bootstrap.servers' = 'localhost:9092', 'format' = 'json' ) """;env.executeSql(createSinkTable);result.insertInto("order_amount").execute();}}

2.3 服务层:从“JDBC接口”到“数据服务化”

传统数据管理通过JDBC/ODBC给业务方提供数据,业务方需要自己写SQL、处理数据格式——这相当于让用户“自己做饭”。而数据产品需要把数据封装成“即拿即用”的服务,比如REST API、GraphQL、SDK。

2.3.1 数据服务化的核心原则
  1. 用户视角:API的命名要符合业务语言(比如/api/v1/retention/api/v1/query_table更易懂);
  2. 版本控制:用v1/v2区分版本,避免破坏旧版本用户;
  3. 权限管理:不同用户访问不同数据(比如运营只能看自己渠道的DAU);
  4. 缓存优化:常用指标(比如DAU)用Redis缓存,减少数据库压力。
2.3.2 代码示例:用Spring Boot搭建数据API

比如实现一个“获取用户留存率”的API:

importorg.springframework.web.bind.annotation.*;importorg.springframework.cache.annotation.Cacheable;importjava.time.LocalDate;importjava.util.List;@RestController@RequestMapping("/api/v1")publicclassRetentionController{privatefinalRetentionServiceretentionService;publicRetentionController(RetentionServiceretentionService){this.retentionService=retentionService;}/** * 获取用户留存率 * @param startDate 开始日期(yyyy-MM-dd) * @param endDate 结束日期(yyyy-MM-dd) * @param channel 渠道(可选,比如"app_store"、"wechat") * @return 留存率列表(次日/3日/7日留存) */@GetMapping("/retention")@Cacheable(value="retention",key="#startDate + '_' + #endDate + '_' + #channel")publicApiResponse<List<RetentionResult>>getRetention(@RequestParam("start_date")LocalDatestartDate,@RequestParam("end_date")LocalDateendDate,@RequestParam(value="channel",required=false)Stringchannel){List<RetentionResult>results=retentionService.calculateRetention(startDate,endDate,channel);returnApiResponse.success(results);}}// 留存率结果类classRetentionResult{privateLocalDatedate;// 注册日期privatedoubleretention1d;// 次日留存privatedoubleretention3d;// 3日留存privatedoubleretention7d;// 7日留存// getter/setter}// 服务类(计算留存率)@ServicepublicclassRetentionService{privatefinalJdbcTemplatejdbcTemplate;publicRetentionService(JdbcTemplatejdbcTemplate){this.jdbcTemplate=jdbcTemplate;}publicList<RetentionResult>calculateRetention(LocalDatestartDate,LocalDateendDate,Stringchannel){// 留存率公式:次日留存 = (注册且次日登录的用户数)/ 注册用户数Stringsql=""" SELECT register_date, COUNT(DISTINCT CASE WHEN datediff(login_date, register_date) = 1 THEN user_id END) / COUNT(DISTINCT user_id) AS retention1d, COUNT(DISTINCT CASE WHEN datediff(login_date, register_date) = 3 THEN user_id END) / COUNT(DISTINCT user_id) AS retention3d, COUNT(DISTINCT CASE WHEN datediff(login_date, register_date) = 7 THEN user_id END) / COUNT(DISTINCT user_id) AS retention7d FROM user_behavior WHERE register_date BETWEEN ? AND ? """+(channel!=null?"AND channel = ?":"")+" GROUP BY register_date";Object[]params=channel!=null?newObject[]{startDate,endDate,channel}:newObject[]{startDate,endDate};returnjdbcTemplate.query(sql,params,(rs,rowNum)->{RetentionResultresult=newRetentionResult();result.setDate(rs.getDate("register_date").toLocalDate());result.setRetention1d(rs.getDouble("retention1d"));result.setRetention3d(rs.getDouble("retention3d"));result.setRetention7d(rs.getDouble("retention7d"));returnresult;});}}

2.4 治理层:从“元数据管理”到“智能数据治理”

数据产品的信任基石是“数据可靠”——用户需要知道“数据从哪来、怎么加工的、质量怎么样”。传统元数据管理(比如Hive Metastore)只能记录“表结构”,而智能数据治理需要:

  1. 数据血缘:追踪数据的“前世今生”(比如“留存率”来自“用户行为表”的“注册时间”和“登录时间”);
  2. 数据质量:自动监控数据的准确性(比如“注册用户数”不能为负)、完整性(比如“订单金额”不能缺失);
  3. 权限管理:细粒度控制数据访问(比如“运营只能看自己渠道的用户数据”);
  4. 数据 catalog:像“数据百度”一样,让用户快速找到需要的数据。
2.4.1 数据血缘的实现:Apache Atlas

Apache Atlas是Hadoop生态的元数据管理工具,支持自动捕获数据血缘:

  • 步骤1:配置Atlas连接Flink/Spark,捕获作业的输入输出表;
  • 步骤2:解析SQL语句,提取字段映射(比如SELECT user_id, COUNT(*) FROM orders GROUP BY user_id中的user_id来自orders表);
  • 步骤3:构建血缘图谱,展示数据的流动路径。
2.4.2 数据质量监控:Apache Great Expectations

Apache Great Expectations是开源的数据质量工具,支持定义“数据预期”:
比如定义“注册用户数”的预期:

expectations:-expectation_type:expect_column_values_to_be_betweencolumn:register_countmin_value:0max_value:100000-expectation_type:expect_column_values_to_not_be_nullcolumn:register_date

当数据不符合预期时,工具会自动发送报警(邮件/钉钉)。

三、实战:搭建“用户行为分析”数据产品

3.1 需求分析:业务要什么?

运营团队的核心需求是:

  • 实时查看DAU(日活用户数)留存率转化率(注册→购买)
  • 渠道(APP Store/微信/抖音)地区(华北/华东/华南)、**用户分层(新用户/老用户)**筛选数据;
  • 查看用户行为路径(比如“注册→首页→商品详情→购买”的转化率);
  • 导出定制化报表(比如“618大促各渠道留存率对比”)。

3.2 架构设计:技术栈选型

技术选型
数据采集Flink CDC(数据库变更)、Logstash(日志)、Kafka(消息队列)
数据处理Flink(实时计算)、Spark(批处理)
数据存储Delta Lake(湖仓)、Redis(缓存)
数据服务Spring Boot(REST API)、GraphQL(复杂查询)
可视化React + ECharts(自定义界面)、Apache Superset(快速报表)

3.3 开发实现:关键步骤

3.3.1 数据采集:实时捕获用户行为

用Flink CDC捕获MySQL的user表(注册数据),用Logstash采集APP日志(登录、点击、购买)到Kafka:

// Flink CDC采集MySQL注册数据MySqlSource<String>mySqlSource=MySqlSource.<String>builder().hostname("localhost").port(3306).databaseList("app_db").tableList("app_db.user").username("root").password("root").deserializer(newJsonDebeziumDeserializationSchema()).build();DataStream<String>registerStream=env.addSource(mySqlSource);// Logstash配置文件(采集APP日志到Kafka)input{file{path=>"/var/log/app/behavior.log"start_position=>"beginning"}}filter{json{source=>"message"}}output{kafka{bootstrap_servers=>"localhost:9092"topic_id=>"app_behavior_topic"}}
3.3.2 实时计算:DAU与留存率

用Flink计算实时DAU(按天去重):

// 解析Kafka中的用户行为数据DataStream<UserBehavior>behaviorStream=env.addSource(kafkaConsumer).map(json->newObjectMapper().readValue(json,UserBehavior.class));// 按用户ID去重,计算DAU(滚动窗口,1天)DataStream<DAUResult>dauStream=behaviorStream.keyBy(UserBehavior::getUserId).window(TumblingProcessingTimeWindows.of(Time.days(1),Time.hours(-8)))// 按UTC+8调整窗口.reduce((a,b)->a,(key,window,input,out)->{out.collect(newDAUResult(window.getStart(),window.getEnd(),1));}).keyBy(DAUResult::getWindowStart).sum("count");// 写入Delta LakedauStream.addSink(DeltaSink.forRowFormat(newPath("/delta/dau"),newJsonRowSerializationSchema.Builder().withSchema(DAUResult.SCHEMA).build()).build());
3.3.3 可视化:用ECharts展示趋势

用React+ECharts实现DAU趋势图:

import React, { useEffect, useState } from 'react'; import * as echarts from 'echarts'; const DAUTrend = () => { const [dauData, setDauData] = useState([]); // 调用API获取数据 useEffect(() => { fetch('/api/v1/dau?start_date=2024-05-01&end_date=2024-05-07') .then(res => res.json()) .then(data => setDauData(data.data)); }, []); // 渲染ECharts图表 useEffect(() => { if (dauData.length === 0) return; const chart = echarts.init(document.getElementById('dau-trend')); const option = { title: { text: '最近7天DAU趋势' }, xAxis: { type: 'category', data: dauData.map(item => new Date(item.windowStart).toLocaleDateString()) }, yAxis: { type: 'value' }, series: [{ data: dauData.map(item => item.count), type: 'line', smooth: true }] }; chart.setOption(option); // 自适应窗口大小 window.addEventListener('resize', () => chart.resize()); return () => window.removeEventListener('resize', () => chart.resize()); }, [dauData]); return <div id="dau-trend" style={{ width: '100%', height: '400px' }} />; }; export default DAUTrend;

3.4 效果:业务方怎么用?

运营小明打开数据产品:

  1. 首页看到核心指标(DAU:12万,留存率1d:30%,转化率:5%);
  2. 点击“渠道筛选”,选择“抖音”,看到抖音渠道的DAU是3万,留存率1d:45%(高于平均值);
  3. 点击“行为路径”,看到“注册→商品详情→购买”的转化率是8%(比“注册→首页→购买”高2倍);
  4. 导出报表,发给老板:“抖音渠道的新用户质量更高,建议加大投放”。

结果:运营团队的决策时间从“3天”缩短到“5分钟”,抖音渠道的投放ROI提升了40%。

四、数据产品化的关键挑战与应对

4.1 挑战1:数据质量如何保证?

问题:数据产品的价值依赖数据质量,但现实中“脏数据”无处不在(比如用户填写的手机号是11位字母)。
应对

  • 前置校验:在数据采集层做格式校验(比如用Logstash的mutate插件过滤无效手机号);
  • 后置监控:用Apache Great Expectations定义数据预期,自动报警;
  • 血缘追溯:当数据出错时,用Atlas快速定位问题源头(比如“留存率”错误是因为“用户行为表”的“登录时间”格式错误)。

4.2 挑战2:跨团队协作如何对齐?

问题:数据产品需要业务、技术、设计团队协作,但常出现“业务说不清楚需求,技术做出来不符合预期”。
应对

  • 用户故事映射:用“用户故事”描述需求(比如“作为运营,我需要按渠道看留存率,以便调整投放策略”);
  • 原型验证:用Figma做低保真原型,让业务方提前看到产品样子;
  • 迭代反馈:每两周发布一个最小可行产品(MVP),收集业务方反馈,快速调整。

4.3 挑战3:成本如何控制?

问题:湖仓一体、流批融合的架构需要大量计算和存储资源(比如Flink集群的成本可能高达每月10万)。
应对

  • 资源隔离:用Kubernetes对不同数据产品的资源进行隔离,避免互相抢占;
  • 缓存优化:用Redis缓存常用指标(比如DAU),减少对Delta Lake的查询;
  • 按需缩放:用Serverless架构(比如AWS Lambda、阿里云函数计算)处理突发流量(比如大促期间的实时查询)。

五、未来趋势:数据产品的“智能化”与“嵌入式”

5.1 趋势1:AI原生数据产品

AI将深度融入数据产品,比如:

  • 智能查询:用自然语言查询数据(比如“最近7天DAU下降的原因是什么?”),AI自动生成SQL并返回结论;
  • 智能推荐:根据用户的查询历史,推荐相关指标(比如用户查了“DAU”,推荐“留存率”“转化率”);
  • 自动建模:AI自动分析数据,生成预测模型(比如预测“未来7天的DAU”)。

5.2 趋势2:嵌入式数据产品

数据产品将从“独立工具”转向“嵌入式功能”,比如:

  • 在CRM系统中嵌入“用户画像”,销售可以直接看到客户的“购买偏好”;
  • 在ERP系统中嵌入“库存预测”,采购可以直接看到“未来30天的库存需求”;
  • 在APP中嵌入“个性化推荐”,用户可以直接看到“感兴趣的商品”。

5.3 趋势3:隐私计算与数据安全

随着《个人信息保护法》《GDPR》的实施,数据产品需要更强的隐私保护:

  • 数据脱敏:对用户的敏感信息(比如手机号、身份证号)进行脱敏(比如“138****1234”);
  • 差分隐私:在数据中加入随机噪声,避免泄露个人信息;
  • 联邦学习:在不共享原始数据的情况下,多个机构联合训练模型(比如银行和电商联合做信用评分)。

六、工具与资源推荐

6.1 核心工具

  • 湖仓存储:Delta Lake、Apache Iceberg;
  • 流批计算:Apache Flink、Apache Spark;
  • 数据服务:Spring Boot、Hasura(GraphQL);
  • 元数据治理:Apache Atlas、Alation;
  • 可视化:ECharts、Apache Superset、Tableau;
  • 数据质量:Apache Great Expectations、Monte Carlo。

6.2 学习资源

  • 书籍:《数据产品经理实战手册》(苏杰)、《湖仓一体架构实践》(Databricks);
  • 博客:InfoQ大数据频道、Apache Flink官方博客;
  • 课程:Coursera《大数据架构与算法》、极客时间《数据产品思维课》;
  • 社区:Apache社区(https://apache.org/)、知乎“大数据”话题。

结语:从“管理数据”到“经营数据”

从传统数据管理到数据产品的转变,本质是思维的转变——从“我有什么数据”到“用户需要什么价值”,从“管理数据”到“经营数据”。

技术架构的演进是支撑,但更重要的是数据团队的角色升级

  • 从“数据工程师”变成“数据产品经理”:懂业务、懂用户、懂技术;
  • 从“数据管理者”变成“数据价值传递者”:把数据的价值“翻译”成业务能听懂的语言;
  • 从“一次性交付”变成“持续运营”:像运营APP一样运营数据产品,不断优化用户体验。

最后,用一句话总结:数据的价值,不是“存下来”,而是“用起来”——而数据产品,就是让数据“用起来”的最好方式

愿你在大数据的浪潮中,从“管理数据”的困境中突围,成为“经营数据”的高手。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/11 2:30:23

基于大数据的多目标推荐系统研究

基于大数据的多目标推荐系统&#xff1a;从原理到实践 摘要/引言 在当今信息爆炸的时代&#xff0c;推荐系统已成为众多互联网产品不可或缺的一部分。然而&#xff0c;传统的推荐系统往往只关注单一目标&#xff0c;如用户的购买意愿或内容的点击量。随着大数据的发展&#xff…

作者头像 李华
网站建设 2025/12/11 2:30:10

节拍和时钟周期

一、时序控制的层级架构&#xff1a;从指令周期到节拍为了管理复杂的指令执行过程&#xff0c;计算机架构师构建了一套严密的时序层级。这一层级结构是理解“节拍”概念的关键&#xff0c;也是中国经典计算机教材&#xff08;如唐朔飞版&#xff09;的核心理论框架 。2.1 第一层…

作者头像 李华
网站建设 2025/12/11 2:29:38

Wan2.2-T2V-5B能否生成书本翻页?纸质媒介动态还原测试

Wan2.2-T2V-5B能否生成书本翻页&#xff1f;纸质媒介动态还原测试 在数字内容爆炸式增长的今天&#xff0c;我们每天被成千上万的短视频包围。广告、教程、社交动态……几乎每个场景都要求“有画面”。但你知道吗&#xff1f;制作一段几秒钟的手翻书动画&#xff0c;传统流程可…

作者头像 李华
网站建设 2025/12/11 2:29:22

Wan2.2-T2V-5B推理延迟分解:瓶颈在哪里?

Wan2.2-T2V-5B推理延迟分解&#xff1a;瓶颈在哪里&#xff1f;从“说一句话出一段视频”说起 你有没有想过&#xff0c;输入一句“一只猫在太空站打太极”&#xff0c;几秒钟后就能看到一段流畅的短视频&#xff1f;这听起来像是科幻电影里的桥段&#xff0c;但如今&#xff0…

作者头像 李华
网站建设 2025/12/11 2:28:59

Wan2.2-T2V-5B在节庆主题视频中的创意应用合集

Wan2.2-T2V-5B在节庆主题视频中的创意应用合集 你有没有经历过这样的时刻——春节临近&#xff0c;品牌营销团队急着要10条“年味十足”的短视频&#xff0c;可剪辑师还在调色、特效师卡在动画渲染&#xff1f;时间紧、任务重、预算少……这几乎是每个节日季内容创作者的噩梦 …

作者头像 李华
网站建设 2025/12/11 2:28:51

Wan2.2-T2V-5B模型镜像下载及依赖环境配置全流程

Wan2.2-T2V-5B模型镜像下载及依赖环境配置全流程在短视频内容爆炸式增长的今天&#xff0c;你有没有遇到过这样的场景&#xff1a;市场部同事凌晨两点发来消息——“明天发布会要用的宣传视频&#xff0c;现在得加一个‘太空漫游’风格的版本”&#xff1f;&#x1f631; 而你手…

作者头像 李华