datainfra前沿动态 · Vol.62

Databricks 开源 Consort 让数据库随代码分支;Glue 6.0 把作业编排收进单个 Spark 作业;Doris + Paimon 2.0 让向量检索回到开放湖表;AI/BI 用一张授权表服务所有观看者

本期聚焦四条 9 月 9 日发布的动态:Databricks 把 copy-on-write 分支的 Lakebase 与一套开源 agentic 框架打包,让 TDD 第一次跑在真实数据库上;AWS Glue 6.0 的 Spark Declarative Pipelines 用表引用推导依赖图,把三层 medallion 收回一个作业;Apache Doris 4.2 把 Paimon 2.0 的 Vector Index 接进 MPP 查询计划,快手实测亿级向量召回率 96.0%~99.6%;Databricks 给出 AI/BI 仪表盘的行级安全参考架构,用一张 entitlements 表覆盖嵌入与直连 SQL 两条路径。

DataInfra Databricks Lakebase Consort 数据库分支 TDD AWS Glue 6.0 Spark Declarative Pipelines Apache Spark 4.1 Apache Doris Apache Paimon 向量检索 多模湖仓 Unity Catalog 行级安全 数据治理

四条动态都落在 9 月 9 日,指向同一个动作:撤销复制品。过去要满足不同使用者,习惯是复制一份出来再改——给测试复制一套 mock 环境、给每一层复制一个 Glue 作业外加一个编排器、给检索复制一份向量进独立库、给每个客户复制一份仪表盘。四条新闻给出的答案一致:只保留一份实体,把差异写进一层可查询、可审计的规则(分支、表引用、索引、授权表)。复制品消失了,代价并没有消失,而是各自换了个位置——conductor 必须是不可商量的状态机、物化视图每次全量重算、外表查询比内表慢 1.07 到 4.18 倍、一个 token 只能携带一个 scope。

Databricks 开源 Consort:数据库能分支之后,TDD 第一次有了真实的”边”

事件概述

Databricks Field Engineering 的 Kevin Hartman 在 9 月 9 日发布 Consort——一个以 Lakebase Postgres 分支能力为地基的开源 agentic 开发框架。文章开头先拆了那句行业口号「像分支代码一样分支数据库」:它真正改变的不是某个数据库开关,而是困难测试发生的时间点。

作者的论证路径很直接。过去集成测试属于外循环——起一个库、灌入 schema 和数据、给每个单元测试都做一遍,代价高到没人真的做,于是团队改用 mock。mock 的问题不是”假”,而是随时间漂移:维护得越久,验证到的真实行为越少。copy-on-write 分支把建库成本压到与数据量基本无关的常数级,第一个 TDD 测试就能跑在真实数据的活分支上,可以随便炸掉 schema,其余人不受影响,用完即弃。

第二个变化是 schema 与代码作为一个单元交付。schema 以版本化迁移(Alembic / Flyway / Knex,按技术栈)随代码走,合并的是 schema 而非数据;DBA 在 pull request 里以 code owner 身份评审迁移脚本,不再是一条下游工单。作者给这个模式起名 Data CD。

技术解析

  • 框架把团队角色映射成 agent:product owner、spec author、architect reviewer、DBA、test strategist 各占一个角色,加上 navigator/driver 结对,由 conductor 调度。工作分两条泳道——先冻结意图的 spec-first 设计泳道,再是对着真实数据库分支跑完整 red/green/refactor 的构建泳道。
  • driver 不许挪动球门:写代码的角色不能为了让测试变绿而改测试,唯一例外是后续 story 正式废止旧测试。绿的定义是”测试在真实数据库分支上跑过并通过”,不是 agent 自己说通过。
  • conductor 是代码而非 agent:这一层是确定性状态机,负责路由、把守人工审批门禁、在冲突时把工作打回对应角色。设计意图明确——驱动流程的那层不能被说服跳过某一步。
  • 防”丢掉任务”:每个 feature 的产物放在专用目录结构中,作为角色之间的契约;每个 agent 拿到的是裁剪过的上下文包(要过哪些测试、设计约束、测试文件在哪),而不是整个代码库。作者把无作用域的访问视为 agent 漂移的主因。
  • 并行实验各有独立分支:同一个 story 的多种实现各自开一个数据库分支加一个 worktree,跑完保留更好的那个。VS Code 插件把成对的 Git 与 Lakebase 分支跨层展示,代码与 schema 变更进同一个 diff 视图。

行业影响

Consort 是开源社区支持项目,不是带 SLA 的平台功能,官方也写明”成品应用就跑在 Lakebase 上,分支只是开发期的做法”——Lakebase 是 Postgres,不必为了用 Consort 改造技术栈。这个定位值得注意:Databricks 把 Lakebase 的分支能力当作一层可编程基础设施对外开放,让社区去试 agent 化开发流程的边界,而不是自己发布一个”AI 写代码”产品。

从 Vol.53 的 Ray Data 双引擎到 Vol.61 的 LTAP 与 Temporal + Lakebase 持久执行,Databricks 近期的动作集中在”让 agent 能安全地使用真实状态”。Consort 补上的是最靠左的一环——在代码被写出来之前,先给 agent 一个撞得疼的边。

相关链接


AWS Glue 6.0 的 Spark Declarative Pipelines:把编排从外部 DAG 收进单个作业

事件概述

AWS Big Data Blog 在 9 月 9 日给出 Glue 6.0 上 Spark Declarative Pipelines(SDP) 的完整教程,用 Bronze / Silver / Gold 三层 medallion 演示声明式 ETL。对比的基线很清楚:命令式做法要 3 个独立 Glue 作业,外加 MWAA 或 Step Functions 承担顺序、错误处理与重试,架构上分出”编排层”和”ETL 处理层”两层;SDP 把这两层压成一个 Glue 作业,依赖图由代码里的表引用推导而来,检查点与执行顺序由框架接管。

核心抽象只有三个 Python 装饰器:@dp.table(流式表,每次运行增量处理新数据,适合原始事件摄取与 CDC)、@dp.materialized_view(物化视图,当前每次运行完全重算)、@dp.temporary_view(临时视图,仅 pipeline 作用域内有效,不落盘)。

技术解析

  • 两个正交的运行控制维度:spark.glue.sdp.jobMode 回答”跑不跑”——VALIDATE 是 dry-run,检查 YAML 语法、依赖解析与 SQL/Python 编译,不写任何数据;RUN 为默认。spark.glue.sdp.runMode 回答”重算什么”——--refresh <datasets> 只更新指定数据集,--full-refresh 重置重算(对流式表还会清 checkpoint),--full-refresh-all 覆盖全部。默认 RUN 会重算每一个物化视图。
  • Python 与 SQL 混写,跨语言依赖自动解析:管道规范 spark-pipeline.yml 用 libraries.glob 发现转换文件,SQL 定义的物化视图可直接引用 Python 定义的表。
  • 打包方式变了:ScriptLocation 指向的是管道 zip(或带尾随 / 的 S3 prefix),不是传统 .py;yml 里的 __BUCKET__ 等 token 必须在打包阶段替换,shell 变量不会在运行时展开。
  • Spark 4.1 的坑:Glue 6.0 构建于 Apache Spark 4.1,默认开启 ANSI mode,原始字符串列直接与数字比较会失败,必须先 cast。
  • 治理覆盖不完整:Lake Formation 细粒度访问控制只覆盖批读,只对物化视图生效,不适用于流式表;SDP 不会自动创建数据库,spark-pipeline.yml 里的库必须已存在且带 S3 LocationUri。

行业影响

编排下沉到执行引擎不是新话题,但 AWS 这次给出的形态值得对标:它把”哪一步先跑”与”重算什么”拆成两个可组合的参数,等于把运维里最高频的两个判断(要不要先干跑一遍、出问题时回滚到哪一层)变成了作业参数而非代码分支。Glue 6.0 每 DPU-hour 比 5.1 便宜 30%,也让”把三层收回一个作业”在账单上说得过去。

代价同样写得很直白:物化视图没有增量状态,reset 和 refresh 对它都是全量重算。作者的建议是生产环境的 Bronze 层改用 @dp.table,靠增量而非每次重读全量源。换句话说,声明式省掉的是编排代码,不是计算量。

相关链接


Doris 4.2 × Paimon 2.0:让向量检索回到开放湖表,不再复制一份进独立库

事件概述

9 月 9 日,Apache Doris PMC 成员、SelectDB 多模湖仓负责人李文强发表《Apache Doris + Paimon 2.0:构建 Agentic AI 数据闭环》,是 Doris 5.0 多模湖仓预告的场景方案篇。文章主张:Agentic AI 需要的不是”加一个向量字段”或”接一个向量数据库”,而是让持续变化的业务事实、多模态内容、模型特征、检索索引与行动结果保持一致。

分工被切成两层。Paimon 2.0 管”数据怎么存、怎么演进、怎么建索引”——新增 BLOB(图片/视频/音频独立文件,未选该列就不读对象内容)、VECTOR<t, n>(固定维度 Embedding 与专用存储布局)、VARIANT(结构灵活的事件与模型输出,常用字段可拆成类型化子列)、Data Evolution(只补变化的列,不重写未变的大对象)、Global Row ID(把数据文件、BLOB、向量、索引与删除状态对齐到同一条逻辑记录)、Global Index(标量、全文与向量索引纳入湖表元数据与快照)。Doris 管”怎么把开放数据变成 Agent 能用的上下文”。

技术解析

  • 快照一致的湖表读取:Paimon Catalog 在一条 SQL 内绑定一致的 Snapshot 与 Schema,查询规划理解 Manifest、主键合并、Deletion Vector、增量范围、Time Travel、Branch 与 Tag,避免把 Paimon 主键表退化成普通文件扫描。
  • Vector Index 进查询计划:FE 规划并下发 Split,BE 通过 C ABI 调用 Paimon Rust Reader;向量检索先并行检索索引分片并合并候选,再把候选范围继续下推到文件、Row Group 和 Parquet Page,确认命中后才读取向量、BLOB 元数据或宽列。Rust 侧结果经 Arrow C Data Interface 进 C++ 转成 Doris Block,随后进 MPP 引擎完成标量过滤、跨表 Join、聚合、权限判断、精排与全局 Top-K。
  • 写回路打通:面向 Doris 4.2,Paimon Catalog 从只读走向读写一体,覆盖 INSERT INTO ... SELECT、INSERT OVERWRITE、UPDATE/DELETE/MERGE(更新主键表中的业务状态、模型标签与人工反馈)、CREATE TABLE 与 schema 演进、Variant 读写。BE 按 Paimon 的分区与 Bucket 规则并行生成文件,FE 聚合各 Writer 的 Commit Message,形成原子可见的 Snapshot;失败或重试由提交协调器负责终止、清理、去重与幂等恢复。
  • 快手的实测数字:向量与业务数据保留在 Paimon 主键表,内联 2048 维向量,用 IVF-RQ Vector Index 召回,远端 Alluxio 提供缓存。公开测试使用 1600 万与 1.28 亿条 2048 维真实向量,Top-K 覆盖 100、1 万、100 万,Paimon 外表链路召回率 96.0%~99.6%;与”本地缓存的 Doris 内表”相比,查询耗时为后者的 1.07~4.18 倍,其中 Top-K 为 100 万时差距收敛到 1.07~1.36 倍。

行业影响

这条路径的价值在于否定了”为 AI 再维护一套封闭数据副本”。把向量复制到独立向量库,就要长期维护第二份业务数据与同步链路;模型版本、业务状态与删除数据持续变化,检索系统很容易返回已经过期、无法与当前业务状态对齐的结果。让向量留在 Paimon,检索结果天然能关联最新的业务状态并进入 Doris 的权限过滤与指标计算。

时间表上,Iceberg、Paimon、Lance 等多模湖仓能力已合入 Doris 4.2 发版分支,随 4.2 于 9 月底发布;Fluss 等能力进入主干,计划随 Doris 5.0 年底发布,SelectDB 已提供基于 4.2 的商业预览版。需要注意的是,文章中的性能对比是”远端 Alluxio 缓存的外表”对”本地缓存的内表”,1.07~4.18 倍这个区间本身就是缓存拓扑差异的度量,不是纯粹的执行引擎差距。

相关链接


一份 Dashboard 服务所有观看者:AI/BI 嵌入的行级安全参考架构

事件概述

Databricks 在 9 月 9 日给出 AI/BI Dashboards 嵌入场景的授权参考架构,作者 Sonakshi Pandey。问题设定很具体:仪表盘嵌进客户门户之后,每个观看者该看到哪些行——外部合作方只看自己的数据,内部区域团队只看自己区域。做法上,文章明确说这是一个设计模式,不是一个可以打开的开关。

模型由三个对象构成:基表、entitlements 表(viewer_scope / market / mask_pii 三列,同一列里并存外部伙伴 ID 与内部组名)、以及把二者 join 起来的 secured view。后端以服务主体身份签发嵌入 token 时写入 external_value,Databricks 签名后把它暴露给仪表盘 SQL 为 __aibi_external_value,观看者无法篡改。视图里的过滤条件只有一句 WHERE viewer_scope = __aibi_external_value,同一个视图、同一个过滤器一并服务外部伙伴与内部团队,差别只在 scope 的来源——外部是固定的伙伴 ID,内部是 IdP(Okta / Entra ID)组名。

技术解析

  • 两条执行路径,一份规则:嵌入路径的查询跑在配置好的发布身份下,不是观看者自己的身份,这让 is_account_group_member() 在嵌入路径上无法识别真实的人;直连 SQL 路径则在基表上加 Unity Catalog row filter,按查询者的身份与组求值,可以跨其所有授权组取并集。两条路径共用同一张 entitlements 表。
  • 默认拒绝,并且提前拒绝:未知 scope 匹配不到任何行,返回空结果且不泄露结构信息。更干净的做法是在签发 token 前先查 entitlements 表,对零授权的 scope 直接拒发——被拒的观看者从头到尾拿不到 token。成功签发与拒绝请求都要记日志,external_viewer_id 与 scope 一并落盘,让每个授权决定在审计时可回溯。
  • 掩码按观看者切换:mask_pii 标志驱动视图里的 CASE 表达式,同一份仪表盘对内部观看者显示完整邮箱,对伙伴显示 ****@acme.com 这类掩码值。规则跨多表变复杂后,作者建议把掩码逻辑迁到 Unity Catalog column mask 与 ABAC。
  • 必须绕开的限制:token 有效期 1 小时,需要 getNewToken 回调续签;external_viewer_id 与 external_value 合计不超过 1 KB;外部嵌入有每工作区每秒 20 次仪表盘加载的速率上限;下载默认开启(CSV / TSV / Excel / PNG),需管理员显式关闭;UC row filter 与掩码只对 account-level 组求值,工作区本地组无效;发布身份的 break-glass 例外是可选的、高风险的。

行业影响

这篇稿子的价值在于把”多租户仪表盘”这个常被含糊处理的需求拆成了可验收的工程项。一个 token 只能携带一个 external_value,多组并集的真实需求要么走全权组、要么走直连 SQL 路径——复合 scope 可以塞进 JSON,但解析与匹配会落进数据集 SQL,且仍受 1 KB 限制。这类”写清楚做不到什么”的内容,比功能列表更接近生产落地所需的信息密度。

相关链接


编者评

四条动态是同一个动作的四次重复:撤销复制品。给测试复制一套 mock 环境、给每层 ETL 复制一个作业外加一个编排器、给检索复制一份向量进独立库、给每个客户复制一份仪表盘——四件事的共同结构是”复制一份出来再改,用副本的差异表达需求差异”。这四条给出的替代方案形态一致:只保留一份实体,把差异写进一层可查询、可审计的规则——分支、表引用、索引、entitlements 表。

这层规则之所以值得单独造,是因为它被要求一并满足两个此前冲突的性质:一边要当数据用——能查询、能审计、能不改代码就调整;一边要当契约用——使用方绕不过去。Doris 的解法是把索引放进湖表快照体系,让索引覆盖范围可被识别;AI/BI 的解法是把 scope 签进服务端 token,观看者看不到也改不了;Consort 的解法最激进,直接把 conductor 写成确定性状态机,因为”能被说服跳过一步的流程”不算流程。

代价哪儿都没消失,只是换了位置:Consort 的 conductor 失去了灵活性,Glue SDP 的物化视图每次全量重算,Doris 外表相对内表仍慢 1.07 到 4.18 倍,AI/BI 一个 token 只认一个 scope。判断这类方案是否值得采用,看的不是复制品有没有消失,而是新位置的代价是不是比老位置的漂移成本更可控——mock 与真实行为的偏离、三份作业与外部编排器的运维面、向量副本与业务状态的过期、N 份仪表盘的改版同步,这四项都是会随时间自行恶化的成本,而换来的四项是写死在文档里的边界。