数据开发 L3:架构演进
资深数据工程师成长路线,学习平台架构设计、性能调优和数据治理,从开发者到架构师的进阶。
数据开发工程师 L3:架构演进#
[!quote] 写在前面 如果你正在读这篇文档,说明你已经在数据开发领域摸爬滚打了几年。你对数仓建模、Hive/Spark 已经相当熟练,日常工作得心应手。但你开始感到某种瓶颈:业务方要实时数据,现有的 T+1 架构满足不了;数据量越来越大,以前的优化手段不够用了;新技术层出不穷,Flink、数据湖、流批一体…你不确定该往哪个方向发力。
L3 阶段是一个分水岭。从这里开始,你不再只是”写代码的”,而是要开始思考”为什么这么做”、“有没有更好的架构”。这篇文档会帮助你理清这个阶段的学习重点,以及如何从”熟练工”进化为”架构师”。
这个阶段的你,可能是这样的#
画像一:业务要实时数据,但你只会离线#
老板说:“竞对的数据大屏是实时的,我们也要。“产品说:“用户下单后,5秒内就要在 APP 里看到状态更新。“你慌了——你的技能树全点在离线数仓上,Flink 只听过没用过,Kafka 只知道是个消息队列。
给你的建议:实时计算是 L3 阶段最重要的技能跃迁。好消息是,实时和离线的思维方式有很多相通之处。你在 Spark SQL 上的经验,可以快速迁移到 Flink SQL。建议从 Flink SQL 入手,先跑通一个简单的实时 ETL,再慢慢深入 DataStream API 和状态管理。
画像二:Spark 任务越来越慢,调参调不动了#
你负责的 Spark 任务,数据量翻了一倍,运行时间从 2 小时变成了 8 小时。你试了各种参数调优——增加 executor 数量、调整内存配比、调整 shuffle 分区数——但效果有限。你意识到,可能不是参数的问题,而是架构的问题。
给你的建议:到了 L3 阶段,“调参”已经不是主要手段了。你需要深入理解 Spark 的执行原理——Stage 是怎么划分的?Shuffle 数据是怎么落盘的?内存是怎么管理的?搞清楚这些,你才能从根本上解决问题,而不是在参数上碰运气。
画像三:想往架构师方向发展,但不知道从哪开始#
你听说高级别的岗位叫”数据架构师”,薪资很高,也很有技术含量。但你不知道架构师具体做什么,也不确定自己是否具备那些能力。你想往这个方向发展,但没有明确的路径。
给你的建议:架构师不是突然”升级”的,而是在日常工作中逐渐培养出来的。你可以从以下几个方面开始:
- 每次接需求时,多想想”有没有更好的架构方案”
- 主动参与系统设计评审,学习别人的设计思路
- 尝试写技术方案文档,把你的设计思考落到纸面上
- 关注业界的架构演进,了解为什么别人要这么设计
画像四:对数据治理没什么概念,感觉是”虚的”#
你听过数据质量、元数据管理、数据血缘这些词,但觉得这些是”管理层的事”,和写代码没什么关系。你的关注点一直在技术实现上,对治理体系不太上心。
给你的建议:数据治理绝对不是”虚的”。当你半夜被叫起来排查”数据怎么又错了”,当你花了三天才搞清楚一个字段的口径,当你的任务因为上游变更突然挂掉——这些都是缺乏治理的后果。L3 阶段,你需要开始建立治理思维:写代码的同时,思考如何让这套系统更可控、更可追溯、更少出问题。
L3 阶段的核心目标#
用一句话概括:
能够设计和落地复杂的数据架构,解决性能、时效、质量方面的核心挑战。
具体来说:
- 掌握实时计算技术,能构建秒级延迟的数据链路
- 深入理解计算引擎原理,能进行深度性能优化
- 能进行架构选型和设计,权衡各种方案的利弊
- 具备数据治理意识,能建立质量保障体系
L2 阶段你学会了”构建系统”,L3 阶段你要学会”设计架构”。构建是执行,架构是决策。
必须掌握的核心技能#
1. 实时计算 —— 从 T+1 到 T+0#
这是 L3 阶段最重要的能力跃迁。离线计算和实时计算是两种完全不同的思维方式。
离线 vs 实时的本质区别:
| 维度 | 离线计算 | 实时计算 |
|---|---|---|
| 数据特点 | 有界数据集 | 无界数据流 |
| 计算模式 | 批处理(一次处理所有) | 流处理(逐条/微批处理) |
| 时效性 | T+1 或更长 | 秒级/分钟级 |
| 容错方式 | 任务失败重跑 | Checkpoint + 状态恢复 |
| 核心挑战 | 数据量、计算效率 | 延迟、乱序、状态管理 |
为什么实时计算这么难?
离线计算处理的是”已经发生完”的数据,可以反复计算、校验。实时计算处理的是”正在发生”的数据,你不知道后面还有什么,而且必须快速响应。
几个核心挑战:
- 乱序问题:用户 10:00 的行为,可能 10:05 才到达系统。你该按发生时间算还是到达时间算?
- 状态管理:要算用户的累计消费额,必须存储历史状态。状态存在哪?多大?崩溃了怎么恢复?
- Exactly-Once:消息来了处理一半系统挂了,重启后怎么保证不丢不重?
Flink 核心概念:
- 时间语义:
// Event Time:事件发生时间(最常用,但需要处理乱序)
// Processing Time:处理时间(最简单,但结果不可复现)
// Ingestion Time:进入 Flink 的时间(折中方案)
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);java- Watermark(水位线):
Watermark 是处理乱序数据的核心机制。它告诉系统:“我认为时间戳小于这个值的数据都已经到齐了。”
// 假设数据最多乱序 5 秒
WatermarkStrategy
.<Event>forBoundedOutOfOrderness(Duration.ofSeconds(5))
.withTimestampAssigner((event, timestamp) -> event.getTimestamp());java- 窗口(Window):
// 滚动窗口:每 5 分钟一个窗口,窗口不重叠
stream.keyBy(e -> e.userId)
.window(TumblingEventTimeWindows.of(Time.minutes(5)))
.sum("amount");
// 滑动窗口:窗口大小 10 分钟,每 5 分钟滑动一次
stream.keyBy(e -> e.userId)
.window(SlidingEventTimeWindows.of(Time.minutes(10), Time.minutes(5)))
.sum("amount");
// 会话窗口:不活跃超过 30 分钟,窗口关闭
stream.keyBy(e -> e.userId)
.window(EventTimeSessionWindows.withGap(Time.minutes(30)))
.sum("amount");java- 状态(State):
// Keyed State:每个 Key 独立的状态
public class CountFunction extends KeyedProcessFunction<String, Event, Result> {
// 值状态:存储一个值
private ValueState<Long> countState;
// 列表状态:存储一个列表
private ListState<Event> historyState;
// Map状态:存储一个Map
private MapState<String, Long> detailState;
@Override
public void open(Configuration parameters) {
countState = getRuntimeContext().getState(
new ValueStateDescriptor<>("count", Long.class));
}
@Override
public void processElement(Event event, Context ctx, Collector<Result> out) {
Long count = countState.value();
if (count == null) count = 0L;
count++;
countState.update(count);
// ...
}
}java- Checkpoint:
Flink 通过定期做快照(Checkpoint)来保证容错。任务崩溃后可以从最近的 Checkpoint 恢复。
// 启用 Checkpoint,每 60 秒一次
env.enableCheckpointing(60000);
// Exactly-Once 语义(更安全,但更慢)
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
// At-Least-Once 语义(更快,但可能重复)
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.AT_LEAST_ONCE);javaFlink SQL —— 快速入门实时计算:
如果你已经熟悉 SQL,Flink SQL 是最快的入门方式。
-- 创建 Kafka 源表
CREATE TABLE order_source (
order_id STRING,
user_id STRING,
amount DECIMAL(10,2),
order_time TIMESTAMP(3),
WATERMARK FOR order_time AS order_time - INTERVAL '5' SECOND
) WITH (
'connector' = 'kafka',
'topic' = 'orders',
'properties.bootstrap.servers' = 'localhost:9092',
'format' = 'json'
);
-- 实时聚合:每分钟的订单统计
SELECT
TUMBLE_START(order_time, INTERVAL '1' MINUTE) as window_start,
COUNT(*) as order_cnt,
SUM(amount) as total_amount
FROM order_source
GROUP BY TUMBLE(order_time, INTERVAL '1' MINUTE);sql推荐学习:实时数据架构 ↗
[!warning] 实时计算的坑 实时任务一旦上线,就是 7x24 小时运行的。和离线任务不同,你没法说”今晚重跑一下就好了”。所以:
- 一定要做好监控和报警
- 状态不能无限增长,要设置 TTL
- 要考虑好 Schema 变更怎么处理
- 要有回溯方案(从某个时间点重新消费 Kafka)
2. 数据湖与湖仓一体 —— 架构的下一站#
传统数据仓库有一些固有的问题:
- 不支持 ACID 事务,数据更新只能全量覆盖
- 只能存储结构化数据,非结构化数据没法处理
- Schema 强绑定,修改表结构很痛苦
数据湖技术(Hudi、Iceberg、Delta Lake)就是为了解决这些问题。
核心能力对比:
| 特性 | 传统 Hive | 数据湖(Hudi/Iceberg) |
|---|---|---|
| ACID 事务 | 不支持 | 支持 |
| 增量更新 | INSERT OVERWRITE | UPSERT/DELETE |
| Schema 演进 | 困难 | 支持 |
| 时间旅行 | 不支持 | 支持(查历史快照) |
| 存储格式 | Parquet/ORC | Parquet + 元数据 |
Hudi 核心概念:
Copy-on-Write (COW):
- 写入时复制整个文件
- 读取性能好(直接读 Parquet)
- 写入性能差(要重写文件)
- 适合读多写少的场景
Merge-on-Read (MOR):
- 写入时只追加 Delta 文件
- 写入性能好
- 读取时需要合并(读性能略差)
- 适合写多读少的场景plaintext实际应用场景:
-- Hudi 表创建示例
CREATE TABLE hudi_order (
order_id STRING,
user_id STRING,
amount DECIMAL(10,2),
status STRING,
update_time TIMESTAMP
) USING hudi
OPTIONS (
'primaryKey' = 'order_id',
'type' = 'cow',
'preCombineField' = 'update_time'
);
-- 支持 UPSERT(有则更新,无则插入)
MERGE INTO hudi_order target
USING source_data source
ON target.order_id = source.order_id
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *;
-- 时间旅行:查询昨天的数据快照
SELECT * FROM hudi_order TIMESTAMP AS OF '2024-06-14';sql湖仓一体架构:
传统架构:
数据源 → 数据湖(原始存储) → 数据仓库(分析)
↑ 两套系统,数据要搬来搬去
湖仓一体:
数据源 → 数据湖 + 仓库能力(一套系统搞定)
↑ 存储和计算分离,同一份数据支持批/流/交互式分析plaintext推荐学习:数据仓库与数据湖建模 ↗ → 云原生数据架构 ↗
3. 深度性能优化 —— 从调参到调架构#
L2 阶段的优化主要是”调参”,L3 阶段要深入到原理层面。
Spark 执行原理深度解析:
一个 Spark SQL 的执行过程:
SQL 语句
↓ 解析
逻辑计划(Logical Plan)
↓ 优化器(Catalyst)
优化后的逻辑计划
↓ 物理计划生成
物理计划(Physical Plan)
↓ 代码生成(Codegen)
RDD 执行图
↓ DAGScheduler
Stage 划分(以 Shuffle 为边界)
↓ TaskScheduler
Task 分发到 Executor 执行plaintext几个关键优化点:
- 减少 Shuffle:
Shuffle 是分布式计算中最昂贵的操作。数据要写磁盘、通过网络传输、再读出来合并。
-- 不好的写法:两次 Shuffle
SELECT a.user_id, b.order_cnt, c.pay_amount
FROM users a
JOIN (
SELECT user_id, COUNT(*) as order_cnt
FROM orders
GROUP BY user_id
) b ON a.user_id = b.user_id
JOIN (
SELECT user_id, SUM(amount) as pay_amount
FROM payments
GROUP BY user_id
) c ON a.user_id = c.user_id;
-- 优化后:合并子查询,减少 Shuffle
SELECT
a.user_id,
COUNT(DISTINCT o.order_id) as order_cnt,
SUM(p.amount) as pay_amount
FROM users a
LEFT JOIN orders o ON a.user_id = o.user_id
LEFT JOIN payments p ON a.user_id = p.user_id
GROUP BY a.user_id;sql- 利用分区裁剪:
-- 不好的写法:全表扫描
SELECT * FROM orders WHERE order_date >= '2024-06-01';
-- 好的写法:如果 dt 是分区字段,只扫描需要的分区
SELECT * FROM orders WHERE dt >= '2024-06-01';sql- 避免数据膨胀:
-- 危险的写法:笛卡尔积
SELECT a.*, b.*
FROM table_a a
JOIN table_b b
ON a.key = b.key AND a.key IS NULL;
-- 如果 a.key 有很多 NULL,会产生笛卡尔积
-- 更危险的写法:CROSS JOIN
SELECT * FROM table_a CROSS JOIN table_b;
-- 1万行 x 1万行 = 1亿行sql- AQE(Adaptive Query Execution):
Spark 3.0 引入的自适应查询执行,可以在运行时动态调整执行计划。
-- 启用 AQE
SET spark.sql.adaptive.enabled = true;
-- 自动合并小分区(避免大量小文件)
SET spark.sql.adaptive.coalescePartitions.enabled = true;
-- 自动处理数据倾斜
SET spark.sql.adaptive.skewJoin.enabled = true;sqlJVM 层面的优化:
# Executor 内存配置
--executor-memory 8g
--conf spark.executor.memoryOverhead=2g
# 内存管理
--conf spark.memory.fraction=0.6 # 执行+存储内存占比
--conf spark.memory.storageFraction=0.5 # 存储内存占比
# GC 优化
--conf spark.executor.extraJavaOptions="-XX:+UseG1GC -XX:MaxGCPauseMillis=200"bash推荐学习:性能优化 ↗
[!tip] 性能优化的正确姿势 不要盲目优化。正确的流程是:
- 定位瓶颈:看 Spark UI,找出最慢的 Stage
- 分析原因:是数据倾斜?是 Shuffle 太多?是内存不够?
- 针对性优化:根据原因选择合适的优化手段
- 验证效果:对比优化前后的执行时间和资源消耗
4. 数据治理 —— 从混乱到有序#
L3 阶段,你要开始建立治理思维。这不是管理层的事,而是架构设计的一部分。
数据质量管理:
数据质量问题的代价是巨大的。我见过因为一个字段口径错误,导致财务报表偏差几百万;见过因为数据延迟,导致运营活动失败。
质量检查的几个维度:
| 维度 | 含义 | 检查方法 |
|---|---|---|
| 完整性 | 数据是否缺失 | NULL 值比例、行数波动 |
| 准确性 | 数据是否正确 | 业务规则校验、交叉验证 |
| 一致性 | 不同数据源是否一致 | 核对关键指标 |
| 时效性 | 数据是否及时 | 监控任务延迟 |
| 唯一性 | 是否有重复数据 | 主键去重检查 |
-- 数据质量检查示例
-- 完整性检查:关键字段 NULL 比例
SELECT
COUNT(*) as total,
SUM(CASE WHEN user_id IS NULL THEN 1 ELSE 0 END) as null_cnt,
SUM(CASE WHEN user_id IS NULL THEN 1 ELSE 0 END) / COUNT(*) as null_ratio
FROM dwd_order_detail
WHERE dt = '${bizdate}';
-- 一致性检查:订单金额和支付金额是否匹配
SELECT
SUM(order_amount) as order_sum,
SUM(pay_amount) as pay_sum,
ABS(SUM(order_amount) - SUM(pay_amount)) / SUM(order_amount) as diff_ratio
FROM ads_daily_summary
WHERE dt = '${bizdate}';
-- 唯一性检查:主键是否重复
SELECT order_id, COUNT(*) as cnt
FROM dwd_order_detail
WHERE dt = '${bizdate}'
GROUP BY order_id
HAVING cnt > 1;sql元数据管理与数据血缘:
当你有几千张表时,“这个字段是从哪里来的”就成了一个大问题。
数据血缘的价值:
1. 影响分析:修改一张表前,知道会影响哪些下游
2. 问题追溯:数据错了,能快速定位是哪个环节出问题
3. 口径统一:知道每个指标是怎么算出来的plaintext成本治理:
大数据计算资源很贵。L3 工程师要有成本意识。
成本优化的几个方向:
1. 资源利用率:任务申请 100G 内存,实际只用 20G
2. 存储优化:历史数据压缩、冷热分层
3. 计算优化:避免重复计算,合理设置任务周期
4. 淘汰无用数据:很多表几个月没人用了,占着资源plaintext推荐学习:数据质量管理体系与实践 ↗ → 数据开发文档管理 ↗
5. 云原生与容器化 —— 需要学吗?#
你可能听说”现在都上 K8s 了”、“不会云原生找不到工作”。这里帮你理清。
什么情况下需要学 Kubernetes?
| 你的情况 | K8s 是否必要 | 建议 |
|---|---|---|
| 公司数据平台部署在 K8s 上 | 需要 | 至少能看懂 YAML、会用 kubectl |
| 公司还是传统 YARN 集群 | 暂不必要 | 先把当前技术栈学精 |
| 想做数据平台架构师 | 必须学 | 云原生是未来趋势 |
| 只做 ETL 开发 | 不必要 | 平台运维有专人负责 |
L3 阶段需要了解的程度:
基本概念(必须知道):
- Pod:K8s 最小调度单位
- Deployment:管理 Pod 副本
- Service:服务发现和负载均衡
- ConfigMap/Secret:配置管理
实操技能(按需学习):
- 能看懂 Spark/Flink on K8s 的 YAML 配置
- 能用 kubectl 查看日志、排查问题
- 理解 Spark on K8s 和 Spark on YARN 的区别plaintext云原生 vs 传统方案对比:
| 组件 | 传统方案 | 云原生方案 |
|---|---|---|
| 计算引擎 | Spark on YARN | Spark on K8s |
| 实时引擎 | Flink on YARN | Flink Kubernetes Operator |
| 消息队列 | 自建 Kafka 集群 | Kafka on K8s / 云托管 |
| 存储 | HDFS | S3 / OSS / MinIO |
[!tip] 务实建议 不要为了学 K8s 而学 K8s。如果你当前工作用不到,先把实时计算、架构设计这些核心技能学好。当公司开始做云原生转型时,再深入也不迟。
6. AI 时代对 L3 工程师的影响#
L3 阶段,你需要思考 AI 对数据工程的影响——不是焦虑”会不会被取代”,而是思考”如何利用”。
AI 能帮 L3 工程师做什么?
| 场景 | AI 能做 | 你必须做 |
|---|---|---|
| 架构设计 | 列出方案选项、分析优缺点 | 结合公司情况做最终决策 |
| 技术选型 | 比较 Flink vs Spark 特点 | 考虑团队能力、运维成本 |
| 性能调优 | 分析执行计划、建议方向 | 验证效果、处理边界情况 |
| 代码编写 | 生成 Flink/Spark 代码框架 | Review 逻辑、处理异常 |
AI 替代不了什么?
- 架构决策:需要结合公司实际情况权衡
- 深度调优:复杂问题需要深入理解原理
- 业务理解:数据模型设计需要理解业务
- 故障处理:线上问题需要快速判断和决策
关于 MLOps / 特征工程:
L3 阶段你可能开始接触 ML 相关需求(特征计算、数据集准备)。了解基本概念有帮助,但不是必须——除非你的工作方向明确是 ML 平台开发。
[!note] 核心观点 AI 时代,L3 工程师的价值在于:架构决策能力 + 深度问题解决能力 + 业务理解能力。这些恰恰是 AI 做不好的。把 AI 当高效工具用,同时深耕这些核心能力。
架构选型的思考框架#
L3 阶段,你经常要做架构选型。这里提供一个思考框架:
Lambda 架构 vs Kappa 架构#
Lambda 架构:
数据源
↓
┌────┴────┐
批处理层 实时处理层
└────┬────┘
↓
服务层
优点:批处理保证准确性,实时满足时效性
缺点:两套代码,维护成本高
Kappa 架构:
数据源 → 消息队列 → 实时处理 → 服务层
↑
重放(回溯)
优点:一套代码,架构简单
缺点:对实时引擎要求高,历史重算成本高plaintext如何选择?
- 如果团队实时能力强,数据量不是特别大,Kappa 更简单
- 如果需要复杂的批处理逻辑,或者需要经常回算历史,Lambda 更稳妥
- 很多公司采用”伪 Lambda”:实时链路用 Flink,每天跑批任务修正数据
选型决策清单#
每次做技术选型时,问自己这些问题:
- 业务需求:时效性要求多高?数据量有多大?准确性要求多高?
- 团队能力:团队熟悉什么技术栈?能否支撑新技术的运维?
- 运维成本:这个技术生态是否成熟?出了问题能否快速定位?
- 可扩展性:未来数据量增长 10 倍,这个架构还能撑住吗?
- 成本:计算资源、存储资源、人力成本各是多少?
[!warning] 技术选型的陷阱 不要为了用新技术而用新技术。我见过很多团队,业务场景明明用 Hive 就够了,非要上 Flink;数据量明明不大,非要搞分布式。结果运维成本大增,效率反而下降。选型要基于问题,而不是基于技术流行度。
你可能会遇到的困难#
”Flink 学了很多,但工作中用不上”#
你的公司可能还是以离线为主,没有实时业务场景。
解决方案:
- 主动找实时场景——实时监控大屏、实时推荐、实时风控,很多业务其实有需求,只是没人做
- 如果公司确实没有,可以考虑换一个有实时业务的平台历练
- 至少保持学习,技术储备在,机会来了才能抓住
”感觉自己只会 CRUD,没有架构能力”#
架构能力不是天生的,是在实践中培养出来的。
培养方法:
- 每次设计前,先画架构图,和团队讨论
- 多看别人的系统是怎么设计的(开源项目、技术博客、架构书籍)
- 主动参与系统重构,这是最好的架构训练
- 复盘出过的问题,思考”如果重新设计,怎么避免这个问题"
"数据治理不知道从哪开始”#
数据治理是一个体系工程,不要指望一步到位。
建议的起步方式:
- 从数据质量开始——先把关键表的质量检查做起来
- 建立基本的监控告警——任务失败、数据异常要能及时发现
- 梳理核心链路的血缘——至少知道核心报表是从哪些表算出来的
- 逐步完善,不要追求完美
”不确定要不要深入源码”#
源码阅读是一个争议话题。有人觉得必须读,有人觉得没必要。
我的建议:
- 不需要通读全部源码,那是不可能的任务
- 但关键模块要理解——比如 Spark 的 Shuffle 实现、Flink 的 Checkpoint 机制
- 遇到诡异问题时,源码是最终的答案
- 如果想往架构师方向发展,源码阅读能力是必备的
L3 阶段可以胜任的岗位#
完成 L3 阶段的学习后,你可以胜任:
高级数据开发工程师
- 主要工作:核心数据系统开发、性能优化、架构设计
- 薪资参考:一线城市 35-55K,二线城市 25-40K
- 面试重点:实时计算、性能调优、架构设计能力
实时计算工程师
- 主要工作:实时数据链路建设、Flink/Kafka 集群运维
- 特点:专注实时领域,技术深度要求高
数据架构师(初级)
- 主要工作:数据平台架构设计、技术选型、标准制定
- 特点:从执行转向规划,需要更广的技术视野
[!note] L3 的瓶颈 L3 是一个比较难突破的阶段。很多人会在这个阶段停留很长时间。突破的关键是:
- 不要只做自己熟悉的事,要主动接触新领域
- 培养系统性思维,从全局看问题
- 提升表达和沟通能力,好的架构需要”卖出去”
给 L3 学习者的真诚建议#
1. 深度和广度要平衡#
L3 阶段容易走两个极端:要么只钻一个方向,要么什么都想学。正确的做法是:在某一个领域(比如实时计算)建立深度,同时保持对其他领域的了解。
2. 从”解决问题”到”预防问题”#
L2 阶段你学会了解决问题,L3 阶段要学会预防问题。设计架构时,要思考:这个系统可能出什么问题?如何提前规避?
3. 开始建立影响力#
L3 阶段,你应该开始在团队内建立技术影响力:
- 做技术分享,把你的经验传播出去
- 写技术文档,让后来者少走弯路
- 参与招聘,帮助团队识别人才
- 指导新人,在教的过程中深化理解
4. 保持对业务的敏感度#
技术最终是为业务服务的。不要只顾着研究技术,要理解业务目标是什么、数据是如何产生价值的。能用技术解决业务问题的人,永远比只会技术的人更有价值。
接下来#
当你能够独立设计复杂的数据架构,有这样的困惑时:
- “我应该如何规划整个公司的数据平台?”
- “团队该怎么组建?流程该怎么设计?”
- “数据平台的 ROI 应该怎么衡量?”
- “新技术那么多,应该投入多少资源跟进?”
恭喜你,你已经准备好进入下一个阶段了。
➡️ L4:技术战略 ↗ —— 技术管理、平台规划、组织建设
相关资源:
- 实时数据架构 ↗ —— 实时计算架构设计
- 数据仓库与数据湖建模 ↗ —— 数据湖技术详解
- 性能优化 ↗ —— Spark/Flink 性能调优
- 数据质量管理体系与实践 ↗ —— 数据治理方法论
- L2:核心构建 ↗ —— 如果数仓基础不够扎实,可以回顾