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 两条路径。
四条动态都落在 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 一个撞得疼的边。
相关链接
- Introducing Consort: Test-driven development on a branching database
- Consort 仓库(databricks-solutions/consort)
- Databricks Lakebase 产品页
- Build durable agents with Temporal and Lakebase(Vol.61 已报道,持久执行的上下文)
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里的库必须已存在且带 S3LocationUri。
行业影响
编排下沉到执行引擎不是新话题,但 AWS 这次给出的形态值得对标:它把”哪一步先跑”与”重算什么”拆成两个可组合的参数,等于把运维里最高频的两个判断(要不要先干跑一遍、出问题时回滚到哪一层)变成了作业参数而非代码分支。Glue 6.0 每 DPU-hour 比 5.1 便宜 30%,也让”把三层收回一个作业”在账单上说得过去。
代价同样写得很直白:物化视图没有增量状态,reset 和 refresh 对它都是全量重算。作者的建议是生产环境的 Bronze 层改用 @dp.table,靠增量而非每次重读全量源。换句话说,声明式省掉的是编排代码,不是计算量。
相关链接
- Build declarative ETL pipelines with AWS Glue 6.0
- The 40-year-old database rule agents just broke(Vol.61 已报道)
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 倍这个区间本身就是缓存拓扑差异的度量,不是纯粹的执行引擎差距。
相关链接
- Apache Doris + Paimon 2.0:构建 Agentic AI 数据闭环
- Doris Paimon Catalog 文档
- Apache Doris 5.0 年度版本前瞻(一):构建统一的多模湖仓实时分析平台
一份 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 份仪表盘的改版同步,这四项都是会随时间自行恶化的成本,而换来的四项是写死在文档里的边界。