2. SQL流式处理基础:流式SQL概念、与传统批处理SQL的区别、常见流引擎简介

2.1 流式SQL的核心概念

流式SQL(Streaming SQL)是将标准SQL语法扩展应用于无界数据流的查询语言。与传统SQL操作静态表不同,流式SQL操作的是动态表——数据持续到达,查询结果实时更新。其核心思想是将数据流抽象为一张逻辑上的无限表,每一条到达的记录都相当于向这张表插入一行数据。

关键术语:
  • 无界数据(Unbounded Data):持续产生、永不完结的数据流,如交易流水、传感器日志。
  • 动态表(Dynamic Table):随时间不断追加或更新的逻辑表,是流式SQL的操作对象。
  • 连续查询(Continuous Query):注册在动态表上的SQL,每次数据到达自动增量计算并输出结果。
  • 事件时间(Event Time):数据实际发生的时间戳,用于处理乱序和延迟数据。

流式SQL的典型处理模式包含三个步骤:

  1. 定义流表(Stream Table):将Kafka Topic或消息队列映射为SQL表结构。
  2. 注册连续查询:编写SELECT、JOIN、GROUP BY等SQL语句,指定窗口策略。
  3. 输出结果:将计算结果写入下游Sink(数据库、消息队列、文件系统)。
风险归因场景提示:在实时风控中,流式SQL常用于计算“过去5分钟单设备登录次数”、“跨账户资金归集检测”等窗口聚合查询,结果直接触发预警规则。

2.2 流式SQL与传统批处理SQL的区别

下表从多个维度对比流式SQL与批处理SQL的核心差异:

对比维度 批处理SQL 流式SQL
数据范围 有界数据集(全量历史数据) 无界数据流(持续到达)
执行模式 一次性触发,读取-计算-结束 连续运行,数据到达即触发增量计算
查询结果 静态快照,查询结束即固定 动态更新,随时间演进
时间语义 处理时间(查询发起时间) 事件时间 + 处理时间 + 水位线
窗口机制 无窗口概念,全量扫描 滚动窗口、滑动窗口、会话窗口
状态管理 无状态(每次独立计算) 有状态(维护中间聚合结果)
容错语义 Exactly-Once(通过事务保证) At-Least-Once / Exactly-Once(通过Checkpoint)
延迟要求 分钟级~小时级 毫秒级~秒级
常见误区:流式SQL并非“批处理SQL的加速版”。由于数据无界、乱序、延迟到达,流式SQL必须处理水位线(Watermark)、迟到数据(Late Data)和状态过期(State TTL)等批处理中不存在的问题。

2.3 流式SQL与传统批处理SQL的处理流程对比

下图直观展示了批处理与流式处理在数据生命周期上的差异:

批处理 vs 流式处理流程对比 批处理流程 全量数据读取 一次性计算 输出静态结果 流式处理流程 持续数据流入 连续查询引擎 实时结果更新 持续循环 核心差异: 批处理:数据静止 → 计算一次 → 结果固定;流处理:数据流动 → 计算持续 → 结果动态。 流式SQL需要额外处理水位线、窗口触发、状态管理、迟到数据修正等复杂语义。

2.4 常见流引擎简介

2.4.1 Apache Flink SQL

Apache Flink 是当前最主流的流批一体计算引擎,其SQL层完全遵循Apache Calcite标准,支持ANSI SQL和丰富的窗口函数。Flink SQL在风控场景中的核心优势包括:

  • 精确一次语义:基于分布式快照(Checkpoint)和两阶段提交Sink,保证数据不重不丢。
  • 事件时间处理:内置水位线机制,支持乱序数据到达后的正确窗口聚合。
  • 动态表演化:支持CDC(变更数据捕获)流,可直接关联数据库变更日志。
  • 丰富的连接器:原生支持Kafka、Pulsar、JDBC、Elasticsearch等风控常用数据源。
Flink SQL 风控示例:
-- 定义Kafka交易流表
CREATE TABLE trade_stream (
  trade_id STRING,
  user_id STRING,
  amount DECIMAL(10,2),
  trade_time TIMESTAMP(3),
  WATERMARK FOR trade_time AS trade_time - INTERVAL '5' SECOND
) WITH (
  'connector' = 'kafka',
  'topic' = 'trade_topic',
  'properties.bootstrap.servers' = 'localhost:9092',
  'format' = 'json'
);

-- 连续查询:每5分钟统计单用户累计交易额
SELECT
  user_id,
  TUMBLE_START(trade_time, INTERVAL '5' MINUTE) AS window_start,
  SUM(amount) AS total_amount
FROM trade_stream
GROUP BY
  user_id,
  TUMBLE(trade_time, INTERVAL '5' MINUTE);

2.4.2 KSQL (ksqlDB)

KSQL 是 Confluent 基于 Kafka Streams 构建的流式SQL引擎,专为Kafka生态设计。其特点在于:

  • 原生Kafka集成:直接操作Kafka Topic,无需额外连接器配置。
  • 流表二元性:同时支持流(Stream)和表(Table)两种抽象,表可视为流的物化视图。
  • 轻量级部署:无独立集群要求,作为Kafka集群的交互式查询层运行。
  • Pull/Push查询:支持传统Pull查询(一次性)和Push查询(持续推送)。
适用场景对比:Flink SQL适合复杂ETL、多流Join、大状态计算;KSQL适合Kafka原生生态下的轻量级流处理、实时过滤和简单聚合。在风险归因中,Flink SQL常用于跨多数据源的复杂关联分析,KSQL则适合单Topic的实时规则匹配。

2.4.3 其他流引擎

引擎 SQL支持程度 典型场景 风控适用性
Spark Structured Streaming ANSI SQL + 窗口函数 微批处理、与批处理混合作业 中等(延迟较高,适合准实时)
RisingWave PostgreSQL兼容SQL 实时物化视图、监控看板 高(专为流式SQL设计)
Materialize PostgreSQL兼容SQL 增量物化视图、交互式分析 中高(适合风控指标实时更新)

2.5 流引擎架构对比

下图展示Flink SQL与KSQL在架构层面的核心差异:

Flink SQL 与 KSQL 架构对比 Apache Flink SQL SQL Client / REST API Flink SQL Planner (Calcite) DataStream API (有状态) Kafka / JDBC / HDFS Sink KSQL (ksqlDB) REST API / CLI KSQL 引擎 (Kafka Streams) Kafka Streams DSL Kafka Topic (输出) 架构差异要点: Flink SQL:独立集群 + Calcite优化器 + 自定义状态后端,适合复杂多流Join和大状态计算。 KSQL:嵌入Kafka生态 + Kafka Streams运行时,轻量但状态管理依赖Kafka内部Topic。

2.6 流式SQL在风险归因中的选型建议

选型决策树:
  • 需要复杂多流Join(如交易流+用户画像流+设备指纹流)? → 优先选择 Flink SQL,其状态管理和窗口语义更成熟。
  • 数据源全部在Kafka,且规则简单(单Topic过滤/聚合)? → 选择 KSQL,部署运维成本最低。
  • 需要与现有批处理ETL共用引擎? → 选择 Spark Structured Streaming,但需接受微批带来的额外延迟。
  • 需要实时物化视图且SQL兼容性要求高? → 选择 RisingWave 或 Materialize。
风险归因最佳实践:在大型风控平台中,通常采用混合架构——Flink SQL负责核心的复杂归因计算(如团伙欺诈检测、跨账户资金链分析),KSQL负责边缘节点的实时规则过滤(如单笔交易金额阈值检查),两者通过Kafka Topic解耦。