Flink 2.3 实时 AI 推理实战 —— 第 16 章 生产部署、安全与合规
章节定位:第六篇收官。推理作业上了生产,面对的不再是"跑不跑得通",而是"敢不敢跑"——密钥会不会泄、数据出不出域、模型换版怎么灰度、出问题怎么回滚。本章覆盖部署形态、密钥与配置管理、I/O 密集型资源画像、Checkpoint 与远程调用的一致性边界、PII 脱敏与数据出域管控,以及完整的上线 SOP(灰度/影子流量/回滚)。本章是把前十五章所有能力安全送上生产的最后一道关卡。
版本基线:Apache Flink 2.3.0(JDK 17)+ Kafka 3.x + Paimon 1.4.x + Doris 4.1
章节导读
- 16.1 部署形态:Session / Gateway / 提交规范
- 16.2 密钥与配置管理
- 16.3 资源规划:I/O 密集型作业画像
- 16.4 Checkpoint 与远程调用
- 16.5 数据安全与合规
- 16.6 上线 SOP:灰度、影子流量、回滚
- 16.7 实战:一次完整的上线演练
- 16.8 本章小结与下章预告
16.1 部署形态:Session / Gateway / 提交规范
16.1.1 两种部署形态选型
YARN Session(推荐本课程场景): 推理作业多而碎(分类/归因/RAG 各自一条链路),共享 Session 集群 SQL Client / Gateway 提交,资源复用,启停快 Application Mode: 注意:SQL Client 不支持 application mode(主系列硬约束) 纯 SQL 推理作业要走 Gateway 或打包 DataStream 作业才能用16.1.2 提交规范(沿用主系列,AI 作业无特权)
# ① 所有依赖 jar 进 lib,禁止 -j(双 ClassLoader 报 not a subtype)cpflink-sql-connector-kafka-*.jar$FLINK_HOME/lib/cpflink-sql-connector-paimon-*.jar$FLINK_HOME/lib/cpflink-sql-connector-doris-*.jar$FLINK_HOME/lib/# ② 提交:命名 + Checkpoint + 无限重试./bin/sql-client.sh-fai_alert_pipeline.sql\-Dpipeline.name="alert-attr-ai-v1"\-Dexecution.checkpointing.interval=30s\-Drestart-strategy=fixed-delay\-Drestart-strategy.fixed-delay.attempts=2147483647\-Drestart-strategy.fixed-delay.delay=10s\-Dtable.dml-sync=true| 规范 | 原因 |
|---|---|
pipeline.name必命名 | WebUI 识别,多作业共存排查必备 |
| checkpoint 30s | 与 Paimoncommit.interval对齐(15.3.2) |
| fixed-delay 无限重试 | 远程模型抖动频发,不允许作业退出 |
table.dml-sync=true | YARN 提交下等待 sink 完成,避免异步遗留 |
| JDK 17 全栈 | 主系列硬性基线,不可降级 |
16.1.3 环境隔离
三套环境,模型注册与 Kafka group 全面隔离: dev → endpoint=test 网关, group.id=ai-dev-* staging → endpoint=内网灰度网关,group.id=ai-staging-*(影子流量用) prod → endpoint=内网生产网关,group.id=ai-prod-* 模型命名带版本: ai.alert_attr_v1 / ai.alert_attr_v2(第 4 章规范) → 同名不同环境,配置注入区分,DDL 本身零改动16.2 密钥与配置管理
16.2.1 三红线(第 4 章确立,本章落地)
红线一:禁止硬编码——api-key 不出现在任何 .sql / .java / git 仓库 红线二:禁止入日志——密钥不打印,Provider 日志脱敏 红线三:生产必走内网网关——密钥集中在网关层,作业侧拿网关临时凭证16.2.2 envsubst 注入流程
# DDL 模板(入库管理):api-key 只有占位符# model.sql.tplCREATE MODEL alert_attr INPUT(alert_text STRING)OUTPUT(result STRING)WITH('provider'='openai','endpoint'='${LLM_GATEWAY}','api-key'='${LLM_API_KEY}', -- 占位符,非密钥'model'='qwen-turbo');# 发布流水线:K8s Secret / Vault → 环境变量 → 渲染exportLLM_GATEWAY="https://llm-gw.prod.internal/v1"exportLLM_API_KEY="$(vault kv get-field=key secret/flink/llm)"envsubst<model.sql.tpl>model.sql# 渲染产物不进 git./bin/sql-client.sh-fmodel.sqlrm-fmodel.sql# 渲染后即用即焚16.2.3 密钥轮换 SOP
① 网关侧签发新密钥,新旧并行生效 24h ② 流水线重新渲染 DDL → DROP MODEL + CREATE MODEL(模型对象重建) 注意:改模型定义需 stop 作业 → 执行 DDL → 无状态重启(16.4.3) ③ 验证调用成功率 → 网关侧吊销旧密钥 ④ 全程作业侧零感知,密钥未落任何文件16.3 资源规划:I/O 密集型作业画像
16.3.1 与计算密集型的根本差异
常规 ETL 作业:CPU 打满,内存吃状态,网络其次 AI 推理作业: CPU 常年 10%~30%——大部分时间在等 HTTP 响应 网络出口带宽是命脉(尤其公网模型) 内存主要消耗:异步 buffer、结果缓存(13.4)、连接池16.3.2 并行度测算(12.6 公式回顾)
所需并行度 ≥ 峰值 QPS × 平均推理延迟(秒) 示例:峰值 500 msg/s,平均延迟 1.2s → 600 并发 → 若单 subtask 异步并发 32 → 约 19 个推理 subtask → Kafka 分区数决定 source 并行度,扩容前先确认分区够(15.1.3)16.3.3 资源配置建议
| 资源 | 建议 | 说明 |
|---|---|---|
| TM CPU | 2~4 core | 推理算子异步,CPU 不是瓶颈 |
| TM 内存 | 4~8 GB | 大头在异步缓冲与缓存,非状态 |
| 网络 | 保证出口带宽与网关间低延迟 | 内网网关是硬性要求之一 |
| 重算子隔离 | slotSharingGroup独立隔离 | 重 Join/推理算子不与轻算子抢 slot |
| state backend | ForSt | 大状态窗口基线(主系列) |
压测方法见 12.6:逐级加压找到 ML_PREDICT 算子反压拐点,P99 达标线以内定容量,预留 50% 余量应对模型服务抖动。
16.4 Checkpoint 与远程调用
16.4.1 一致性边界:必须说清的一件事
远程模型调用本身:非事务、不可回滚——barrier 来了,在飞的 HTTP 请求 不能"暂停",要么等它完成,要么超时放弃 Exactly-Once 的边界: 作业内部状态:Flink Checkpoint 保证 结果落地: 靠 sink 幂等 upsert(Doris UK+MoW / Paimon PK) ——主键去重兜住故障重放产生的重复推理(15.2.2) 模型侧: 同一输入重复调用,结果可能不同(采样温度) → 接受"至少一次推理 + 幂等落地 = 端到端效果唯一"16.4.2 异步推理与 Checkpoint 的协同
风险:异步 in-flight 请求过多 → barrier 对齐慢 → Checkpoint 超时 对策: ① 限制单 subtask 异步并发(max-parallelism),控制 in-flight 总量 ② timeout 必须 < checkpoint 超时的可容忍窗口(30s timeout vs 60s ck) ③ 背压时启用 Unaligned Checkpoint(主系列调优组合) ④ 推理超时样本打 degraded 标记走兜底(13.3),不阻塞 barrier16.4.3 表/模型变更的铁律
DDL 变更(加列/改模型定义/换模型版本): stop 作业 → 执行 DDL → 无状态重启 禁止依赖 Savepoint 恢复不兼容变更: schema 对不上会抛 OutOfRangeException(主系列教训) 推理作业状态价值低(主要是维表缓存/窗口),无状态重启代价小 → 这是 AI 作业相对重状态 ETL 作业的一个隐性优势16.5 数据安全与合规
16.5.1 PII 脱敏:入 prompt 之前
-- 推理前置脱敏视图:手机号/身份证掩码,VIN 保留(业务键)CREATETEMPORARYVIEWalert_maskedASSELECTevent_id,vin,REGEXP_REPLACE(REGEXP_REPLACE(alert_text,'(1[3-9]\\d)\\d{4}(\\d{4})','$1****$2'),-- 手机号'(\\d{6})\\d{8}(\\d{4})','$1********$2')-- 身份证ASalert_textFROMalert_src;-- ML_PREDICT 输入一律取 alert_masked,原始文本不进 prompt16.5.2 数据出域管控
管控层级: L1 文本脱敏(16.5.1):prompt 内无 PII L2 网关审计:内网网关记录全量请求,可审计"什么数据给了哪个模型" L3 模型侧约束:与模型服务方约定不留存/不训练(合同层) L4 最强管控:私有化部署自建 vLLM(第 10 章),数据物理不出域 车联网红线:VIN 关联车主信息属敏感数据 审计表(14.6)入湖前 VIN 哈希化:SHA256(vin + salt),salt 单独保管16.5.3 审计表脱敏衔接
14.6 的 inference_audit 入湖链路: input_text/output_text 已是脱敏后文本(16.5.1 视图产出) vin → vin_hash(SHA256 加盐) 保留 trace_id / model_ver / latency / degraded(无敏感信息) → 满足"可追溯"与"不泄敏"的双重要求16.6 上线 SOP:灰度、影子流量、回滚
16.6.1 三段式上线
阶段一 影子流量(1~3 天): 新作业用独立 group.id 旁路消费同一 Kafka topic 结果写影子表(*_shadow),不影响生产表 离线对比:影子 vs 生产(若有旧逻辑)/人工抽检 阶段二 小流量灰度(10%): 按 vin 哈希取模分流:v1 处理 90%,v2 处理 10% 监控五件套(14.4)+ 在线评估(14.1)双盯 阶段三 全量: 灰度指标达标 → 100% 切换 → 旧版本模型注册保留 7 天(回滚窗)16.6.2 影子对比 SQL
-- 影子表与生产表结果一致性对比SELECTCOUNT(*)AStotal,SUM(CASEWHENs.label=p.labelTHEN1ELSE0END)*1.0/COUNT(*)ASagree_rateFROMai_alert_result_shadow sJOINai_alert_result pONs.event_id=p.event_id;-- agree_rate < 95% → 逐条 diff 分析,不准上线16.6.3 回滚预案
回滚级别(从轻到重): L1 调用级:ML_PREDICT CONFIG 切回 v1 模型名 → 秒级,SQL 重提 L2 模型级:DROP v2 → 作业重新指向 alert_attr_v1(16.4.3 流程) L3 作业级:整体下线 v2 作业,旧作业无状态重启接管 L4 数据级:v2 期间脏数据按 model_ver 圈定 → Paimon 侧重刷(15.3.4) 关键:模型双注册(v1/v2 并存)让 L1/L2 回滚永远可行16.6.4 上线检查单
□ 密钥走 envsubst + 网关,git 全文检索无 key 字样 □ 影子流量 ≥ 24h,agree_rate 达标,五件套指标正常 □ 降级兜底链路实测(手工断网关,degraded 打标率上升,主链路不停) □ 回滚演练:L1/L2 各演一次,记录耗时 □ 监控大盘与六条告警规则已上线(14.5) □ 审计表含 trace_id + model_ver,PII 已脱敏 □ 作业命名/Checkpoint 30s/无限重试/table.dml-sync 已配置16.7 实战:一次完整的上线演练
16.7.1 场景
alert_attr 模型 v1(qwen-turbo) → v2(qwen-plus,归因更准但更贵) 目标:零中断完成升级,具备随时回滚能力16.7.2 执行步骤
# Step1 注册 v2 模型(与 v1 并存)envsubst<model_v2.sql.tpl>model_v2.sql ./bin/sql-client.sh-fmodel_v2.sql# 校验:SHOW MODELS; 应见 ai.alert_attr_v1 与 ai.alert_attr_v2# Step2 影子作业:同 topic 独立 group,指向 v2,写影子表./bin/sql-client.sh-falert_attr_shadow.sql\-Dpipeline.name="alert-attr-v2-shadow"\-Dexecution.checkpointing.interval=30s\-Drestart-strategy=fixed-delay\-Drestart-strategy.fixed-delay.attempts=2147483647# Step3 24h 后跑影子对比(16.6.2 SQL),agree_rate ≥ 95% 继续# Step4 生产作业切流:stop → 修改 ML_PREDICT 指向 v2 → 无状态重启./bin/cancel.sh<v1_job_id>./bin/sql-client.sh-falert_attr_v2.sql\-Dpipeline.name="alert-attr-ai-v2"\-Dexecution.checkpointing.interval=30s\-Drestart-strategy=fixed-delay\-Drestart-strategy.fixed-delay.attempts=2147483647\-Dtable.dml-sync=true# Step5 观察 24h:在线评估准确率应升,成本在预算内# Step6 达标 → 7 天后 DROP v1;不达标 → L2 回滚(指回 v1)16.7.3 演练记录模板
| 项 | 记录位 | | 影子时长 | ____ h | | agree_rate | ____ % | | v2 准确率增益 | ____ pp(在线评估) | | 成本增幅 | ____ %(token 日用量对比) | | 回滚演练耗时 | L1 ____ min / L2 ____ min | | 审批人 | ____ |16.8 本章小结与下章预告
本章小结
┌──────────────────────────────────────────────────────────────┐ │ 第 16 章 要点回顾 │ └──────────────────────────────────────────────────────────────┘ ✓ 部署:Session 为主(SQL Client 不支持 application mode); jar 进 lib 禁 -j;命名+30s Checkpoint+无限重试+dml-sync ✓ 密钥:三红线;envsubst 渲染即用即焚;轮换走网关双密钥并行 ✓ 资源:I/O 密集型——CPU 轻、网络是命脉;并行度=QPS×延迟; slotSharingGroup 隔离重算子;ForSt 状态后端 ✓ 一致性:远程调用非事务;幂等 upsert 兜底端到端效果唯一; 异步并发限总量;DDL 变更必须 stop→改→无状态重启 ✓ 合规:prompt 前脱敏;网关审计;出域四级管控; 审计表 VIN 加盐哈希 ✓ SOP:影子流量→10% 灰度→全量;模型双注册保回滚; 回滚四级预案;上线检查单逐项打勾下章预告
第 17 章 实战一:实时告警智能归因与分级
第七篇开战——车联网告警洪峰的智能化治理:业务需求拆解(自动分类/根因归纳/处置建议/严重等级)、链路设计(Kafka 告警流 → ML_PREDICT 结构化推理 → 结果落 Doris)、稳定 JSON 输出的 Prompt 设计、结果解析与异常兜底、超时降级与人工审核闭环、分级准确率/误报率/人工采纳率的效果验证。前十六章的所有能力,将在本章拧成一条完整的生产链路。
官方参考资料
- Apache Flink 2.3 Documentation(首页,含部署 / 配置参考)
- Flink 2.1 发布公告(ML_PREDICT / Model DDL 能力介绍)
- Flink 2.2 发布公告(Table API 推理与 VECTOR_SEARCH 增强)
本章实战代码清单
序号 内容 说明 1 提交规范命令(命名/Checkpoint/重试/dml-sync) 16.1.2 2 envsubst 密钥注入流程与轮换 SOP 16.2.2 / 16.2.3 3 I/O 密集型资源配置表 16.3.3 4 Checkpoint 与异步推理协同四对策 16.4.2 5 PII 脱敏视图 SQL(手机号/身份证/VIN 哈希) 16.5.1 / 16.5.2 6 影子对比 SQL + 四级回滚预案 + 上线检查单 16.6 7 v1→v2 零中断升级六步演练 16.7