1. 实时数据处理系统全景

实时数据处理并不是“把批处理跑得更快”,而是一条从事件产生到洞察呈现的持续链路。在这条链路上,Google Cloud 提供了一组职责清晰、可组合的托管服务:Pub/Sub 负责事件的接收与分发,Dataflow 负责流式转换与计算,Bigtable 承担低延迟在线服务型读写,BigQuery 提供面向分析的实时落地与 SQL 查询,Looker 则把结果转化为可交互的仪表板与业务视图。理解每个组件“站在链路的哪一段、解决什么问题、不适合做什么”,是后续所有开发工作的前提。

一、实时链路的五个关键位置

把一条典型的实时管道拆开看,数据会依次经过五个位置,每个位置对系统的要求不同:

  • 接入层(Pub/Sub):面对的是海量、突发、来源分散的事件。它需要做到高吞吐、至少一次投递、按主题解耦生产者和消费者。Pub/Sub 的订阅(Subscription)是消费的基本单位,消息在未被确认(ack)前会保留,ack 截止时间(ack deadline)到期未确认则重新投递。
  • 处理层(Dataflow):面对的是“无界数据”。它基于 Apache Beam 模型,用窗口(Window)、触发器(Trigger)、水位线(Watermark)处理乱序与延迟。Dataflow 的自动扩缩容让吞吐波动时不必手工调机器。
  • 在线服务层(Bigtable):面对的是毫秒级点查与写入。它按行键(Row Key)排序存储,适合“按用户 ID 查最近状态”“按设备 ID 写时序点”这类访问模式,而不是复杂分析查询。
  • 分析层(BigQuery):面对的是大规模 SQL 分析与近实时落地。通过 BigQuery Storage Write API 或 Dataflow 的 BigQueryIO,流式数据可以持续写入,配合物化视图或 BI Engine 实现秒级查询。
  • 呈现层(Looker):面对的是业务人员。它通过 LookML 建模,把 BigQuery 中的表抽象为维度与度量,支撑仪表板、下钻和告警。

这五层不是必须全部出现。一个只做实时告警的场景可能只需要 Pub/Sub + Dataflow + 通知;一个需要“实时看板 + 历史回查”的场景才需要把 BigQuery 和 Looker 纳入。

事件源 App / IoT / 日志 点击流 / CDC Pub/Sub Topic 主题 Subscription 订阅 ack / 重投递 至少一次投递 Dataflow Apache Beam 模型 Window / Trigger Watermark 水位线 自动扩缩容 Exactly-once 状态 Bigtable Row Key 点查 毫秒级读写 在线服务型 BigQuery Storage Write API SQL 分析 物化视图 / BI Engine Looker LookML 建模 仪表板 / 下钻 业务视图 接入 / 解耦 转换 / 聚合 在线服务 vs 分析落地 呈现 延迟量级参考: Pub/Sub 毫秒~秒级 Dataflow 秒级 Bigtable 毫秒级 BigQuery 秒~分钟级 注:以上为典型量级示意,实际延迟受数据量、窗口策略、区域与配额影响。

二、各组件定位与“不该做什么”

选型时最容易犯的错误,是让一个组件去做它不擅长的事。下面把每个组件的边界说清楚。

组件核心定位典型用法不适合
Pub/Sub事件接入与分发多源事件汇聚、按订阅扇出、削峰缓冲复杂计算、长期存储、SQL 查询
Dataflow无界数据流处理窗口聚合、会话拼接、格式转换、写多目标毫秒级点查服务、交互式 SQL
Bigtable低延迟在线读写用户状态、设备时序、推荐特征多表 JOIN、全表扫描分析
BigQuery大规模分析落地实时明细入仓、聚合看板、历史回查单行毫秒级点查、高频小写入
Looker业务语义与呈现指标定义、仪表板、下钻分析数据清洗、流式计算

三、选型原则:从访问模式倒推组件

不要先问“我要用哪些产品”,而要先问三个问题:数据以什么速度到达?谁以什么方式读取结果?能接受多长延迟?

  1. 按读取模式选存储:如果下游是“按主键查一条记录”,选 Bigtable;如果是“按时间范围做聚合统计”,选 BigQuery。两者可以并存——Dataflow 同时写入 Bigtable 供在线服务、写入 BigQuery 供分析,这就是常见的 Lambda 式双写。
  2. 按延迟要求选处理方式:秒级告警用 Dataflow 流式窗口;分钟级看板可以让 Dataflow 微批写入 BigQuery;小时级报表甚至可以直接用 BigQuery 定时查询。
  3. 按数据乱序程度选窗口策略:事件时间(Event Time)与处理时间(Processing Time)差距大时,必须设置合理的 allowed lateness 和水位线,否则迟到数据会被丢弃或重复计算。
  4. 按成本与运维复杂度权衡:Pub/Sub 按消息量计费,Dataflow 按 vCPU·小时计费,Bigtable 按节点·小时计费,BigQuery 按扫描量或槽位计费。实时链路越长,成本越高,能用批处理满足的场景不要强行流式。
选型速记:接入看 Pub/Sub,计算看 Dataflow,点查看 Bigtable,分析看 BigQuery,呈现看 Looker。任何一层缺失,都要先确认是否真的不需要,而不是默认省略。

四、一个可对照的示例场景

假设要做一个“电商实时订单监控”:订单事件从 App 和 Web 产生,需要实时统计每分钟各品类成交额,同时支持客服按订单号查询最新状态,运营在仪表板上看趋势。

  • App/Web 将订单事件发布到 Pub/Sub 主题 order-events,按渠道建立两个订阅,便于独立消费。
  • Dataflow 从订阅读取,按事件时间做 1 分钟固定窗口,计算 category → sum(amount),并设置 allowed lateness 为 2 分钟以容纳迟到事件。
  • 聚合结果写入 BigQuery 表 realtime_category_sales,供 Looker 仪表板查询;同时把订单最新状态写入 Bigtable 表 order_status,行键设计为 order_id,供客服系统毫秒级点查。
  • Looker 基于 BigQuery 表建立 LookML 视图,定义“成交额”“订单数”等度量,运营可查看每分钟趋势并按品类下钻。

这个例子中,五个组件各司其职:Pub/Sub 解耦来源,Dataflow 做窗口计算,Bigtable 服务点查,BigQuery 承载分析,Looker 呈现业务语义。如果只做告警,可以去掉 Bigtable 和 Looker;如果只做离线报表,可以把 Dataflow 换成 BigQuery 定时查询。选型的本质,是让每个组件只做它最擅长的那一段。

常见误区:把 Bigtable 当分析库用(全表扫描会非常慢且昂贵);把 BigQuery 当在线点查库用(单行查询延迟和成本都不合适);在 Pub/Sub 里做复杂计算(Pub/Sub 只负责传递,不负责转换)。避开这三个误区,实时链路的架构就成功了一半。