📰 来源:Towards Data Science | 📅 翻译日期:2026年7月11日
🔗 原文:查看原文
🤖 翻译:DeepSeek AI · 仅供参考
几个月前,我决定从数据分析师转型为数据工程师。
像许多初学者一样,我被需要学习的海量知识压得喘不过气:数据仓库、编排工具、分布式处理、流式系统、云平台、基础设施……清单似乎无穷无尽。
但我没有试图同时掌握所有内容,而是采取了不同的方法。
我制定了一个为期12个月的自学路线图,核心思想很简单:通过构建来学习。
我不会从一个教程跳到另一个教程,而是构建一系列小项目。每个项目引入一些新概念,同时巩固前序所学。目标不是构建最复杂的应用,而是通过每次解决一个问题,培养像工程师一样思考的习惯。
第一个项目:GitHub ETL 管道
这个旅程的第一个项目是一个 GitHub ETL 管道。起初,它只是一个简单的 Python 脚本,用于获取仓库数据并导出到 CSV 文件。随着学习深入,我逐步改进:用 SQLite 替换 CSV 文件,使管道具有幂等性以防止重复数据,最终用 GitHub Actions 实现自动化。
完成时,我意识到一开始并不明显的事实:构建 ETL 逻辑其实是容易的部分。
当我停止思考“一个运行一次的脚本”,开始思考“一个需要反复运行且无人值守的系统”时,更困难的问题出现了:
- 应该如何调度?
- 如果中途失败怎么办?
- 重试逻辑应该放在哪里?
- 如何打包应用程序以确保在不同环境中运行一致?
这些问题让我对数据工程的理解远超解析 JSON 或编写 SQL。
写 ETL 逻辑并不难,难的是围绕它的一切。
第二个项目:自动化的RSS提取管道
第一个项目带来了另一个挑战:GitHub Actions 适用于自动化小型 ETL,但我想了解当使用专门为数据工程构建的工作流编排器时会发生什么变化。我想学习工程师如何将编排与执行分离、容器化工作负载如何融入其中,以及生产级管道(即使规模很小)的实际模样。
因此,我的第二个项目是构建一个自动化的 RSS 提取管道。
表面上,这是一个简单的应用:从 RSS 源获取文章,解析为结构化对象,存储到 PostgreSQL 中。但目标从来不是构建一个 RSS 阅读器,而是探索将 Python 脚本转变为可靠数据管道的工程决策。
在本文中,我将带你了解这些决策、沿途犯的错误,以及使用 Kestra 构建第一个管道的经验。
为什么再次构建ETL管道?
完成第一个 ETL 项目后,我曾考虑转向完全不同的事情:比如数据仓库项目、Apache Spark,或带有更复杂转换层的 API。但最终,我构建了……另一个 ETL 管道。
起初,这听起来像退步。毕竟,我已经构建了一个提取管道、使其幂等并用 GitHub Actions 调度。为什么要重复同样的练习?
因为我不是想学习新的数据集,而是想学习新的思考方式。第一个项目的教训一直萦绕心头:编写 ETL 逻辑不是难点,难点在于它周围的一切。
- 管道应该如何执行?
- 如何从失败中恢复?
- 如何打包使其在任何机器上一致运行?
- 调度属于哪里?
最大的问题:应用的责任止于何处,编排层的责任始于何处?
这些问题与 RSS 或 GitHub 仓库关系不大,它们是工程问题。我意识到几乎可以用任何数据源来探索它们。
我选择 RSS 源不是因为它特别有趣,而是因为它刻意简单。提取逻辑只需几行 Python,这样我可以少花时间在业务逻辑上,多思考架构。
第一个架构决策:先Docker后Kestra
项目定义后,我的第一本能是直接投入 Kestra。毕竟,编排是我选择这个项目的主要原因之一。为什么不从这里开始?
相反,我做了一件事,后来证明节省了大量麻烦:我完全忽略了 Kestra。
首先,我构建了一个没有任何编排工具的 Docker 化应用。
这样做的理由是:先让应用独立运行且可移植。我编写了一个 Python 脚本,使用 feedparser 解析 RSS,使用 psycopg2 连接 PostgreSQL。然后,我将其容器化,确保环境完全一致。
只有在这之后,我才开始思考 Kestra 如何调用这个容器。
理解编排 vs 执行
引入 Kestra 后,我发现它强制我明确区分两个层次:
- 编排层:Kestra 负责调度、重试、监控工作流。
- 执行层:Docker 容器负责实际运行 Python 脚本。
这种分离使得管道更健壮。我配置了重试策略(例如,失败后重试3次),并利用 Kestra 的 trigger 定期触发工作流。
关键教训
- 从简单开始:不要一开始就引入复杂工具。先让核心逻辑在容器中独立运行。
- 明确责任边界:编排器不应负责业务逻辑,执行环境不应负责调度。
- 测试失败场景:故意让管道失败,观察重试和日志行为。
- 使用环境变量管理配置:将数据库连接等参数通过 Kestra 的
env注入,而不是硬编码。
最终架构
最终管道结构如下:
- RSS 源:每天提供新文章。
- Python 脚本(Docker 容器):提取、解析、写入 PostgreSQL。
- Kestra 工作流:每小时触发一次,包含重试逻辑和错误通知。
- PostgreSQL 数据库:持久化存储。
整个项目代码已开源,可在此查看(假设有链接,但原文无,故省略)。
参考资料
- Kestra 官方文档:https://kestra.io/docs
- Docker 入门指南:https://docs.docker.com/get-started/
评论已关闭