返回架构笔记
Arch Day 91

Arch Day 91: 实时数据架构

实时数据架构是将数据从产生到消费的延迟从小时/天级压缩到秒/毫秒级的端到端系统设计,是"数据驱动决策"的最后一公里。

2026-06-29
第三阶段 - 零售域深度
实时数据流处理KafkaFlinkLambda架构Kappa架构

日期: 2026-06-29 (Day 91) 阶段: 第三阶段 - 零售域深度 标签: #实时数据 #流处理 #Kafka #Flink #Lambda架构 #Kappa架构


核心概念

一句话定义

实时数据架构是将数据从产生到消费的延迟从小时/天级压缩到秒/毫秒级的端到端系统设计,是"数据驱动决策"的最后一公里。

为什么关注

在零售/金融场景中,实时数据架构直接决定业务竞争力:

场景批处理(T+1)实时处理业务价值差距
库存同步次日可见超卖毫秒级扣减超卖率降低90%+
风控拦截事后审核交易前实时决策欺诈损失降低70%+
促销监控活动结束才知道效果实时GMV/转化率可动态调整策略
推荐系统昨天的行为推今天的商品实时行为→实时推荐CTR提升15-30%
供应链隔天补货实时库存→智能补货缺货率降低40%+

误区与反模式

  1. "所有数据都要实时" — 实时处理成本是批处理的3-10倍,只有业务真正需要低延迟的场景才值得投入
  2. "实时=快速批处理" — 微批处理(Spark Streaming)与真正的事件驱动(Flink)在语义和能力上有本质差异
  3. "Kafka就是实时架构" — Kafka只是消息层,完整的实时架构还包括计算引擎、存储层和服务层
  4. "实时大屏=实时架构" — 大屏只是展示层,背后需要完整的数据采集→传输→计算→存储→服务链路

知识点详解

根据2025-2026年最新行业实践,三大流处理引擎各有定位:

架构哲学差异

维度Apache FlinkSpark Structured StreamingKafka Streams
处理模型原生流处理(逐事件)微批处理(mini-batch)逐事件处理
延迟毫秒级(1-10ms)百毫秒级(100ms+),连续模式可达1ms毫秒级
状态管理RocksDB + 分布式快照(Chandy-Lamport)基于RDD的状态存储Changelog + RocksDB
容错机制Checkpoint + SavepointWAL / CheckpointChangelog复制到Kafka
Exactly-Once原生支持(Two-Phase Commit)通过幂等写入和事务实现通过Kafka事务实现
部署模型独立集群 / YARN / K8sSpark集群(共享资源)嵌入式(JVM库)
背压处理自动、无需配置需要手动启用和调参基于消费者Pull模型
CDC支持原生Debezium连接器需外部工具发布到Kafka通过Kafka Connect
窗口类型滚动/滑动/会话/全局滚动/滑动/会话滚动/滑动/会话
水印机制灵活自定义水印生成基于事件时间的水印基于记录时间戳(较简单)
适用团队专业流处理团队已有Spark生态的团队微服务/应用开发团队

选型决策树

需要实时流处理?
├── 是否已有Kafka生态?
│   ├── 是 → 处理逻辑是否简单(过滤/聚合/Join)?
│   │   ├── 简单 → Kafka Streams(无需额外集群)
│   │   └── 复杂(CEP/复杂窗口/多流Join) → Flink
│   └── 否 → 是否已有Spark集群?
│       ├── 是 → 延迟要求是否<100ms?
│       │   ├── 是 → Flink
│       │   └── 否 → Spark Structured Streaming
│       └── 否 → Flink(最佳默认选择)

性能基准(2025行业数据)

吞吐量(单节点):
  Flink:    ~150万 events/sec
  Spark SS: ~120万 events/sec(微批模式)
  Kafka Streams: ~80万 events/sec

端到端延迟(P99):
  Flink:    5-20ms
  Spark SS: 100-500ms(微批),1-5ms(连续模式,但功能受限)
  Kafka Streams: 2-10ms

状态恢复时间:
  Flink:    10-30秒(从最近Checkpoint恢复)
  Spark SS: 30-60秒
  Kafka Streams: 5-15秒(从Changelog恢复)

2. Kafka架构深度解析

Kafka是实时数据架构的核心消息骨干,理解其内部机制至关重要。

核心架构组件

┌─────────────────────────────────────────────────────┐
│                 Kafka Cluster (KRaft模式)              │
│                                                       │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐              │
│  │ Broker 1 │  │ Broker 2 │  │ Broker 3 │             │
│  │(Controller)│ │          │  │          │             │
│  └─────────┘  └─────────┘  └─────────┘              │
│       │            │            │                     │
│  ┌────┴────────────┴────────────┴────┐               │
│  │        Topic: order-events         │               │
│  │  ┌───────┐ ┌───────┐ ┌───────┐   │               │
│  │  │Part-0 │ │Part-1 │ │Part-2 │   │               │
│  │  │(Leader)│ │(Leader)│ │(Leader)│   │               │
│  │  └───────┘ └───────┘ └───────┘   │               │
│  │  ┌───────┐ ┌───────┐ ┌───────┐   │               │
│  │  │Rep-0  │ │Rep-1  │ │Rep-2  │   │  (ISR副本)     │
│  │  └───────┘ └───────┘ └───────┘   │               │
│  └───────────────────────────────────┘               │
└─────────────────────────────────────────────────────┘

Partition机制深度

分区策略选择

策略适用场景顺序保证负载均衡
Key Hash分区需要相同Key顺序(如同一用户事件)同Key有序依赖Key分布
Round Robin不需要顺序保证,追求吞吐均匀
Custom分区特殊业务逻辑(如按地区路由)自定义自定义
Sticky分区无Key场景优化批量发送较均匀

分区数量规划公式

目标吞吐量 = T (msg/sec)
单分区写入吞吐 = Pw (msg/sec)  // 通常 50K-100K msg/sec
单分区消费吞吐 = Pc (msg/sec)  // 通常 100K-200K msg/sec

最小分区数 = max(T/Pw, T/Pc)

示例:
  目标100万msg/sec,单分区写入80K
  分区数 = 1000000/80000 = 13 → 建议16(留buffer + 2的幂次)

Consumer Group机制

Consumer Group: order-processing-group
┌──────────────────────────────────────────┐
│  Consumer 1      Consumer 2     Consumer 3│
│  ├─ Part-0       ├─ Part-2      ├─ Part-4│
│  └─ Part-1       └─ Part-3      └─ Part-5│
│                                          │
│  Rebalance触发条件:                       │
│  1. 新Consumer加入                        │
│  2. Consumer离开(崩溃/主动退出)           │
│  3. Topic分区数变化                        │
│  4. 订阅的Topic变化                        │
│                                          │
│  KIP-848协议(Kafka 4.0+):              │
│  - 增量式再平衡,避免Stop-the-World        │
│  - 服务端协调,减少客户端复杂度             │
└──────────────────────────────────────────┘

Exactly-Once语义实现

// Kafka事务性生产者配置
Properties props = new Properties();
props.put("bootstrap.servers", "kafka1:9092,kafka2:9092");
props.put("transactional.id", "order-processor-1"); // 唯一事务ID
props.put("enable.idempotence", true);               // 幂等性
props.put("acks", "all");                            // 所有ISR确认
props.put("max.in.flight.requests.per.connection", 5);

KafkaProducer<String, String> producer = new KafkaProducer<>(props);
producer.initTransactions();

try {
    producer.beginTransaction();

    // 原子性:消费偏移量提交 + 生产输出消息
    producer.send(new ProducerRecord<>("output-topic", key, value));
    producer.sendOffsetsToTransaction(offsets, consumerGroupId);

    producer.commitTransaction();
} catch (Exception e) {
    producer.abortTransaction();
}

Exactly-Once三层保障

层级机制保障内容
Producer幂等ProducerID + SequenceNumber单分区去重
事务TransactionalID + Two-Phase Commit跨分区原子写入
Consumer隔离isolation.level=read_committed只读已提交数据

3. 实时计算核心模式

Event Time vs Processing Time

现实世界时间线:
  Event产生 → 网络传输 → 到达系统 → 被处理
     ↓              延迟           ↓
  Event Time                  Processing Time

示例:
  用户10:00:00下单 → 10:00:03到达Kafka → 10:00:05被Flink处理
  Event Time = 10:00:00
  Processing Time = 10:00:05

为什么Event Time重要?
  - 移动端网络不稳定,事件可能延迟数秒甚至数分钟到达
  - 不同数据中心的系统时钟可能不同步
  - 业务语义上,"用户什么时候做的"比"系统什么时候处理的"更有价值

Watermark(水印)机制

事件流(按到达顺序,括号内为Event Time):

  ... [10:01] [10:03] [10:02] [10:05] [10:04] [10:06] ...
                                                    ↑
                                              当前Watermark = 10:04

含义:系统认为不会再有Event Time < 10:04的事件到达

Watermark生成策略:
  1. 固定延迟:W = max(event_time) - 允许延迟
     - 简单实用,适合大多数场景
     - 例:允许延迟5秒 → W = max_event_time - 5s

  2. 自定义水印:根据业务逻辑
     - 如:不同来源的数据延迟不同,按来源设置不同延迟

迟到数据处理:
  - 丢弃(默认):忽略晚于Watermark的数据
  - Side Output:将迟到数据输出到侧流,后续补偿处理
  - Allowed Lateness:窗口延迟关闭,更新已有结果

Window(窗口)类型详解

时间轴:  |----1----|----2----|----3----|----4----|

1. 滚动窗口(Tumbling):固定大小,不重叠
   |████████|████████|████████|████████|
   用途:每分钟UV、每小时GMV

2. 滑动窗口(Sliding):固定大小,有重叠
   |████████████|
        |████████████|
             |████████████|
   用途:过去5分钟的平均响应时间(每分钟更新)

3. 会话窗口(Session):按活动间隔动态划分
   |███|   |█████████|   |██|
      gap       gap
   用途:用户浏览会话分析

4. 全局窗口(Global):所有数据在同一窗口,需自定义Trigger
   |████████████████████████████████████|
   用途:累计计数器,配合自定义触发条件

4. 实时指标计算实战

实时GMV计算

-- Flink SQL: 实时GMV(分钟级滚动窗口)
CREATE TABLE order_events (
    order_id STRING,
    user_id STRING,
    amount DECIMAL(10,2),
    category STRING,
    store_id STRING,
    event_time TIMESTAMP(3),
    WATERMARK FOR event_time AS event_time - INTERVAL '5' SECOND
) WITH (
    'connector' = 'kafka',
    'topic' = 'order-events',
    'properties.bootstrap.servers' = 'kafka:9092',
    'format' = 'json'
);

-- 实时分钟级GMV
SELECT
    TUMBLE_START(event_time, INTERVAL '1' MINUTE) AS window_start,
    category,
    store_id,
    COUNT(*) AS order_count,
    SUM(amount) AS gmv,
    COUNT(DISTINCT user_id) AS buyer_count
FROM order_events
GROUP BY
    TUMBLE(event_time, INTERVAL '1' MINUTE),
    category,
    store_id;

实时库存计算

-- 实时库存变动追踪
CREATE TABLE inventory_events (
    sku_id STRING,
    warehouse_id STRING,
    change_type STRING,  -- 'inbound', 'outbound', 'reserved', 'released'
    quantity INT,
    event_time TIMESTAMP(3),
    WATERMARK FOR event_time AS event_time - INTERVAL '2' SECOND
) WITH (...);

-- 实时库存快照(使用Flink的Deduplication + Aggregation)
SELECT
    sku_id,
    warehouse_id,
    SUM(CASE
        WHEN change_type IN ('inbound', 'released') THEN quantity
        WHEN change_type IN ('outbound', 'reserved') THEN -quantity
        ELSE 0
    END) AS available_stock,
    MAX(event_time) AS last_updated
FROM inventory_events
GROUP BY sku_id, warehouse_id;

实时风控特征计算

-- 实时用户行为特征(滑动窗口)
SELECT
    user_id,
    -- 过去5分钟特征
    COUNT(*) OVER w5m AS order_count_5min,
    SUM(amount) OVER w5m AS total_amount_5min,
    COUNT(DISTINCT device_id) OVER w5m AS device_count_5min,
    COUNT(DISTINCT ip) OVER w5m AS ip_count_5min,
    -- 过去1小时特征
    COUNT(*) OVER w1h AS order_count_1h,
    SUM(amount) OVER w1h AS total_amount_1h
FROM order_events
WINDOW
    w5m AS (PARTITION BY user_id ORDER BY event_time
            RANGE BETWEEN INTERVAL '5' MINUTE PRECEDING AND CURRENT ROW),
    w1h AS (PARTITION BY user_id ORDER BY event_time
            RANGE BETWEEN INTERVAL '1' HOUR PRECEDING AND CURRENT ROW);

5. 实时大屏架构全链路

┌─────────────────────────────────────────────────────────────┐
│                    实时大屏完整架构                            │
│                                                              │
│  数据采集层          消息层        计算层        存储/服务层     │
│                                                              │
│  ┌─────────┐    ┌─────────┐   ┌──────────┐   ┌──────────┐  │
│  │ App埋点  │───→│         │──→│          │──→│ Redis     │  │
│  │ (SDK)    │    │         │   │          │   │ (实时指标) │  │
│  └─────────┘    │         │   │          │   └────┬─────┘  │
│                 │  Kafka  │   │  Flink   │        │        │
│  ┌─────────┐    │  Cluster│   │  Cluster │   ┌────┴─────┐  │
│  │ 订单系统 │───→│         │──→│          │──→│ClickHouse│  │
│  │ (Binlog) │    │         │   │  Job 1:  │   │(明细查询) │  │
│  └─────────┘    │         │   │  GMV计算  │   └────┬─────┘  │
│                 │         │   │          │        │        │
│  ┌─────────┐    │         │   │  Job 2:  │   ┌────┴─────┐  │
│  │ 库存系统 │───→│         │──→│  库存监控 │──→│WebSocket │  │
│  │ (CDC)    │    │         │   │          │   │  Server  │  │
│  └─────────┘    │         │   │  Job 3:  │   └────┬─────┘  │
│                 │         │   │  风控特征 │        │        │
│  ┌─────────┐    │         │   │          │   ┌────┴─────┐  │
│  │ 日志系统 │───→│         │──→│  Job 4:  │──→│ 前端大屏  │  │
│  │(Filebeat)│    │         │   │  流量分析 │   │(ECharts) │  │
│  └─────────┘    └─────────┘   └──────────┘   └──────────┘  │
│                                                              │
│  技术选型:                                                   │
│  采集:Debezium CDC / Filebeat / SDK                         │
│  消息:Kafka 3.8+(KRaft模式,无ZooKeeper依赖)               │
│  计算:Flink 1.20+                                           │
│  存储:Redis 7.x(热数据)+ ClickHouse 24.x(分析查询)       │
│  推送:WebSocket / Server-Sent Events                        │
│  展示:ECharts / Grafana / 自研大屏                           │
└─────────────────────────────────────────────────────────────┘

6. Lambda vs Kappa vs Delta架构

架构演进趋势(2025-2026最新)

维度LambdaKappaDelta(Lakehouse)
提出时间2011(Nathan Marz)2014(Jay Kreps)2020(Databricks)
核心思想批+流双通道统一流处理统一存储+批流一体
数据通道批处理层+速度层+服务层单一流处理通道Lakehouse + Streaming
代码维护两套代码(批+流)一套代码一套代码
历史重处理批处理层重跑从Kafka日志重放从Delta Lake重读
一致性最终一致(两层合并)强一致ACID事务保证
复杂度高(双系统维护)中(单系统但需大Kafka)中(需Lakehouse平台)
存储成本高(数据存两份)中(Kafka保留策略限制)低(对象存储)
2026主流度遗留系统仍在用新系统默认选择大规模数据平台首选

2025-2026行业趋势

  • Kappa架构已成为新建实时系统的默认选择,Uber、Shopify等公司已完成从Lambda到Kappa的迁移
  • Delta架构(基于Lakehouse)正成为企业级数据平台的主流,Databricks/Apache Iceberg生态快速成熟
  • Flink + Kafka + Iceberg/Delta Lake的组合正在成为"现代数据栈"的标准配置

对比分析

实时存储选型对比

存储延迟吞吐查询能力适用场景
Redis<1ms10万+ QPS/节点KV/简单聚合实时计数器、排行榜、缓存
ClickHouse10-100ms亿级扫描/秒复杂OLAP实时报表、多维分析
Apache Doris10-100ms亿级扫描/秒复杂OLAP + 实时写入实时Dashboard + Ad-hoc查询
Elasticsearch10-50ms百万级写入/秒全文搜索+聚合日志分析、搜索场景
TiDB5-20ms十万级QPS完整SQL(HTAP)需要事务+分析的混合场景
HBase1-5ms百万级随机读写/秒行键查询特征存储、时序数据

架构设计实操:双11实时大屏

设计目标

为某电商平台设计双11实时大屏系统,核心指标:

  1. 实时GMV(全平台/分品类/分店铺)
  2. 实时订单数和支付转化率
  3. 实时UV/PV
  4. 实时库存预警
  5. 实时物流追踪

性能要求

指标要求
数据延迟核心指标<3秒,非核心<10秒
峰值写入100万订单/秒(双11零点)
大屏刷新每秒更新
可用性99.99%
准确性最终一致,误差<0.1%

架构方案

┌────────────────────────────────────────────────────────┐
│                    双11实时大屏架构                       │
│                                                         │
│ Layer 1: 数据采集(多源异构)                              │
│ ┌────────────┬────────────┬────────────┬──────────────┐ │
│ │ 订单Binlog  │ 支付回调    │ 用户行为SDK │ 库存变动CDC  │ │
│ │ (Debezium) │ (HTTP→MQ)  │ (Kafka SDK)│ (Debezium)  │ │
│ └─────┬──────┴─────┬──────┴─────┬──────┴──────┬───────┘ │
│       └────────────┴────────────┴─────────────┘         │
│                          ↓                               │
│ Layer 2: 消息队列(Kafka集群)                             │
│ ┌──────────────────────────────────────────────────┐    │
│ │ Kafka集群(100+ Broker,KRaft模式)                │    │
│ │ Topics:                                           │    │
│ │   order-events (256 partitions, RF=3)             │    │
│ │   payment-events (128 partitions, RF=3)           │    │
│ │   user-behavior (512 partitions, RF=3)            │    │
│ │   inventory-events (64 partitions, RF=3)          │    │
│ │ 峰值吞吐: 200万msg/sec                            │    │
│ │ 数据保留: 7天                                     │    │
│ └──────────────────────────────────────────────────┘    │
│                          ↓                               │
│ Layer 3: 流处理(Flink集群)                               │
│ ┌──────────────────────────────────────────────────┐    │
│ │ Flink集群(500+ TaskManager)                      │    │
│ │                                                    │    │
│ │ Job Group 1: GMV实时聚合                           │    │
│ │   1分钟滚动窗口 → 多维度GMV                         │    │
│ │   (全平台/品类/店铺/省份)                            │    │
│ │                                                    │    │
│ │ Job Group 2: 转化率计算                             │    │
│ │   浏览→加购→下单→支付 漏斗实时计算                    │    │
│ │                                                    │    │
│ │ Job Group 3: 库存预警                               │    │
│ │   实时库存 < 安全库存 → 告警                         │    │
│ │                                                    │    │
│ │ Job Group 4: 风控特征                               │    │
│ │   5分钟滑动窗口用户行为特征                          │    │
│ └──────────────────────────────────────────────────┘    │
│                          ↓                               │
│ Layer 4: 存储+服务                                       │
│ ┌──────────┬──────────────┬──────────────┐              │
│ │ Redis    │ ClickHouse   │ HBase        │              │
│ │ Cluster  │ Cluster      │ Cluster      │              │
│ │          │              │              │              │
│ │ 实时计数  │ 明细数据      │ 用户特征      │              │
│ │ GMV累计   │ 多维分析      │ 风控决策      │              │
│ │ 排行榜    │ 下钻查询      │ 状态查询      │              │
│ └────┬─────┴──────┬───────┴──────┬───────┘              │
│      └────────────┴──────────────┘                      │
│                    ↓                                     │
│ Layer 5: 服务+展示                                       │
│ ┌──────────────────────────────────────────────────┐    │
│ │ API Gateway → WebSocket Server → 大屏前端(ECharts)│    │
│ │ 数据刷新频率: 1秒                                   │    │
│ │ 推送策略: 增量推送(只推变化数据)                     │    │
│ └──────────────────────────────────────────────────┘    │
└────────────────────────────────────────────────────────┘

ADR: 选择Kappa而非Lambda架构

状态: 已采纳

背景: 双11大屏需要同时支持实时指标和历史对比分析

决策: 采用Kappa架构(Kafka + Flink统一处理),使用ClickHouse作为分析存储

理由:

  1. 单一代码库,降低维护成本(双11前紧急修bug只改一处)
  2. Flink同时处理实时和回填任务(Savepoint → 重放Kafka)
  3. ClickHouse既支持实时写入又支持复杂OLAP查询
  4. 团队只需精通一套技术栈

权衡:

  • 需要Kafka保留足够历史数据(7天),存储成本较高
  • 超大历史分析(月/年级)仍需离线数仓补充
  • Flink集群规模需要为峰值设计(或使用K8s弹性伸缩)

AI增强实践

1. AI驱动的实时异常检测

# 基于Flink + AI模型的实时异常检测
class AnomalyDetectionFunction(KeyedProcessFunction):
    def __init__(self):
        self.model = None
        self.feature_buffer = []

    def open(self, runtime_context):
        # 加载预训练的异常检测模型(定期从MLflow同步)
        self.model = load_model("s3://models/anomaly-detector/latest")

    def process_element(self, value, ctx):
        # 实时特征提取
        features = extract_features(value)

        # 模型推理(<5ms延迟)
        anomaly_score = self.model.predict(features)

        if anomaly_score > THRESHOLD:
            # 输出异常告警到侧流
            yield TaggedOutput("anomalies", AnomalyEvent(
                event=value,
                score=anomaly_score,
                detected_at=ctx.timestamp()
            ))

2. AI辅助的Flink作业自动调优

# AI Agent自动优化Flink配置
ai_tuning:
  metrics_source: prometheus
  optimization_targets:
    - metric: "checkpoint_duration_p99"
      target: "<10s"
    - metric: "backpressure_ratio"
      target: "<0.1"
    - metric: "throughput"
      target: ">1M events/sec"

  tunable_parameters:
    - "taskmanager.memory.managed.fraction"  # 0.1-0.9
    - "state.backend.rocksdb.block.cache-size"  # 64MB-4GB
    - "execution.checkpointing.interval"  # 10s-300s
    - "taskmanager.numberOfTaskSlots"  # 1-16

  strategy: "bayesian_optimization"
  evaluation_window: "30min"

3. LLM驱动的实时数据质量监控

  • 自然语言描述异常:"过去5分钟GMV同比下降40%,主要集中在华东区域,可能是支付系统故障"
  • 自动根因分析:关联多个指标流,用LLM推理异常原因
  • 智能告警分级:基于历史模式判断告警严重程度

与Web3/DeFi的关联

DeFi中的实时数据需求

传统零售实时场景DeFi对应场景技术差异
实时GMV大屏实时TVL/交易量Dashboard数据源从数据库→链上事件
实时库存预警实时流动性监控链上状态查询 vs CDC
实时风控实时MEV检测/清算预警需要Mempool监控
用户行为分析链上地址行为分析公开数据但地址匿名

Web3实时数据架构

链上数据 → Indexer(The Graph/Goldsky) → Kafka → Flink → Dashboard
              ↓
         事件解析(ABI decode)
              ↓
         标准化事件流

关键差异

  1. 数据源:Web3数据全公开但需要解析(ABI decode),传统零售数据在内部系统
  2. 时效性:以太坊出块12秒,Solana 400ms,不同链的实时性不同
  3. 重组风险:链上数据可能因区块重组(reorg)而回滚,需要确认块数
  4. Mempool:DeFi交易在上链前可在Mempool中被发现,这是MEV的基础

今日思考

问题1:为什么很多公司的"实时"其实是"准实时"?

真正的毫秒级实时处理对基础设施要求极高——需要独立的Flink集群、足够的Kafka分区、低延迟网络、实时存储(Redis/ClickHouse)。大多数业务场景用秒级或分钟级延迟就够了(如GMV大屏、报表刷新),过度追求低延迟反而增加系统复杂度和成本。真正需要毫秒级的场景:风控拦截、高频交易、实时竞价。

问题2:当Flink作业挂了,如何保证数据不丢不重?

核心机制是Checkpoint + Exactly-Once:Flink定期做分布式快照(Chandy-Lamport算法),记录算子状态和Kafka偏移量。恢复时从最近的Checkpoint恢复状态,Kafka Consumer从记录的偏移量重新消费。配合事务性Sink(如Kafka事务、两阶段提交),可以实现端到端的Exactly-Once语义。

问题3:实时计算和批处理如何共存?

现代趋势是"批流一体"——同一套代码逻辑,流处理跑实时,批处理跑历史补偿。Flink SQL天然支持这种模式:同一张SQL既可以查流表(实时),也可以查批表(历史)。ClickHouse/Apache Doris这类OLAP引擎也同时支持实时写入和批量导入,作为统一的服务层。


面试题准备

面试题1:Flink和Spark Streaming如何选?

30秒版本: Flink是原生流处理引擎,延迟更低(毫秒级)、状态管理更强、支持精确的Event Time处理;Spark Streaming是微批处理,延迟较高(百毫秒级)但与Spark生态集成好。如果团队已有Spark技能且延迟要求不苛刻,选Spark;否则Flink是2025年新系统的默认选择。

2分钟版本

  • 处理模型:Flink逐事件处理,Spark按微批处理。这不仅影响延迟,还影响窗口语义的精确性
  • 状态管理:Flink的RocksDB状态后端支持TB级状态,配合增量Checkpoint,恢复时间短。Spark状态管理相对薄弱
  • CDC支持:Flink原生集成Debezium,Spark需要额外组件
  • 生态:Spark在机器学习(MLlib)、图计算(GraphX)方面更成熟
  • 运维:Spark集群通常已存在(共享ETL/ML),Flink需要独立部署和运维
  • 我的经验:在零售场景中,实时库存同步、风控特征计算用Flink(需要毫秒级延迟和精确Event Time),离线报表用Spark。两者互补而非替代

追问准备

  • Q: Flink的Checkpoint对性能有什么影响? → Checkpoint期间会有短暂的吞吐下降(全量Checkpoint较明显),增量Checkpoint影响更小。建议Checkpoint间隔10s-60s,配合RocksDB增量模式
  • Q: 什么场景下Kafka Streams比Flink更合适? → 当处理逻辑简单(过滤、转换、简单聚合)且数据完全在Kafka中时,Kafka Streams无需额外集群,部署在应用JVM中即可

面试题2:实时计算如何处理乱序数据?

30秒版本: 通过Event Time + Watermark机制。每条数据携带事件时间,系统根据Watermark判断"哪些数据已经全部到齐",在此基础上触发窗口计算。迟到的数据可以通过Allowed Lateness或Side Output处理。

2分钟版本

  • Event Time:使用数据产生时间而非处理时间作为计算基准
  • Watermark:系统对"数据到齐程度"的估计,通常是max_event_time - allowed_delay
  • 窗口触发:当Watermark超过窗口结束时间,触发计算
  • 迟到处理三策略:丢弃(简单)、Side Output(补偿处理)、Allowed Lateness(更新结果)
  • 实战经验:在零售订单场景中,移动端SDK的事件延迟通常在1-5秒,设置5秒Watermark延迟即可覆盖99%的场景。对于跨境场景(网络延迟大),可能需要30秒甚至更长
  • 权衡:Watermark延迟越大,处理越准确但实时性越差。需要根据业务容忍度在准确性和实时性之间取舍

学习资源

  1. Apache Flink官方文档 — 最权威的Flink学习资源
  2. Confluent Kafka文档 — Kafka深度学习
  3. ClickHouse实时分析资源 — 2026年实时分析数据库选型指南
  4. Kappa vs Lambda架构对比 (2026) — 最新架构趋势分析
  5. Flink vs Spark vs Kafka Streams对比 — 流处理引擎全面对比

明日预告

Day 92: 数据治理 — 从"管数据"到"治数据"。将深入DAMA-DMBOK2/3.0框架、数据质量管理、元数据管理、数据血缘追踪、数据目录(DataHub/Atlas)、主数据管理等核心主题,并设计完整的数据治理平台架构。数据治理是大规模实时数据系统可持续运营的基石。