Iceberg REST Catalog 加入 Read Restrictions 把行列级权限写进目录;七家 REST Catalog 实测暴露 11 项过度声明;Polars 2.0 RC1 把 SQL 默认引擎换成流式;阿里云 EMR Serverless Spark 多模态算子市场开公测
本期聚焦开放表格式向治理层与执行层两头延伸:Read Restrictions 让权限策略随表一起走,七家 REST Catalog 实测则量出规范承诺与实现之间的落差。
本期四条动态围绕同一个词的两面展开:可移植。Snowflake 把行列级权限塞进 Iceberg REST Catalog 的
loadTable响应,让策略跟着表走而不是跟着引擎走;一份 9 月 3 日的七家目录实测则量出了这份承诺的现实厚度——11 项端点过度声明、视图基本只有 Polaris 实现、Glue 用 HTTP 200 包裹未路由的操作;Polars 2.0 RC1 把 SQL 默认引擎换成流式,等于承认”内存装得下”不再能当默认假设;阿里云 EMR Serverless Spark 多模态算子市场开公测,把视频、图片、文本、音频的处理直接放进 Spark 与 Daft on Ray 的作业内部。前一条在规范里推进可移植,后三条在各自的层面上回答推进的代价落在哪里。
Iceberg REST Catalog 迎来 Read Restrictions:列脱敏与行过滤写进目录层
事件概述
2026 年 9 月 3 日,Snowflake 工程团队在官方博客宣布,由其提交并推动的 Read Restrictions 扩展已合并进 Apache Iceberg REST Catalog 规范。这个扩展要解决的问题很具体:一张 Iceberg 表可以被任意引擎读取,但挂在它上面的精细化访问控制(FGAC)策略却锁死在某一个引擎或平台里。在 A 系统写的策略,换到 B 引擎上读就不生效,结果要么策略被复制多份,要么引入一套与真正持有表的目录脱钩的第三方系统。
Read Restrictions 的做法是把 FGAC 直接搬进 REST Catalog 规范。客户端加载一张表时,拿到的不再只是表元数据,还附带一组按调用者身份定制的脱敏与过滤指令;管理员事先指定哪些引擎被信任去执行这些指令,策略留在目录里,判决随表走到负责执行的引擎上。
技术解析
- 两个新字段,都按调用者定制:
loadTable响应新增required-row-filter(读取方必须施加的行过滤谓词)与required-column-projections(需要按指定动作掩码的列清单)。二者都绑定到发起请求的 principal——同一张表对不同的调用者、或同一个调用者在不同时刻,可以返回不同的指令。 - 行过滤是 Iceberg 谓词,不是 SQL:
required-row-filter形如country = USA,可用=、`!=`、>、<、IN、NOT IN等原语。EXISTS/NOT EXISTS这类存在性检查只有在策略涉及的表规模可控时才能用这些原语表达,复杂 JOIN 目前仍无法表达。判定为 false 的行不得出现在结果里,由这些行派生出的任何信息也不得泄漏。 - 九种掩码,逐字节钉死:
mask-alphanum(数字变 n、其余变 x,保留( ) , . - @)、mask-to-fixed-value、replace-with-null、show-first-4、show-last-4、truncate-to-year、truncate-to-month、sha-256-global、sha-256-query-local。掩码语义被规定得足够精确,两个独立实现的引擎应产出完全一致的输出。例如4111-1111-1111-4444走show-last-4得到nnnn-nnnn-nnnn-4444;a.analyst@example.com走mask-alphanum得到x.xxxxxxx@xxxxxxx.xxx。 - 两种哈希掩码的取舍值得单独记:
sha-256-global是全局确定性的,同一输入恒得同一输出,脱敏后的列仍然可以 join;sha-256-query-local每次查询换一个随机盐,单次查询内一致、跨查询不可关联。选哪一个,取决于你还要不要在这列上做关联。 - 失败必须关闭(fail-closed):读取方若支持 read restrictions 却无法完整执行所收到的指令——遇到不认识的掩码、无法解析的表达式、不知道该怎么兑现的投影——必须让查询失败。不允许返回原始数据,不允许返回部分数据,也不允许返回空结果。对治理原语来说,静默是唯一不可接受的失败模式。
- 信任模型被刻意留在规范之外:目录可以用平台支持的任意语义定义策略,并自行决定把 read restrictions 发给谁;mTLS、on-behalf-of flow 等建立信任的手段属于目录与引擎之间的双边约定,规范不做定义。代价换来的是性能——因为访问控制由引擎直接执行,不需要额外产出一份”治理过的副本”,谓词下推照常工作。
- 已有端到端验证:规范 PR #16198 之外,还有 Iceberg Generics #16131、Spark #16082 的 E2E,Trino 侧的 E2E 文档,以及供服务端自检的 RCK #17809。
行业影响
这是开放表格式第一次尝试把”策略”也变成可移植对象。此前 Iceberg 让数据可移植(一个引擎写、任意引擎读),REST Catalog 让元数据可移植(一个目录、任意客户端),Read Restrictions 是同一动作作用在治理上。
它对平台团队的直接影响是可以少维护一套东西:不用再为每个引擎重写一遍列脱敏规则,也不用为了执行策略而复制一份数据。新出现的前提是”引擎必须被信任”——这个前提过去隐含在”我们只用自家的引擎”里,如今被写成了显式配置项,需要目录管理员逐个引擎去认证。Snowflake 也提示了高级引擎能提供 plan hiding、防谓词重排攻击等额外保证,意味着”能执行”和”执行得足够好”之间存在档次差异。
七家 Iceberg REST Catalog 实测:11 项过度声明、视图基本只有 Polaris、Glue 用 200 包裹未路由操作
事件概述
一位开发者(dev.to @gde,复现仓库 xbill9/lakehouse-iceberg-2026)于 2026 年 9 月 3 日对七家 Iceberg REST Catalog 做了一轮统一探针测量:Apache Polaris 1.7.0(开源对照组)、Databricks Unity、Snowflake Horizon、Google BigLake、Microsoft OneLake、AWS Glue、AWS S3 Tables。结论不是”谁家不支持 Iceberg”——七家都跑通了核心读取路径——而是”支持 Iceberg REST Catalog”这句话的信息量有多低。
技术解析
- 读写分开放榜:读探针 Polaris 15/16、Unity 12/14、Horizon 12/14、BigLake 11/14、OneLake 11/15、Glue 9/15、S3 Tables 9/15;写探针 Polaris 16/17、Unity 10/17、BigLake 10/14、Glue 与 S3 Tables 各 10/17、Horizon 7/14、OneLake 0/14(OneLake 官方即为只读)。
- 11 项 overclaim(声明了端点却不服务):OneLake 4 项(
create_namespace、create_table、commit_table、rename_table)、Horizon 4 项(list_views、create_view、update_namespace_props、commit_transaction)、Unity 2 项(plan_table_scan、update_namespace_props)、BigLake 1 项(load_credentials);Polaris 零项。Glue 与 S3 Tables 根本不发布 endpoints 列表,能力发现只能靠探测(该字段在规范中是可选的,不算违规)。 - Unity 的一个端点要求规范里不存在的字段:调用
update_namespace_props返回400 Malformed request: INVALID_PARAMETER_VALUE: Etag token version is missing,而 Iceberg 规范的UpdateProperties请求并没有 etag 字段——合规客户端无法调用它。 - 视图是 Polaris 独有的能力:规范的 6 个视图操作中,Polaris 全部实现;Glue 返回 406、S3 Tables 与 Unity 与 BigLake 返回 404、OneLake 返回 404/405、Horizon 即使使用
ACCOUNTADMIN也返回 403。Horizon 声明了 7 个视图端点,一个都不服务。作者用”命名空间中已存在真实原生视图”重测过,排除了空命名空间的假象。 - Glue 用 HTTP 200 伪装未路由的操作:三个探针返回
200 OK,body 里却是{"Output": {"__type": "com.amazon.coral.service#UnknownOperationException"}, "Version": "1.0"}。这是 AWS 协议层在回答一个前端根本不路由的操作,而不是端点返回了成功。只检查状态码的客户端会误以为这三个端点可用——而 Glue 的 config 里还声明了rest-table-scan-enabled: true,scan planning 正在被伪装成 200 的端点之列。 - commit 路径的深度被低估:
POST .../tables/{table}是单个端点,底下挂着 25 个不同的 update action,本次只测了 5 个。Polaris、Glue、S3 Tables、Unity、BigLake 全部接受;Horizon 接受set-properties与add-schema,拒绝remove-properties与set-current-schema(在 409 与 500 之间不确定地交替),并明确拒绝upgrade-format-version(Upgrading the Iceberg format version of an existing table is not allowed for Horizon accounts)。 - purge 语义各不相同:Polaris 需开启
DROP_WITH_PURGE_ENABLED才接受purgeRequested=true;Glue 直接拒绝(PurgeRequested cannot be true for Glue iceberg tables.);S3 Tables 反过来只支持带 purge 的 drop;BigLake、Unity、Horizon 接受 purge 形式删表。 - 路由前缀不是单一路径段:Polaris 是
quickstart_catalog,Glue 是catalogs/AWS_ACCOUNT_ID,Unity 是两段catalogs/workspace,BigLake 是四段,S3 Tables 是百分号编码的 ARN。客户端若把 prefix 当一段路径处理、或对其二次编码,会生成服务端无法路由的 URL——作者本人搭 harness 时踩过这两种坑。 - 一个反直觉的 null result:
loadTable响应中 30 个规范字段路径里,24 个在七家目录上完全相同;剩下 6 个差异中 1 个由 fixture 引起、2 个反映存储与凭证 vending 配置、2 个只是”无统计信息”渲染成空列表还是省略该 key。元数据保真度不是区分实现的地方,差异全在写入面与操作语义。
行业影响
对选型的人来说,这份测量的用处不在于排名,而在于把”声明”和”服务”拆开看。规范允许 endpoints 字段可选,于是厂商可以选择不声明(AWS 两家)或过度声明(另外四家共 11 项);只有开源对照组 Polaris 在这一点上完全诚实。
测量本身的局限也要一并读进去:单区域、单次、单一表形态;覆盖规范 35 个操作中的 25 个、25 个 update action 中的 5 个、8 个 table requirement 中的 1 个;Unity、Horizon、OneLake 三家都跑在试用层上,而 Horizon 的拒绝信息里直接写着 “not allowed for Horizon accounts”,产品层限制会混进结果。作者把这些都写进了 limitations,反而让前面那些数字更可信。
Polars 2.0.0-rc.1:SQL 默认引擎换成流式,Iceberg sink 复用原生元数据
事件概述
Polars 于 2026 年 9 月 1 日(UTC)打出 Python 侧 py-2.0.0-rc.1 预发布标签。这个 RC 的最大破坏性变更只有一条:SQL 接口的默认执行引擎从原引擎切换为流式引擎(#28973)。在这条变更之外,一批与 Iceberg 写入和查询优化相关的改动集中落地。
技术解析
- 默认引擎切换意味着什么:在此之前,大于内存的数据集走 SQL 路径需要手动开启流式执行。切换之后,SQL 路径默认就能处理超出内存的数据集——“内存装得下”不再是一个默认成立的假设。
- Iceberg 写入侧三条改动:复用 Iceberg sink 的原生元数据以提升写入性能(#29062);暴露 Iceberg sink 的 writer 选项(#29065);支持分区 Iceberg sink(#28823)。三条合起来,Polars 对 Iceberg 的接入从”能读”转向读写双向、且写入可配置。
- 查询侧的优化集中在新引擎的代价模型上:
EXISTS谓词下推到子查询之前(#29078);原始类型的 group-by 聚合收进单个 chunk(#28825);用代价信息决定是否保留缓存节点(#29042);采样耗尽时用 scan cardinality 决定 build side(#29040);新增 join reordering(#28985、#29038)。 - SQL 解析时机后移:把 SQL resolving 延迟到转换为 IR 时再做(#29077),配合多轮 SQL coverage 改进(#29010、#29006),SQL 这条路径上的优化空间被打开。
- 顺带一提:SQL 中暴露定长数组内积(#29033),这对向量检索场景是实用的小改动。
行业影响
单机 DataFrame 引擎把流式设为默认,是”数据集规模假设”的一次集体修正。Polars 的定位一直是”单机上跑得最快”,而流式引擎成为默认之后,这个”单机”的边界从”内存大小”变成了”内存 + 可溢出的执行计划”。
对 lakehouse 用户来说,Iceberg sink 那三条改动的分量更重:分区 sink 与 writer 选项暴露之后,Polars 不再只是湖仓里一个读得快的客户端,而是能按分区写出、写参数可调的生产端。这与本期第一条形成了有趣的对照——一个引擎在争取成为被目录信任的”读取执行方”,另一个引擎在补上”写入执行方”的资格。
阿里云 EMR Serverless Spark 多模态算子市场开公测:SparkSQL AI Function、Daft Local、Daft on Ray 三环境免费
事件概述
阿里云 EMR Serverless Spark 上线多模态算子市场并开启免费公测,公测期为 2026 年 8 月 31 日至 9 月 30 日,面向所有阿里云用户开放。产品提供开箱即用的算子,覆盖视频、图片、文本、音频四类场景的多模态数据处理。相关说明文档更新时间为 2026 年 9 月 1 日。
技术解析
- 免费范围限定在三种运行环境:SparkSQL AI Function、Daft Local、Daft on Ray。这三种环境下的算子调用在公测期内免费。
- 默认模型与 Token 计费:算子调用
qwen3.7-flash模型时不额外收取 Token 费用,该模型也是本次公测的默认模型。 - 公测期的两条限制:不保障 SLA(但服务不降级);需遵守数据安全规范、勿上传敏感数据。
- 公测结束后的计费口径:2026 年 9 月 30 日后转为正式商用,按实际使用量计费,计费项为计算资源 + 模型调用两部分;商业化开启后 SLA 立即生效;公测期间创建的任务与数据保留。
- 上手路径:在 EMR Serverless Spark 控制台进入 Spark 工作空间,创建 Notebook 并选择支持算子的引擎版本即可运行;官方给出的完整示例是视频抽帧 → 去黑边 → 大模型打标的处理链路。
行业影响
多模态处理进引擎这件事,价值不在”能调模型”,而在少一次数据往返。传统做法是 Spark 抽出数据、送到外部推理服务、再把结果写回,中间多一套服务要运维、多一次数据要搬。把算子放进 SparkSQL AI Function 与 Daft 之后,视频抽帧、去黑边、打标这类操作成为作业内部的一步。
值得单独留意的是 Daft on Ray 入选运行环境:Daft 本身就是面向多模态数据的分布式 DataFrame,Ray 提供执行后端。托管 Spark 产品把这条链路纳入官方支持,说明云厂商对多模态负载的执行后端判断已经不再默认绑定 Spark 自身。公测期不保障 SLA 这一点也提醒使用者:这条路径目前适合验证与批处理试点,还不适合放进有 SLA 承诺的生产链路。
编者评
把四条放在一起看,本期讲的是同一件事在四个层面的推进与一次自我校正。Snowflake 的 Read Restrictions 试图让权限策略随表流动,Polars 让超内存查询成为默认路径,阿里云把多模态算子塞进 Spark 与 Daft 作业内部——三者都在把原本属于”外围系统”的能力折叠进数据栈的核心层,减少数据搬运与策略复制。
那份七家目录的实测是这次推进的校正项。它量出的事实是:可移植性目前仍是被声明出来的,不是被保证出来的。11 项端点过度声明、视图只有 Polaris 真正实现、Glue 用 HTTP 200 包装未路由的操作、purge 语义各家不同——这些落差不会出现在任何一份兼容性矩阵里,只会在你把工作负载从一个目录迁到另一个目录的那天集中爆发。
Read Restrictions 的设计恰好可以被读成对这类落差的回应。它的 fail-closed 条款与”信任模型不在规范内”的声明,等于把”你打算信任哪个引擎”从一个隐含假设变成了必须显式作答的配置项。开放表格式走到 2026 年秋天,竞争的维度已经不是格式本身,而是谁能在规范里把信任、边界与失败模式写到足够精确——精确到两个独立实现能产出逐字节一致的结果。
相关链接
- A Step Toward Interoperable Governance(Snowflake 工程博客,2026-09-03)
- API: Add ReadRestrictions(apache/iceberg #16198)
- Seven Iceberg REST Catalogs: What They Declare, and What They Serve(实测,2026-09-03)
- 复现仓库 xbill9/lakehouse-iceberg-2026
- Python Polars 2.0.0-rc.1 发布说明
- Polars 官网
- EMR Serverless Spark 多模态算子市场免费公测说明(阿里云)