Flink 2.1 SQL:解锁实时数据与AI集成,实现可扩展流处理

本文整理自阿里云的高级技术专家、Apache Flink PMC 成员李麟老师在 Flink Forward Asia 2025 新加坡站 ------ 实时 AI 专场中的分享。将带来关于 Flink 2.1 版本中 SQL 在实时数据处理和 AI 方面进展的话题。

本篇将探讨三个部分:

Data + AI:在 Flink SQL 中连接实时数据处理与AI能力

首先,将介绍 Flink SQL 2.1 如何连接实时数据处理与AI能力。您将看到我们如何增强对 AI 函数的支持,从模型注册到通过ML_PREDICT与 SQL 的无缝集成,支持大模型文本生成和RAG工作流等任务。

优化 Join:解决 Flink 流式 Join 中的关键挑战

接下来,了解一下解决流式连接中的一个关键挑战。深入探讨两个关键改进:Delta Join,通过结合索引和变更日志处理来消除状态存储;以及 Multi-way Join,在保持低延迟的同时减少多流连接中的冗余。

未来展望:Flink SQL 在数据与 AI 方面的持续增强和路线图

最后,将分享未来的路线图,包括 RAG 管道中的向量搜索支持和扩展的AI函数支持。

接下来我将展示 Flink 2.1 如何让您无缝构建可扩展的实时 AI 管道。在深入 Flink AI 函数之前,让我们先从一个现实世界的问题开始。

案例:实时产品合规性

想象一下您正在运营一个全球电商平台。平台卖家每天会发布数百万个产品。但问题是:您需要确保每一个产品发布都符合您运营的每个国家的当地法律。

例如,一个标题为"含微量酒精的葡萄汁饮料"的产品在特定国家违反了政策,因为它包含"酒精"。

目前,团队使用 Flink SQL 构建管道来帮助人工审核:

  1. 首先从 Kafka 主题读取产品列表数据

  2. 使用自定义 UDF 如keyword_match,根据禁用关键词列表检查标题

  3. 输出风险列表供人工审核

但问题是------基于规则的系统非常僵化。

基于规则的关键词匹配的挑战:误报和漏报

好的,让我们看两个基于规则的关键词匹配失败的具体例子。

案例1:过度阻拦案例(误报)

想象一个标题为"葡萄汁(无酒精)"的产品。关键词"酒精"触发了规则,系统将其标记为风险。但它明确说了"无酒精"!这是一个误报------我们阻拦了一个安全的产品,浪费了人工审核时间,并可能导致客户不满。

案例2:阻拦不足案例(漏报)

现在,看看这个标题:"天然香草提取物"。我们的关键词列表包括"酒精"和"酒",但香草提取物通常含有酒精!规则完全遗漏了它------这是一个漏报。这可能导致严重的处罚。

那么...我们如何解决这个问题?这就需要比关键词匹配更智能的检测能力。

利用AI的语义分析实现更智能的合规性

让我们测试一下 AI 是否更优秀。这里有一个 ChatGPT 的简单例子------这可以是您训练的任何 LLM 或自定义模型。

步骤1:教AI任务

我们给模型一个清晰的提示,包括角色、规则和示例。

步骤2:用我们的问题案例测试

当我们输入棘手的"天然香草提取物"案例时,AI推导出它"含有酒精"。这正是我们需要的。

现在,让我们尝试将其集成到 UDF 中。

我们构建了一个直接连接到 LLM 的新 UDF,管道看起来几乎和以前一样。相同的流程:

  1. Kafka 输入(产品标题流入)

  2. 升级到新 UDF 后,决策现在更加智能

  3. Kafka 输出(结果进入相同的审核主题------下游无需更改)

看起来完美...但是等等。

虽然这对小规模测试有效,但现实的挑战很快就会出现。

构建自定义 LLM UDF一开始感觉很棒,但现实情况是

  1. 代码重写:如果我们想从 OpenAI 切换到阿里云,我们需要重写 UDF 代码。测试不同的模型?更多的代码更改。这种方法无法扩展。每次新模型或 API 更改时重写 UD F代码是不高效的。

  2. 同步请求 = 交通堵塞 :每个产品标题都会触发对 LLM 的同步 API 调用。每次调用需要1-3秒------那么吞吐量将非常低。所以如果我们想要使用异步请求获得更高的吞吐量,我们需要通过使用AsyncScalarFunction再次重写 UDF。现在我们应该更多地关注异步回调和错误处理。这不有趣,必须有更好的方法。

让我们看看 Flink 2.1 如何解决这个问题。

以下是利用 Flink SQL 原生 AI 函数的工作流程:

使用CREATE MODEL通过简单的 SQL 命令注册需要的 LLM。需要切换模型?只需更改MODEL参数------无需重写代码。模型管理变得如此简单。

Flink 2.1 中的新ML_PREDICT()函数已为这些用例做好准备:

  1. 聊天/生成式任务:对于产品合规性检查、情感分析等场景,只需将文本传递给模型,它就会返回分析结果。

  2. embedding:进行特征提取,通过从文本生成向量嵌入来为您的 RAG 管道提供支持。

一切都直接在 SQL 中工作。启用异步处理:只需添加一个简单的参数。切换模型:在 SQL 查询中引用MODEL名称,无需 UDF 代码更改。

让我们通过一个具体的示例将所有内容整合在一起。以下是 Flink AI 函数如何解决我们的产品合规性挑战:

首先,我们使用CREATE MODEL语法创建一个合规性模型------需要指定提供商(这里是阿里云的百炼平台)、模型名称qwen-turbo,以及告诉AI其作为产品列表审核专家角色的系统提示。

当像"天然香草提取物"这样的产品标题到达时,Flink 通过ML_PREDICT函数将其发送到AI模型。这是一个异步请求以确保高吞吐量。模型分析它并返回 JSON 响应。

最后,当risk_rate超过定义的阈值时,我们将结果插入风险输出 topic。

让我们深入了解两个关键优化:异步配置和资源设置。

  1. 异步执行是首选 :在ML_PREDICT()调用中启用异步执行可以是首选。与增加任务并行度相比,这更具成本效益。对于仅追加的流,使用allow_unordered output_mode,这样Flink可以处理得更快。设置max-concurrent-operations以匹配您的 LLM 容量。如果您不想触发任务失败,可以将异步超时参数设置得比 AI 的最大延迟更大。有关异步操作的更多详细信息,请参考Flink文档

  2. 基于 Little 定律进行资源规划:应用此公式进行容量规划:

    • L:队列槽位(对应max-concurrent-operations

    • λ:请求速率(对应预期的QPS)

    • W:平均延迟(对应模型的响应时间)

例如:对于目标100 QPS和1.2秒的99百分位延迟,我们需要120个最大并发请求(max-concurrent-operations)。此外,考虑到队列长度和平均行大小,我们需要更多关注 TaskManager 中的内存设置。适当的调优可能显著提升运行AI函数的吞吐量和稳定性。

JSON 无处不在:从大数据到AI工作流

在深入了解 Join 之前,先聊一聊一个基础的数据类型:JSON。

让我们从一个简单的事实开始:JSON 无处不在。从传统数据管道到新的 AI 工作流,JSON 是表示结构化和半结构化数据的重要格式。我们在事件日志、搜索文档、API 负载中看到它。RAG 管道依赖 JSON 来存储和查询文档。甚至 LLM 提示和输出通常也格式化为 JSON。

到目前为止,Flink SQL 已经支持许多内置的 JSON 函数。但随着 JSON 变得更深入和更动态,这里有一个性能挑战。

表面上,JSON_VALUE和类似的函数使得访问 JSON 字符串内的数据变得容易。但在底层,每次调用都会触发完整的JSON 解析。每次都是如此,对每一行都是如此。这对简单情况可能工作得很好,但在处理大型数据集、嵌套结构或深度查询路径时------比如 JSON 路径$.metadata.device------性能会快速下降。

没有schema感知,JSON 内部没有索引,所以 SQL 优化器无法优化访问。

Flink 2.1 引入了新的VARIANT类型,这是一个原生的、二进制编码的半结构化类型。与普通的JSON字符串不同,VARIANT以结构化方式存储元数据和值。因此访问data.metadata.device只是一个直接的偏移查找,不再是完整的解析。

因为它是感知 schema 的,SQL 规划器可以在未来版本中应用查询优化。这使其非常适合数据管道。VARIANT为大规模处理 JSON 解锁了性能和灵活性。了解更多关于Flink VARIANT类型的信息。

现在让我们转向流式连接,这是实时处理中的另一个核心挑战。Flink SQL 支持丰富的连接类型:Regular Join、Interval Join、Temporal Join、Lookup Join 等等。每种都是为特定用例设计的。其中,regular join 是最直观的------它看起来完全像传统的 SQL 连接,使其易于编写和理解。

让我们看看 Regular Join 是如何工作的:我们有两个输入流:页面浏览和订单从 Kafka 到达,它们将通过product_id列实现 Join。Join 操作符有两个状态存储,左状态和右状态,都按product_id 分组存储。当新事件到达时,Flink 在对端的状态表中查找匹配的条目,执行连接逻辑并输出。

Regular Join 严重依赖 Flink 的状态后端来缓冲输入流。当正确使用时,这提供了高吞吐量和低延迟,特别是对于小到中等大小的数据流。但随着流大小的增长,Regular Join 开始出现问题。连接节点每一侧维护的状态变得越来越大。最终,这导致状态访问缓慢、检查点时间长和恢复时间长。您可能开始看到延迟峰值、背压,甚至检查点失败。这是一个经典的权衡------简单性和灵活性以可扩展性为代价。

那么我们如何解决 Regular Join 的大状态问题呢?

Delta Join:无状态 Join 的全新范式

这就是 Delta Join 的用武之地------它带来了一种截然不同的设计思路。与传统 Join 方式将所有数据缓存在 Flink 状态后端不同,Delta Join 转而依赖外部存储系统(例如基于 RocksDB 构建的 Apache Fluss),将数据存于外部,实现真正的无状态计算。

其工作原理如下:

Fluss 会持续发送变更日志(changelog)更新,确保 Join 数据始终最新。每当有新事件到达时,Delta Join 只需在 Fluss 中执行一次索引查询------就像访问一个键值存储(key-value store)一样简单高效。

可以看到,现在的 Delta Join 已经完全无状态。此前困扰流处理的各种"大状态"问题也随之消失。这使得过去难以实现的大规模 Join 任务,如今成为可能。

Delta Join 实战表现:真实场景下的性能飞跃

在生产环境中的实际表现印证了 Delta Join 的巨大价值。

传统的流式 Join 在数据规模扩大后迅速变得难以维系:状态体积膨胀至 100TB 以上,检查点耗时极长,故障恢复复杂且耗时。而通过 Delta Join,我们将状态外卸至 Fluss 等外部存储系统,实现了秒级检查点,CPU 与内存使用降低超 80%,启动冷启时间缩短 87%,并首次实现了 Join 算子的实时可追溯性。这使得 Flink 在处理超大规模 Join 任务时,变得更加稳定、高效、可扩展。

级联 Regular Join vs. Multi-way Join:从冗余中突围

让我们深入看看传统 Join 的一个"隐形陷阱"------尤其是在多流关联场景下的性能瓶颈。

Flink 的 Regular Join 是一个二元操作:一次只能连接两条流。如果我们想关联 T1、T2 和 T3 三张表,系统必须构建一个级联式执行计划:先将 T1 与 T2 关联,再将结果与 T3 关联。

这种模式带来了严重的效率问题:

每个 Join 阶段都需要维护自己完整的状态;

中间结果(如 T1 与 T2 的关联结果)会被重复存储;

整体状态体积呈倍数增长,检查点时间急剧上升。

虽然 FLIP-415的mini-batch join 能缓解部分中间结果输出的压力,但无法解决状态重复存储的根本问题。

那么,如何破局?

答案就是:Multi-Way Join。

流式 Multi-Way Join:高效 Join 的新范式

Multi-Way Join 是一种全新的 Join 策略,从设计源头就杜绝了冗余。

它允许使用同一个关联键,在单个算子内同时关联多条流。不同于级联式的二元 Join,Multi-Way Join 为每条输入流维护一个独立的索引状态表,不再生成中间 Join 结果,也无需嵌套存储。

这意味着:

  • 没有中间状态复制

  • 没有嵌套检查点延迟

关联的流越多,优势越明显。尤其在复杂事件处理、多维事实表关联等场景下,性能提升显著。

接下来,让我们看看 Flink SQL 的未来发展方向。

一个重要的短期目标是:在 SQL 中原生支持端到端的 RAG(检索增强生成)流程。

目前,用户可以使用 Flink 生成嵌入向量并写入 Milvus 等系统,但检索环节仍无法通过 SQL 直接处理。

未来,我们将引入 VECTOR_SEARCH 函数,直接在 Flink SQL 中实现向量检索,并结合 ML_PREDICT 完成嵌入与生成,实现完全声明式的 RAG 流水线:

  • 数据摄入与向量化

  • 通过向量检索获取 top-k 相似结果

  • 将检索结果用于下游模型推理

整个流程无需编写 Java/Python 代码,真正实现"用 SQL 写 AI 流水线"。

AI 能力扩展:支持多模态与评估函数

我们也在持续拓展 Flink SQL 的 AI 能力边界。除了现有的文本处理和嵌入函数,未来将支持:

  • 多模态处理:支持图像、音频等非文本输入;

  • 评估函数(Evaluation Functions):在流水线执行过程中,实时评估模型输出的质量(如相关性、毒性、重复率等)。

这些能力将帮助用户在数据流中直接集成、监控和调优模型行为,实现更完整的智能处理。

持续优化:流式 Join 性能再突破

Join 性能始终是流式计算的核心课题。Delta Join 已通过解耦了 Flink Task 与本地状态的强绑定,有效解决了大数据量 Join 的扩展性难题。未来,我们将进一步支持更多存储引擎(如 Apache Paimon),以实现近实时 Delta Join。同时,我们也在增强对复杂多流 Join 的支持,包括:

  • 放宽 Schema 对齐要求;

  • 支持更丰富的查询模式;

目标是让 Flink 在面对复杂关联场景时,更加灵活、高效、易用。

最后,总结本次分享的三大关键点:

  1. Flink SQL 融合 AI:让数据与智能无缝集成 原生支持模型管理与 AI 函数,让 AI 流水线在 SQL 中更统一、更易用; 新增 VARIANT 类型,高效处理 JSON 等半结构化数据,为未来 Planner 优化奠定基础。

  2. 攻克流式 Join 顽疾 Delta Join:通过状态卸载,彻底摆脱本地大状态束缚,提升稳定性与资源效率; Multi-Way Join:消除多流关联中的冗余状态,实现更轻量、更快速的 Join 处理。

  3. 未来路线图:更智能、更灵活 扩展 AI 支持:集成向量检索、多模态处理; 持续优化 Join 性能:支持更多存储、更复杂查询。

所有这些努力,都是为了一个目标:让 Flink SQL 成为构建实时、智能数据流水线的终极利器。

相关推荐
Hello.Reader33 分钟前
以 Eland 玩转 Elasticsearch 8.12 Learning-to-Rank
大数据·elasticsearch·jenkins
ALex_zry39 分钟前
Git Status 命令深度指南:洞悉仓库状态的核心艺术
大数据·git·elasticsearch
weixin_425878232 小时前
AWS 可靠性工程深度实践: 从 Well-Architected 到“零失误”VPC 落地
大数据·云计算·aws
九河云2 小时前
华为云代理商的作用与价值解析
大数据·人工智能·华为云
SelectDB3 小时前
天翼云与飞轮科技达成战略合作,共筑云数融合新生态
大数据·数据库·数据分析
Sunhen_Qiletian4 小时前
机器学习实战:逻辑回归深度解析与欺诈检测评估指标详解(二)
大数据
慌ZHANG6 小时前
云原生安全挑战与治理策略:从架构思维到落地实践
大数据·云原生·架构
程序员小羊!7 小时前
Hadoop HDFS 3.3.4 讲解~
大数据·hadoop·hdfs
张太行_7 小时前
人月神话:软件工程的永恒智慧
大数据·软件工程