数据管道架构是一组组件及其运行顺序,负责将数据从产生之处传输至使用之处。架构设计合理,分析师无需关心数据如何到达,便能查询到最新、可信的数据表;设计不当,你则会花费整周时间追查缺失的行、格式错误的字段以及悄然停止执行的作业。本指南是面向工程师的架构概念指引:包括标准阶段、批处理与流处理、整体编排方式、可观测性保障,以及网页抓取数据在其中的位置。

本文的框架刻意注重实践性。大多数管道图在白板上看起来整洁,但当上游数据源变更其模式或第三方网站屏蔽数据收集器时,往往不堪一击。因此,本文在介绍清晰模型的同时,也涵盖了实际容易出问题的部分,并将采集层(外部数据进入系统的入口)视为头等关注点,而非事后补充。

数据管道架构究竟是什么

从核心来看,数据管道是一种有向流:数据进入,经过一系列转换,最终落入可供读取的位置。架构是围绕这一流程的契约:哪些数据源馈入其中,每个阶段保证什么,如何处理故障,以及整个流程如何被调度和监控。这是一次性脚本与凌晨三点仍可依赖的系统之间的区别。

将其视为架构而非胶水代码的价值在于整合与统一。真正的管道从多个数据源(包括数据库、API、事件流和抓取的网页)拉取数据,并将所有数据重塑为一个地方的统一格式。这个单一漏斗让团队无需手动协调五种不同结构便能跨源查询,也降低了原始数据到达与洞察产出之间的摩擦。

数据管道的各个阶段

几乎所有管道,无论使用何种工具,都按照相同的标准阶段顺序运行。各团队的命名不尽相同,但顺序不变:

  • 采集/收集。 数据从其数据源进入管道:操作性数据库、第三方 API、事件流、文件以及网页。这是原始记录最初落地的地方,通常是在任何处理之前先进入暂存区。
  • 处理/转换。 原始数据经过清洗、标准化、验证、去重,跨源合并,并重塑为下游消费者所期望的模式。单位、日期和类别在此处进行规范化,损坏或无效的记录被修正或丢弃。
  • 存储。 转换后的数据被写入持久化目标,通常是数据仓库、数据湖或两者兼有。这是所有下游读取的系统记录。
  • 服务/分析。 存储的数据被暴露给其消费者:BI 仪表板、即席 SQL、机器学习训练任务、反向 ETL 回传至运营工具,或某个 API。这个阶段证明了其他所有阶段的存在价值。

有两个横切关注点贯穿每个阶段,而不是位于阶段之间。编排决定每个步骤何时运行以及按什么顺序运行,监控则验证每个步骤是否完成了其声称的工作。两者都不是你一次性经过的阶段,而是在管道的整个生命周期内持续运作。下文将分别介绍。

四个阶段,依次排列。 数据从左到右流经采集、处理、存储和服务阶段,而编排与监控在管道的整个生命周期内贯穿所有阶段。

ETL 与 ELT:转换发生在哪里

经典模型是 ETL:提取(Extract)、转换(Transform)、加载(Load)。你从数据源中拉取数据,在专用处理层中重塑,然后将完成的结果加载到数据仓库中。它使仓库保持整洁,但转换逻辑位于仓库之外。

现代默认方式已转变为 ELT:提取(Extract)、加载(Load)、转换(Transform)。你先将原始数据落地到云数据仓库,然后用 SQL 在原地进行转换。存储成本已足够低廉,保留原始数据是值得的,因为当需求变更时,你可以重新推导任何表格,而无需重新从数据源收集。对于抓取的数据,这一点尤为重要:重新运行转换是免费的,但重新爬取你不再能访问的网站则不然。保留你收集的原始 HTML 或 JSON,ELT 让你在几个月后修复解析错误时无需再次访问数据源。

批处理与流处理

最重要的架构分叉是数据移动的频率。批处理管道在一个窗口(一小时、一天、一次固定运行)内收集数据,并将其作为一组进行处理。这种方式更易于推理,运营成本更低,易于重新处理,适合绝大多数分析工作。如果目标是每日销售汇总,批处理几乎总是正确答案。

流处理管道持续处理记录,逐事件处理,通常通过 Kafka 或同等的托管服务传递。当新鲜度本身就是产品时,你才需要流处理:欺诈检测、实时定价、实时竞争对手监控,以及任何一小时前的答案就是错误答案的场景。然而代价是真实的:流处理系统更难测试,更难重新处理,并且从第一天起就需要考虑迟到和乱序事件。

许多成熟的系统同时运行两种模式:为少数需要实时的指标建立流处理路径,其余一切使用批处理路径,通常保留原始数据以便在不重新收集的情况下回答新问题。选择满足实际新鲜度要求的最简单模型,不要为明天才有人看的数字引入流处理。

延迟是需求,不是默认值

在选择流处理之前,用具体数字写下业务实际所需的新鲜度。"五分钟内"和"明天早上之前"会导致完全不同的架构、运营成本和值班负担。大多数团队高估了数据需要多新鲜,并为从未用到的流处理复杂性付出代价。

编排与调度

一旦有了多个步骤,就需要有东西来决定什么运行、按什么顺序、以及步骤失败时发生什么。这就是编排,是管道的神经系统。调度器根据节奏或事件触发作业;编排器对作业之间的依赖关系建模,使转换只在其采集成功后才运行,并使故障停止所有下游执行,而不是向前传播错误数据。

在实践中,这是一个有向无环图(DAG):每个节点是一个任务,每条边是一个依赖关系,编排器遍历图,重试瞬时故障并暴露永久故障。Airflow、Dagster 和 Prefect 等工具正是为此而生。架构要点独立于工具:自动化调度使运行可重复,使依赖关系明确以便故障得以遏制,并使整个图具有幂等性,使重新运行产生相同结果而不是重复计数。

以下是一个每日 DAG 的最小框架,收集、转换和加载的编排形状,而非生产代码:

python
from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime

with DAG(
    dag_id='market_prices',
    schedule='@daily',
    start_date=datetime(2026, 1, 1),
    catchup=False,
) as dag:
    ingest = PythonOperator(task_id='ingest', python_callable=collect_pages)
    transform = PythonOperator(task_id='transform', python_callable=clean_and_parse)
    load = PythonOperator(task_id='load', python_callable=write_to_warehouse)

    ingest >> transform >> load

>> 运算符声明了依赖链:transform 等待 ingestload 等待 transform。如果采集失败,下游的任何任务都不会运行,这正是你所期望的行为。

监控与数据质量

无法观察的管道是无法信任的管道。监控分为两个容易混淆的问题。第一个是运营层面的:作业是否运行,何时开始和停止,运行时长是多少,是否正常退出,以及错误信息说了什么。这与你对任何生产系统所施加的纪律相同,没有它,你就无法知道管道是否还在正常运行。

第二个问题更难,也更重要:数据是否正确?作业可以正常退出,仍然产生垃圾数据。数据质量检查应作为门控条件内置于管道中,而不是事后仪表板。断言行数在预期范围内、关键列非空、值符合预期格式、今日数据量没有悄然下降到昨日的十分之一。当检查失败时,管道应停止并报警,而不是加载坏数据并让其传播到每个下游报告中。

对于抓取的数据源,数据质量监控同时也是收集监控。解析记录的突然下降通常意味着源站更改了其标记或开始屏蔽你,而不是世界上的数据用完了。将数量下降视为一级警报,可以将无声的失败转变为可操作的问题。

网页抓取数据在何处进入管道

网络数据是你能够馈入管道的最丰富的外部数据源之一(包括价格、列表、评论和公开市场信号),但也是运营上最具挑战性的。内部数据库和合作伙伴 API 会提供干净、稳定的结构。而开放网络则在不断变化的反爬虫防御背后提供渲染后的 HTML。这种挑战完全存在于采集阶段,因此你整个管道的可靠性往往取决于数据收集层的健壮程度。

自己构建该层意味着运行无头浏览器以渲染 JavaScript 密集型页面,维护一个住宅代理池以避免第一次请求就被封锁,解决 CAPTCHA,并随着目标不断演变保持一切正常运转。这是一个需要持续运营的系统,与你实际的转换工作毫无关系。务实的做法是将收集作为托管服务,使采集阶段向你的管道提供干净数据,让你的工程时间花在下游。关于保持可收集性的通用手册,请参阅如何在不被封锁的情况下抓取网站,其中深入介绍了各种失败模式。

这正是 Crawlbase 作为采集层的意义所在。Crawling API 接受一个 URL 加上可选的 JavaScript token,在轮换住宅 IP 后的真实浏览器中渲染页面,并返回完整的 HTML 或解析后的 JSON,使客户端渲染的商店或市场在单次调用中返回完整填充的内容。对于你直接控制的原始 HTTP 路由,Smart AI Proxy 将相同的轮换 IP 基础设施作为标准代理端点暴露出来,而 Crawling API 则为常见页面类型返回结构化字段,省去了编写解析器的工作。

Crawlbase 作为你的采集层

让收集成为管道中可靠的阶段,而不是薄弱的环节。Crawling API 在轮换住宅 IP 后渲染 JavaScript 页面,并在单次调用中返回干净的 HTML 或 JSON,使你的 DAG 采集任务只需获取数据。先在免费层级使用并指向真实数据源,然后再连接其余部分。

使用 Crawling API 的最小采集任务如下所示,一次调用即可返回供转换步骤使用的渲染 HTML:

python
from crawlbase import CrawlingAPI

api = CrawlingAPI({'token': 'YOUR_CRAWLBASE_JS_TOKEN'})

def collect_page(url):
    response = api.get(url, {'ajax_wait': True, 'page_wait': 5000})
    if response['status_code'] == 200:
        return response['body']  # rendered HTML, ready to parse
    raise RuntimeError(f'collect failed: {response["status_code"]}')

使用异步爬虫扩展采集规模

每个 URL 一次同步调用对数百个页面来说没问题。一旦你需要按计划收集数以万计甚至数十万计的 URL,在每次请求上阻塞 DAG 就不再合理了。这是你从同步 API 转向异步 API 的临界点。

Crawler 正是为这种规模而生。你将大批量 URL 推入队列,服务在后台异步爬取,然后在每个结果完成时将其传递给你控制的回调(webhook)端点,而不是让你为每个页面保持一个连接打开。你的采集阶段变成了"入队 URL 并继续前进",一个独立的处理程序在回调落地时将结果写入暂存区。这种解耦正是批处理模型应用于数据收集的方式,使大规模爬取不会成为一个脆弱的长期运行作业。对于具有专用吞吐量和支持的组织级规模收集,企业版以相同的模型进行扩展。

对于暂存,Crawlbase Storage 可以保存爬取的响应,使收集和解析保持解耦:爬虫将原始响应写入存储,你的转换步骤按照自己的计划从那里读取。这种分离再次体现了 ELT 模式,原始数据被保留,使你无需重新爬取即可在以后重新解析。这里的经济效益也很重要,因为收集通常是网络数据管道中成本最高的阶段;关于控制这一成本的方法,请参阅电商网络抓取,该文章端到端地介绍了一个大容量收集场景。

网络数据管道的参考架构

将各部分整合在一起,一个健壮的网络数据管道通常是这样的。编排器按计划运行,将目标 URL 入队到异步爬虫。爬虫异步收集,将原始响应原封不动地写入暂存存储。转换步骤读取原始响应,将其解析为结构化行,应用数据质量门控,并将干净的输出加载到数据仓库中。服务工具然后从数据仓库读取,而不是从收集器读取。

使这一切保持稳固的纪律是将每个关注点保持在各自的阶段。收集不做解析;转换不做收集;服务不接触原始数据。当目标网站更改其标记时,你修复转换并从暂存区重新处理,无需重新爬取。当你需要更快的节奏时,你更改计划,而不是代码。由于原始数据被保留,在第六个月发现的解析错误是一次重新处理,而不是数据丢失事件。如果代理和 IP 轮换对你来说是新领域,什么是代理服务器是了解采集阶段底层知识的有用入门资料。

回顾

核心要点

  • 各阶段是通用的。 采集、处理、存储和服务,按此顺序,编排和监控贯穿所有阶段。工具会变,顺序不变。
  • 除非新鲜度就是产品,否则选择批处理。 流处理功能强大但成本高昂;在采用之前,先写下业务实际所需的延迟。
  • 优先选择 ELT 并保留原始数据。 先落地原始数据可以让你在需求变更时重新推导表格,当重新从数据源收集代价高昂或不可能时,这一点至关重要。
  • 用明确的依赖关系进行编排。 具有幂等、可重试任务的 DAG 可以遏制故障,而不是向下游传播错误数据。
  • 监控数据质量,而不仅仅是作业状态。 作业可以正常退出但仍产生坏数据;在管道内对行数、空值和格式设置门控。
  • 将采集视为托管关注点。 网络收集是最具挑战性的阶段;使用 Crawling API 或异步 Crawler 使管道的其余部分保持简单。

常见问题

用简单的话说,什么是数据管道架构?

它是一组组件及其运行顺序,负责将数据从创建之处传输至使用之处。标准流程是采集,然后处理和转换,然后存储,然后服务或分析,编排决定每个步骤何时运行,监控确认每个步骤是否正常工作。架构是围绕这一流程的契约:每个阶段保证什么以及如何处理故障。

ETL 和 ELT 有什么区别?

两者都进行数据的提取、加载和转换,区别在于顺序。ETL 在专用层中转换数据,然后将完成的结果加载到数据仓库中。ELT 先将原始数据加载到数据仓库中,然后用 SQL 在原地进行转换。ELT 是现代默认方式,因为廉价的存储使保留原始数据变得有意义:当需求变更时,你可以重新推导任何表格,而无需重新从数据源收集。

什么时候应该使用流处理管道而不是批处理?

只有当新鲜度就是产品时才使用流处理,例如欺诈检测、实时定价或实时监控,其中一小时前的答案是错误的。对于绝大多数分析,批处理更简单、更便宜、更易于重新处理,而且完全正确。通过写下业务实际所需的延迟来做决定;大多数团队高估了数据需要多新鲜。

网络抓取的数据如何融入数据管道?

抓取的数据与数据库和 API 一样在采集阶段进入,但它是运营上最具挑战性的数据源,因为开放网络会防御机器人并在不通知的情况下更改其标记。可靠的模式是将收集视为托管服务,向管道提供干净的 HTML 或 JSON,然后对其运行正常的转换、存储和服务阶段。这将网络的不稳定性控制在单一阶段内。

Crawlbase 作为采集层如何工作?

Crawling API 接受一个 URL 加上可选的 JavaScript token,在轮换住宅 IP 后的真实浏览器中渲染页面,并在单次调用中返回完整的 HTML 或解析后的 JSON,因此即使是客户端渲染的页面也能返回完整填充的内容。对于大规模或按计划的收集,异步 Crawler 将 URL 批量排队,在后台爬取,并将结果传递到回调端点,同时提供 Storage 用于暂存原始响应,使收集和解析保持解耦。

为什么监控不能只检查作业是否运行?

因为作业可以成功退出,仍然产生错误数据。运营监控告诉你作业是否运行及其时间;数据质量监控告诉你输出是否正确。在管道内对预期行数、非空关键列、有效格式和稳定数据量等断言设置门控,使其在数据不正确时停止并报警,而不是将其加载到每个下游报告中。对于抓取的数据源,数据量下降通常是收集器被封锁的第一个信号。

开始构建

大规模爬取任何站点,无需与基础设施对抗。

Crawlbase 负责处理代理、指纹和 CAPTCHA,让你的团队专注于交付数据流水线,而非维护爬取管道。1,000 次请求免费,无需信用卡。

自助开通 · 无需销售通话 · 提供企业级爬取量