datainfra前沿动态 · Vol.98

Databricks 把「开放目录」拆成三条可核对的判据,UNREGISTER 之后表仍在自己的桶里;LanceDB 不再让表元数据自带信任,嵌入配置改成进程显式批准;LinkedIn 用 Celeborn 把 shuffle 从 executor 生命周期上剥离,运行时降约 14%、单任务 shuffle 成本降近 90%;Databricks 把 dbt 的增量、布局、治理与成本归因收进平台

本期聚焦 10 月 19 日前后四条把「默认由谁负责」重新指派的动作:目录把存储归属与交接指针交回用户、LanceDB 把嵌入配置的信任源从表元数据挪到进程代码、LinkedIn 把 shuffle 从计算节点的生命周期挪到独立资源边界、Databricks 把 dbt 的运维负担从项目挪到平台。

DataInfra Unity Catalog Apache Iceberg 数据可移植性 LanceDB Lance 嵌入函数 供应链安全 Apache Celeborn Remote Shuffle Apache Spark Apache Flink dbt Lakeflow 成本归因

本期四条动态集中在 10 月 19 日前后,做的事可以概括成一句话:把「默认由谁负责」重新指派一次,并且要求每次交接都是可核对的。Databricks 给开放目录下了三条能逐条核对的判据,并把 REGISTER 与 UNREGISTER 接成一次返回 metadata 指针的交接流程,表始终留在用户自己的桶里;LanceDB 在 v0.41.0-beta.9 里把嵌入函数的信任源从表元数据挪到进程代码,理由是能写表的人就能控制元数据,而 sentence-transformers 默认会执行模型仓库里的远程代码;LinkedIn 把 shuffle 从 executor 的生命周期上剥离到 Apache Celeborn 这一层独立资源边界,给出的数字以自家上一代 Magnet 为基线:应用运行时降约 14%、单任务 shuffle 成本降近 90%、fetch 失败从每天约 750 次降到约 20 次;Databricks 另一篇把 dbt 项目里的增量策略、数据布局、表维护、编排与治理逐项交给平台,只留下版本化且被测试覆盖的转换逻辑。四处动作的代价也各自写在明面上:迁移仍要停写、重开表要先批准、shuffle 变成一项要运维的共享服务、那些省事的能力多半只在 Databricks 上成立。

Databricks 给开放目录下三条可核对的判据:存储归你、最好的功能在你的存储上生效、不复制就能搬走

事件概述

10 月 19 日,Databricks 发布《What makes a catalog open? Unity Catalog Advances the Open Lakehouse》,作者 Elizabeth Bowman。文章没有宣布新端点,而是给「开放目录」立了三条判据,再用同一张 Iceberg 表在不同平台上的遭遇做对照。

需要说明的是,这是 10 月 5 日《Unlocking Data Portability》那篇的后续:REGISTER 与 UNREGISTER 的协议细节、三步交接流程,以及「为什么必须先显式放弃而不是直接接管」的工程理由,本专栏在 Vol.85(10 月 6 日)已经展开过。本篇新增的是判据框架本身,以及把「开放」从一句营销表述变成可逐条核对的清单。两个端点目前仍是私有预览,需要联系客户团队开通。

三条判据分别是:表存放在客户自有的存储里,而不是托管在厂商的云账号里;自动优化与全部高级表特性在客户自有存储上也生效,而不是只给厂商控制的存储;表能靠 REGISTER 与 UNREGISTER 进出目录,数据文件原地不动。文章对每一条都给了「缺失会怎样」:桶在厂商账号下、存储费按厂商账单走、迁出还要为移动数据再付一次费;团队为了拿到特性把表搬进厂商存储,此后能做什么由厂商路线图决定;换目录意味着导出并重写每一张表。

技术解析

  • 「managed」在 Unity Catalog 里指谁维护,不是谁拥有:官方给出的数据是,99% 的 UC 托管表位于客户自有存储。文章点明,在围绕厂商控制存储构建的平台上,比例正好反过来,绝大多数表默认锁在专有格式里。差别在决定离开目录的那一天才显现。
  • 与 Snowflake 的三处对照:失效安全(fail-safe)恢复只对存放在自家存储里的表可用,UC 托管表在客户自有存储上仍支持恢复——30 天内可以查询历史版本或恢复被删的表;Snowflake 侧 compaction 在厂商控制存储上成本更高,而 UC 的 Predictive Optimization 对客户自有存储上的 Delta 与 Iceberg 托管表都跑;Snowflake 不清理客户桶里 Iceberg 表的孤儿文件(例如失败写入留下的文件),UC 侧由 Predictive Optimization 自动删除未被引用的文件。
  • 可移植性的实现路径:UNREGISTER 把表从 Unity Catalog 摘除并返回最新的 metadata 位置,也就是下一个目录接管提交所需的确切指针;REGISTER 在新目录里写一条把表名映射到该 metadata 的记录。文章强调这在厂商控制的存储上做不到——退出 API 交不出一个你带不走的指针。
  • 外部 Iceberg 表在 Databricks 里只读:因为提交权归另一个目录,两个目录写同一张表没有干净的协调方式。想让 UC 管理,就用 REGISTER 注册进 UC,或用 SET MANAGED 就地转成托管表。
  • 路线图与边界:官方计划支持 SET MANAGED IN PLACE,把外部表转成托管表而保留用户自己定义的存储路径,不搬数据。FAQ 里也明确,只用 Iceberg 格式本身不构成反锁定——放在厂商存储里的 Iceberg 表可以和专有表一样难搬,放在自有存储里的 Iceberg 表也可能只拿到打了折的功能集。
  • 客户侧的数字:Zepto 数据工程副总监 Abhinav Raghuvanshi 给出的引语是,UC 托管表的自动优化每年省下超过 100 万美元存储成本,并去掉了每天的手工维护。

行业影响

开放表格式解决的是引擎可换,REGISTER 与 UNREGISTER 解决的是治理层可换。这次加上判据之后,讨论从「格式是否开放」推进到「存储归谁、功能是否对齐、退出是否有 API」三件可验证的事,采购谈判里的技术尽调也因此有了可抄的清单。

代价同样清楚。判据是 Databricks 提的,对照物也是它选的,Snowflake 一侧的取舍(失效安全只在自有存储、不清理孤儿文件)由 Databricks 引用 Snowflake 文档给出,读者需要自行判断这些取舍在自家负载上的权重。而对已经在跑 UC 的组织来说,真正的迁移成本不在 API 调用上,Vol.85 已经写过:生产迁移仍要停写、改作业指向,split-brain 从理论风险变成操作风险。

相关链接


LanceDB 不再让表元数据自带信任:嵌入配置改由进程显式批准

事件概述

10 月 19 日,LanceDB 在 21:23 UTC 打出 v0.41.0-beta.9,同一天早些时候 Lance 格式仓库在 05:05 UTC 打出 v14.0.0-beta.21。LanceDB 这一版只有一条破坏性变更,但分量足够单独成题:嵌入函数的设置不再被表元数据说了算(#4550,wjones127,19:11 UTC 合入)。

问题的源头是重建路径。嵌入函数是从表元数据里重建的,而任何能写这张表的人都控制着这份元数据。sentence-transformers 的 trust_remote_code 默认为 True,于是打开并查询一张被精心构造过的表,就会执行模型仓库里的任意代码(PR 正文标注的编号是 GHSA-x8v2-vj73-gfwm)。同一条路径上还有第二类风险:元数据可以把 base_url 指向另一台服务器,把查询内容和环境变量里的 OPENAI_API_KEY 一起送过去。

修复方式是把信任从数据侧挪到代码侧。SentenceTransformerEmbeddings.trust_remote_code 默认值由 True 改为 False;从元数据恢复出的 trust_remote_code=True 与自定义端点(OpenAI base_url、Ollama host/proxy、watsonx url),只有在本进程明确批准过的情况下才生效,否则计算嵌入时抛 UntrustedEmbeddingConfigError。同一进程内创建的函数自动获批。

技术解析

  • 批准的接口:重开一张表之前先调 get_registry().allow_remote_code(model, revision=...) 或 get_registry().allow_endpoint(url)。信任按模型名记账,可选钉到某个 revision,批准一个模型不等于放行元数据里换成的另一个模型。
  • 未获批时表还能用:恢复出的未获批函数被一个占位对象替代,只有真正用到时才抛错,且不会构造真实函数(huggingface 在 __init__ 里就加载模型)。表上的非嵌入操作照常工作。这是这次设计里最实用的一点——安全检查不阻塞整张表的读写。
  • 报错信息给了修复动作:PR 里给出的输出形如 Embedding function 'sentence-transformers' was restored from table metadata with settings this process has not approved,并直接提示调用 allow_remote_code('attacker/model', revision=None)。
  • 覆盖面与缺口:sentence-transformers 与 huggingface 新增 revision 参数;自定义嵌入函数可通过覆写新的 remote_code_model() / endpoints() 钩子接入。PR 明确写出未覆盖三类:TypeScript(内置函数既无远程代码也无可配置端点)、Bedrock 的 assumed_role、未实现这两个钩子的第三方函数。
  • 同版还有两条修复:拒绝存储 schema 不支持的 blob 区间(#4566);把 StreamingDataset 的 raw_batches 队列按 io_queue_depth 收敛,避免无界堆积(#4530,westonpace)。
  • Lance v14.0.0-beta.21:新特性是 optimize_indices 的分布式执行(#9871,zhangyue19921010)。索引维护此前是单进程:一次调用在一台机器上扫描、训练、量化、写文件,表在持续写入时一旦跟不上写入速率,查询就退化为暴力扫描。新实现拆成 plan(driver)→ execute(worker)→ merge(worker)→ commit(driver)四阶段,每个工作单元由 plan 产出且是 JSON 可序列化的,worker 之间只传元数据、索引文件直写共享存储,引擎不必理解索引。新增 max_rows_per_task 与 max_rows_per_segment 两个参数,默认无界,行为与原单进程路径一致。另一条是全文索引暂存收尾按构建的内存配置定尺寸,并只上报一个进度阶段(#10141,LuQQiu)。

行业影响

这条变更把一个在 AI 数据栈里普遍存在的假设挑明了:表元数据是数据,不是代码,但它一直在承担「告诉程序去哪里执行什么」的职责。把嵌入函数定义随表持久化是很方便的设计——换台机器打开表就知道当初用什么模型算的向量——代价是打开一张表变成了一次带副作用的操作。LanceDB 的处理方式值得参考:不删掉便利,而是把信任变成一次显式调用,并把批准粒度设到模型名加 revision,让「批准过 A 模型」不能被用来放行 B 模型。

对已经在生产里用 LanceDB 存嵌入的团队,这是一条单向门:原本能直接重开并搜索的表,在新进程里会先抛错。升级前需要普查哪些模型用了远程代码、哪些端点是非默认的,并把批准调用补进初始化路径。Lance 侧的分布式索引维护则是另一条线的补位——写入早就引擎侧分布式了,索引维护是剩下那个单机瓶颈。

相关链接


LinkedIn 把 shuffle 从 executor 生命周期上剥离:Celeborn 全量落地,fetch 失败每天从 750 次降到 20 次

事件概述

Data Engineering Weekly 第 292 期(10 月 19 日发布)把 LinkedIn 的工程博文推到台前:《Scaling Spark and Flink Shuffle at LinkedIn with Apache Celeborn》,作者 Aravind Patnam,原文发表于 10 月 14 日。本专栏此前报道过 Celeborn 的视角是云厂商给出的架构方案(Vol.71,AWS EMR 上的远程 shuffle),这次是自有超大规模集群的全量落地报告,且所有数字都以自家上一代方案为基线。

LinkedIn 的起点数据是:每天 300,000 多个 Spark 作业、约 200 PB-hour 计算量、占集群利用率 98% 以上。上一代方案是 LinkedIn 自己设计并贡献进 Spark 3.2 的 Magnet(SPARK-30602)——map 端把 shuffle 块推给 merger ESS,按 reducer 分区合并成大文件,reducer 读合并后的文件而不是成千上万个小块。Celeborn 则把 shuffle 存储整体移出 executor 生命周期,交给独立 worker。

文章列出的三个迁移动因都很具体:shuffle 数据绑在产出它的计算节点上,节点故障、磁盘故障、executor 丢失与计划内维护都会导致 fetch 失败与昂贵的 stage 重算;ESS 与 NodeManager 共进程共宿主,重 shuffle 流量会争抢 CPU、内存、磁盘 I/O 与网络,反过来也会把 NodeManager 拖到 OOM;本地盘模型要求每个计算节点按峰值 shuffle 量配存储,而各负载的实际需求差异很大,文章给出的观察是 executor 运行时间中约 10-15% 空等在 shuffle 上。

技术解析

  • 控制面:五节点 Raft 组部署在相互独立的可用区,用 Apache Ratis 复制 worker 成员、应用注册与分区分配状态,支持透明的 leader 选举与故障切换。
  • 副本放置考虑网络拓扑:自定义的网络感知副本(CELEBORN-1313)让两个副本不落在同一次基础设施事件的影响范围内;计划维护期间强制一次只下线一个 AZ。worker 不可用时应用透明地读副本,不触发重算。
  • 中断感知的槽位选择:接入宿主机健康平台,把维护信号纳入放置决策(CELEBORN-2031)——即将进入维护的 worker 继续服务已有的 shuffle 读,但不再接收新分配。这一项带来的结果是任务失败降低 20 倍(以 Magnet 为基线)。
  • 介质与网络:Celeborn 的顺序 I/O 模型让 shuffle 存储从机械盘换到 NVMe SSD,shuffle 总时长降低 40%;worker 配 100 Gbps 网卡,让集群按算力而不是带宽来扩容。
  • 压缩:从默认 LZ4 换成 ZSTD 并提高压缩级别、加大缓冲区,写盘与网络传输量下降,所需 shuffle 集群规模减少约 35%。
  • 热点与 JVM:profiling 之后优化了槽位选择与 shuffle 文件刷写两条 CPU 密集路径,并调整 GC 与堆内外内存配比,槽位选择时间改善 6 倍。其中 CELEBORN-1982、CELEBORN-1106、CELEBORN-2160 已贡献回上游。
  • 安全与运维:应用级鉴权防止跨租户访问(CELEBORN-1011)、TLS 保护传输(CELEBORN-1343)、静态加密保护 worker 上的 shuffle 数据(CELEBORN-2329)、生产 CLI 提供集群与分区视图(CELEBORN-1572)、原生 IPv6 支持(CELEBORN-1513)。集群以 Kubernetes StatefulSet 加 Persistent Volume 部署。
  • 结果(均以 Magnet 为基线):计算成本降约 10%,应用运行时降约 14%;shuffle fetch 失败从每天约 750 次降到约 20 次;全集群单任务 shuffle 成本降近 90%;等待时间相对 executor 运行时的占比从峰值降 10-15%。
  • Flink 侧的收敛:关键管道回填持续支撑每小时数亿事件,多天的回填在个位数小时内完成;管道退役掉并行的 Spark 历史路径,改用统一的 Flink 计算路径处理近线与历史修正,消除重复实现与语义漂移;架构支撑成千上万个管道实例。
  • 下一步:探索在 Celeborn 内做数据缓存以复用、加快与上游 OSS 版本收敛以减少长期内部分叉的维护成本。

行业影响

这篇的价值不在「远程 shuffle 更快」,而在把 shuffle 做成一项有独立资源边界、有 SLO、有鉴权与加密、能滚动升级的共享服务之后,计算侧拿到了什么:大 shuffle 不再受单个计算节点磁盘容量约束,fetch 失败与 stage 重算从常态变成例外,动态分配与临时算力可以用得更激进,Spark 与 Flink 共用一套 shuffle 底座。

代价是运维对象的增加。独立 worker 集群要自己管容量、健康检查、副本放置、升级窗口和一套安全控制,LinkedIn 列出的增强项(网络感知副本、中断感知槽位、机群级异常检测、CLI、双栈网络)几乎全是上游没有或不够的部分。文章也直说他们长期维护着一个内部分叉,并把「更快与上游收敛」列为待办。对规模没到这一级别的团队,结论不是跟着上 Celeborn,而是先量一下自己的 fetch 失败率与空等占比——LinkedIn 给出的迁移前基线(每天数百次 fetch 失败、executor 运行时间一成左右空等)本身就是一份对照表。

相关链接


dbt 在 Databricks 上:增量、数据布局、表维护、编排与治理逐项交给平台

事件概述

同样在 10 月 19 日,Databricks 发布《How to get the most out of running dbt on Databricks》,作者 Srilekha Dornadula 与 Luís Cabral。文章不是版本发布,而是一份把运维负担从 dbt 项目移交给平台的清单,面向已经在 Databricks 上跑 dbt 的团队——官方给出的规模是超过 3000 家组织。

文章分成两段。第一段讲成本与性能:增量策略、物化视图、自动数据布局、查询标签。第二段讲简化:摄入、指标定义、编排、部署、治理。每节都配了具体配置项,落地路径清晰,对正在评估「dbt 项目里那些 post-hook 和配置是不是该留在项目里」的团队有直接参考价值。

技术解析

  • 六种增量策略的选择逻辑:append 用于只插入不更新;merge 用于同一键会多次到达(缓慢变化维、去重、迟到更新);replace_where 与 delete+insert 是 dbt-databricks 专有;insert_overwrite 用于查询返回整分区;microbatch 用于带 event_time 的时间序列与结构化回填。文章指出多数项目默认用 merge,而能用谓词描述变更数据范围时 replace_where 做的活更少——merge 必须扫目标表找匹配;做不到时用 incremental_predicates 收窄这次扫描。
  • 物化视图是原生物化类型:在 dbt-databricks 上把模型改成物化视图是一行配置,由 Databricks 追踪底层数据变化并只刷新受影响的结果。这是「让平台接管增量化」的一条路径,文章给的落点是服务层的聚合。TPC-DI 基准里,服务层从全量重算换成物化视图拿到 17 倍加速。
  • 数据布局不再手工调:Predictive Optimization 按表的查询方式自动决定何时跑 OPTIMIZE、VACUUM 与统计收集,可在 catalog 或 schema 级一次性开启,dbt 项目里为表维护积累的 post-hook 可以退役。Liquid Clustering 用自调优布局取代分区设计,避开过度分区的小文件爆炸,并能随查询模式漂移自适应;CLUSTER BY AUTO 由 Predictive Optimization 依据查询历史选键,一个项目级配置就能让项目建出的每张新表都带上聚类。Automatic upgrades 让 UC 托管表持续吃到后续发布的优化。
  • 成本归因到模型:dbt 在 Databricks 上执行的每条查询会被自动打上模型名、dbt 版本与物化类型,还可以追加自定义维度。标签出现在 system.query.history 里,与 system.billing.usage 关联后,serverless 仓的花费可以按模型、团队、域、物化类型分组。文章把这条定位成回答「季度末为什么账单涨了」的机制。
  • 摄入进 DAG:streaming_table 物化让摄入变成 DAG 里的另一个模型——增量拾取新到达的文件或事件,下游银层金层用 ref() 引用,测试与文档覆盖每一层,血缘从原始文件一直连到最终 mart。
  • 指标定义进仓库:metric view 在 dbt-databricks 上是原生物化类型,度量与维度只声明一次,消费方用 MEASURE() 在查询时自选分组,同一份定义服务 SQL 编辑器、BI 仪表盘、notebook 与 Genie。
  • 编排与部署:Lakeflow Jobs 把 dbt 作为原生任务收进一个 DAG,上下游任务由平台保障依赖,调度、自动重试、运行历史与告警内置;支持 dbt Core 与 dbt Platform,dbt Core v2.0 的支持在路上。Declarative Automation Bundles 把作业定义、调度、计算设置与 dbt 项目一起写成 YAML,--target dev 造出隔离的完整副本,--target prod 提升。按 cadence 给模型打标签、每个 cadence 一个作业,把模型从每日改每小时变成一行改动。
  • 治理写进项目:dbt_project.yml 里的 databricks_tags 驱动分类与策略,grants 控制读权限,row_filters 与 column_masks 控制可见范围;规模上用 ABAC 把策略挂在受管标签上,新建的带 pii 标签的模型在建成的那一刻就被策略覆盖,只有真正与模型绑定的逻辑(例如多租户隔离)才用逐模型过滤器。

行业影响

这份清单往前推一步就是:dbt 项目里剩下的应该是版本化、被 review、被测试覆盖的转换逻辑,其余的运维工作——增量判定、数据布局、表维护、编排、治理执行——都交出去。对成本侧的影响最直接的是查询标签那一条,它把「哪张模型贵」从季度末的争论变成一次 join。

代价是这些能力的具体形态都绑在 Databricks 上:replace_where 与 delete+insert 是 dbt-databricks 专有策略,物化视图、Predictive Optimization、Liquid Clustering、metric view、Lakeflow Jobs、DABs、ABAC 全是平台侧能力。把治理规则写进 dbt_project.yml 会让这套配置随项目一起迁移变得困难,也把 dbt 项目的语义从「转换定义」扩到了「访问策略」。对多引擎并存的团队,需要先把哪些块是平台锁定的划清楚再决定下沉多少。

相关链接


编者评

四条动态落在同一个动作上:把「默认由谁负责」重新指派,并要求指派之后留下可核对的凭据。目录这一层,凭据是 UNREGISTER 返回的那个 metadata 指针——信任不再基于「我们用的是开放格式」,而基于一次有返回值的交接。嵌入配置这一层,凭据是进程里那次 allow_remote_code 调用——表不再能自己授予自己信任。shuffle 这一层,凭据是独立 worker 上的副本与那个只允许一个 AZ 下线的约束——中间数据的可用性不再与 executor 生命周期绑在一起。dbt 这一层,凭据是 system.query.history 里那条自动打上的模型名标签——账单第一次能回答「是哪张模型花的」。

代价的结构也一致:每次指派都在某处多出一次必须显式做出的决定。迁移目录要停写并改作业指向;重开一张带嵌入的表要先批准模型与端点;换远程 shuffle 要多运维一个带鉴权、加密、副本放置与滚动升级的共享服务;把治理写进 dbt 项目之后,这套配置与 Databricks 的耦合会随代码一起长期存在。这些都不是缺陷,是交接本身的成本——此前它们由「约定」或「出事再修」承担,只是没人记账。

本期需要说明两件事。其一,Celeborn 那条的原文本是 10 月 14 日发表的,本专栏的覆盖窗口由 Data Engineering Weekly 第 292 期(10 月 19 日)把它推到台前而确定,数字与引语均取自 LinkedIn 原文而非二手转述。其二,中文厂商源继续没有可用条目:阿里云博客、阿里云开发者社区大数据页、火山引擎文档站与开发者社区四个入口均返回正常页面但检索不到 10 月 18 日至 20 日的新发布,这是连续第 17 期。国产开源侧本期唯一有实质更新的是 MatrixOne v4.1.6(10 月 20 日),一个与 Vol.97 报道的 4.2.6 平行的维护版本,只修两处原生内存泄漏:MergeOrder 在释放耗尽的内存输入批之前先释放其持有引用(#30633),UnionBatch 在原生内存增长被拒绝时保留变长缓冲区、只在增长成功后才发布新缓冲区(该所有权修正从 4.2-dev 反向移植,#28369)。发布说明里还写明该版本替换了先前的发布 commit,此前下载过 v4.1.6 的需重新拉取重建后的产物,且验证部分的最后一项写着「gpt-6.1-sol / xhigh 设计、整体评审与 QA 增量评审通过」——把模型评审写进发布流程的做法本身值得单列观察。

未进入正文但值得留档的:Databricks 同期还有《How HP Is Building an AI-Ready CDP with Databricks CustomerLake》(10 月 20 日)与《Databricks Is Doubling Down On New York City As A Premier AI Talent Hub》(10 月 19 日),前者是客户案例,后者是人才布局,均非技术发布;AWS 大数据博客 10 月 19 日那篇讲用 OpenSearch 追踪多智能体管道的安全威胁,与数据基建主线距离较远;Data Engineering Weekly 第 292 期里其余几篇——Datology 开源的 Zephon(把视图的虚拟与物化取舍搬进 AI 训练数据加载)、Netflix 把可观测性本体落在自建 RDF 四元组库 QuipuDB 上、eBay 用本地环形缓冲加异步 ClickHouse 富化做变现平台可观测——都属于工程实践,留待后续有配套一手材料时再展开。窗口内其余必扫仓库均无新版本:Trino 仍 484、Doris 仍 4.1.5、Pinot 仍 1.6.0 RC0、Hudi 仍 1.1.2、Paimon 仍 2.1.0、Iceberg 仍 1.12.0、Delta Lake 仍 4.4.1,DuckDB 博客最新仍为 10 月 16 日两篇(Vol.96 已报道),GCP 数据云周更汇总仍停在 October 12–16 那一期。