数据工程师到底要会多少东西?从 Kafka 12 个分区到 Flink 反压,我把六年的坑翻了一遍

🔑 关键词:数据工程师,ETL,Flink,数据仓库,职业发展

📖 摘要:一个干了六年的数据工程师,拆解同岗位在三类公司的真实差异,算清实时链路和离线链路的成本账,并给出三个判断自己卡在哪一层的自测题。

上周三晚上十一点,我盯着 Grafana 上那条一路往上爬的消费延迟曲线,第三次在心里问自己为什么要干这行。

图片

出问题的 topic 是两年前建的,12 个分区。当时日均 300 万条消息,富余得很。现在峰值每秒 8000 条,12 个分区里固定有三个在滞后——不是流量均匀打上来的,是 key 分布不均,两个大客户的数据全压在同一个分区里。方案很清楚:扩到 48 个分区,下游 Flink 并行度跟着调,重算状态大小,顺便把 key 策略改掉。代价也很清楚:要停消费,大概两个小时的窗口,得提前一周约运维,还要通知六个下游团队。这种活招聘 JD 里一个字都不会提,但它大概占到数据工程师真实工作量的四成。另外六成是开会、写文档、以及跟业务解释为什么昨天那张表的数据不对。

同一个 title,三种人生

我干这行六年,待过三家公司,见过三类几乎完全不同的「数据工程师」。

第一类在二十来人的公司,一个人从 MySQL binlog 接到 ClickHouse,顺手把 BI 也做了,报表和取数共用同一个只读账号。他的日常是写 SQL、加字段、被业务追着问「这个数为什么对不上」。技术栈窄,但业务理解极深,哪张表该跟哪张表 join、哪个字段有脏数据,他门儿清。

图片

第二类在中型公司,团队 8 到 15 人,Airflow(现在可能换 Dagster 了)加 dbt 加 Snowflake 或 BigQuery 或 Doris,上游接埋点和业务库,下游供分析师和算法。日常一半时间在写模型,一半时间在跟业务对口径,还要处理「这个指标上周还是 3.2% 这周怎么 5.8% 了」这种问题。

第三类在大厂或基础架构团队,日常是读 Flink 源码、改 Iceberg 的 manifest 合并策略、跟存储团队掰扯对象存储的 list 性能。SQL 写得少,Java 或者 Scala 写得多,一年可能只交付两三个「项目」,但这两个项目底下撑着几百个下游任务。

这三类人的技能重叠度,说实话不到 30%。但招聘网站挂着同一个词。所以每次有人问我「数据工程师要会什么」,我都觉得这问题没法直接答,得先问他要去哪一类。我最烦那种「数据工程师必须掌握的 20 项技能」的清单,看完除了焦虑什么也留不下。

实时那条链路,到底值不值

图片

有个账我觉得很少有人摊开算。离线链路和实时链路的成本结构,根本不是一回事。

离线:假设每天凌晨跑三个小时,一百来个 Spark 任务,跑完就下掉。云上按秒计费,一天真正烧钱的时间可能就六小时,剩下十八小时那批机器在干别的,或者压根没开。

实时:Kafka 集群 7×24 常驻,Flink 作业 7×24 常驻,checkpoint 每 30 秒往对象存储写一次状态——我们那条链路单个 checkpoint 峰值到过 400MB,一天下来光状态文件就是几个 T。这还没算为了压延迟做的那些额外操作,比如把 state backend 从 FileSystem 换成 RocksDB、开增量 checkpoint、调大网络缓冲。

业务侧真正需要秒级的场景有多少?我经历过的项目里,掰手指头数得出来:风控拦截、库存扣减、部分营销触发,就这些。剩下那些所谓实时需求,本质是离线那张表早上九点还没跑完,业务等不及了。那是调度和依赖治理的问题,不是实时的问题。

图片

我自己的判断标准一直没变过:决策窗口小于 15 分钟,才值得上实时链路。15 分钟到 1 小时,微批或者十分钟一次的调度完全够用。超过 1 小时的,老老实实做离线,把 SLA 做稳比什么都强。有次我跟一个产品经理讲这个,他反问「那实时大屏呢」。大屏不算决策,算装修。这话说出来有点欠揍,但我是真这么想的。

真正的护城河不是技术广度

六年里我换过的技术栈能列一长串:Hive 到 Spark SQL 到 Flink SQL,Sqoop 到 DataX 到 CDC,Oozie 到 Airflow 到 Dagster。API 该弃用的弃用,该重写的重写,光 Spark 从 2.x 到 3.x 那波 AQE 的默认值调整,就够我改一遍所有任务的参数。技术广度这东西,贬值速度比想象中快。

图片

我觉得真正留下来的只有两样。一样是故障直觉。看到消费延迟上涨,你会先去看分区分布、GC 日志还是下游写库的 RT?看到 Spark 任务从 20 分钟变成 90 分钟,你会先怀疑数据倾斜、小文件,还是 executor 内存不够?这种判断力没法从文档里学,只能被线上事故一次次打出来。

另一样是成本直觉。我见过一个分区底下攒了 9 万个小文件,每个几十 KB,光 namenode 的压力就够呛,合并的时候 executor 直接 OOM。也见过有人把 Spark 的 advisoryPartitionSizeInBytes 从默认 64MB 无脑调到 512MB,结果单个 task 处理 8GB 数据,一路 spill 到磁盘。这些数字背后都是钱和时间,知道往哪调、调多少,这比会写多少种 SQL 语法值钱得多。

三个自测题

如果你不确定自己现在卡在哪一层,可以用这三个问题试一下。

图片

一,给你一个空白的环境,不考虑成本,你能从零把一条链路搭起来吗?从采集、入湖、建模到对外供数。搭不出来,说明还停在执行层。

二,把现有链路的成本砍掉一半,你知道从哪下手吗?先看存储还是先看计算,先动调度频率还是先动数据生命周期,心里有没有一个优先级排序。答不上来,说明你对系统的理解还是黑盒。

三,线上出问题的时候,你是先打开日志,还是先打开监控看板?如果是前者,你可能还在「救火」,没到「预判」。

写完发现有点跑题了,本来想聊技术选型的,结果聊成了职业感受。不过想想也正常,这行干久了,技术问题到最后多半是人的问题和钱的问题。今晚那条延迟曲线已经降下去了,扩分区的事排在下周三。

🏷️ 标签: