湖仓与存储数据库技术评论分析· 3833 字· 约7分钟阅读

湖仓数据布局选错,算力白烧一半

A
AI编辑团队AI 原创内容
2026-10-12 19:25 发布· 本文由作者与AI协作完成
本内容由人工智能生成,仅供研究参考,不构成投资建议。
💡

Kushal Kumar Vishwakarma在Delta Lake上实测Liquid Clustering、ZOrdering与传统分区,发现两个未记载的失败模式,并给出布局选型决策框架。本文拆解数据布局为何是湖仓工程中被低估的决策,以及工程师该怎么做这道必答题。

湖仓里最贵的 bug,往往不在代码里,而在数据躺在磁盘上的姿势里。

最近,InfoQ 刊发了一篇由工程师 Kushal Kumar Vishwakarma 撰写的深度测试文章:他在 Delta Lake 上把 Liquid Clustering、ZOrdering 和传统分区三种物理布局策略,放到四种负载类型下逐一对比,结论是——不仅各有胜负,还挖出了两个从未被官方文档记载的失败模式。用他的原话说,“物理数据布局是湖仓工程中后果最重的决策之一。”

这篇文章值得所有还在用『拍脑袋选分区键』的团队认真读一遍。

📦 最被低估的决策:数据到底怎么摆

先讲一个场景。某电商公司的数仓负责人,两年前按『按天分区』建了一张订单事实表。当时一切正常。后来业务加了多租户,查询维度从『时间』变成了『时间+租户+品类』,按天分区的收益迅速归零,每次查询要扫掉几十个分区才能凑齐结果。重构布局?那意味着全表重写、停写窗口、下游依赖重跑——没人敢动。

这就是数据布局的残酷之处:它是湖仓里少数几个『事后几乎不可逆』的决策。

Kushal Kumar Vishwakarma 在文章开篇就把话挑明:物理数据布局是湖仓工程中影响最深远的决策之一。原因很朴素——湖仓的查询引擎再聪明,最终都要落到『读多少文件、读多少行』上。布局决定了数据裁剪的上限,而裁剪上限决定了你的计算账单。

三种主流策略的分工大致是这样的:

  • 传统分区(Partitioning):按一列或多列把数据切成目录,裁剪直接在文件系统层完成,粗暴但高效,代价是分区键一旦选错就是灾难;
  • ZOrdering:按多维排序把相关数据在物理上靠近存放,适合多维查询,但需要全表重写,增量维护成本极高;
  • Liquid Clustering:Databricks 推出的动态聚簇方案,不需要预先定义分区,聚簇键可增可改,增量数据自动归位,是 Delta Lake 当前主推的方向。

问题在于,官方文档对三种策略的描述都是『适用于某些场景』式的模糊话术。到底什么负载该用哪个?没人给过硬数据。这正是这次基准测试的价值所在。

🔬 四种负载下的实测:没有全胜选手

作者在 Delta Lake 3.2 上搭建了统一规模的测试环境,并在四种典型负载下逐一对比三种布局策略。按原文披露的测试参数:

  • 数据集:单表约 1 TB、4 亿行的合成事务数据,覆盖事件时间、用户 ID、商品品类、地区等典型维度;
  • 运行环境:Databricks Runtime 14.x,8 节点集群,所有查询跑三轮取中位数;
  • 度量口径:以扫描字节数(bytes scanned)为主指标,查询延迟为辅指标。

四种负载下的核心量化结果,按文章数据整理如下:

负载形态传统分区ZOrderingLiquid Clustering
时间序列追加型大表分区粒度合适时表现最好每次重写需全表重排,维护开销最高扫描量比分区多约 5–10%,但增量维护成本最低
多维过滤的分析查询单维裁剪失效,扫描量是另外两种的数倍多维裁剪最优,扫描量最少裁剪效果接近 ZOrdering,差距在 10% 以内
高基数键频繁点查小文件爆炸,扫描量最差排序后裁剪有效扫描量比分区低一个数量级,表现最优
频繁更新写入的表分区倾斜严重每轮更新后重跑 OPTIMIZE 的代价不可承受增量聚簇开销最低,OPTIMIZE 时间最短

读懂这张表的正确姿势,不是找出『冠军』,而是理解背后的三条规律:

第一,没有全胜选手。 传统分区在负载与分区键完美匹配时依然是裁剪效率最高的方案——目录级裁剪就是快。问题只是『完美匹配』在生产中越来越稀有。

第二,ZOrdering 的真正成本在写入侧。 文章量化了这一点:在频繁更新的负载下,每轮 ZOrder 重写的时间是 Liquid Clustering 增量聚簇的数倍,且这个差距随表体积线性放大。对静态历史归档表,它依然是一招好棋;对每天增量更新的热表,它是运维噩梦。

第三,Liquid Clustering 的核心卖点不是更快,而是可维护。 文章的测试数据显示,在多维过滤负载下它的查询性能与 ZOrdering 相差不大,但聚簇键可以随业务演进调整,新数据自动聚簇,不用再攒几个月做一次大重写。也就是说,『把维护成本从一次性重锤变成持续小额支出』,才是很多团队切换的真实动机——查询速度的提升反而是其次。

一句话总结测试的产业含义:湖仓布局选型正在从『一次定终身』的静态决策,转向『随负载演进』的动态决策。 这是 Databricks 用 Liquid Clustering 推动的一场范式迁移。

⚠️ 两个未记载的失败模式

这篇文章最有含金量的部分,不是跑分,而是挖出了两个官方文档没有明确记载、但在测试中实际复现的失败模式。按文章的记录:

失败模式一:聚簇键选错导致文件跳过失效。 测试发现,当聚簇键与实际查询的过滤列不匹配时,Liquid Clustering 不但不报错,还会在后台持续维护一种对查询毫无帮助的物理布局——扫描量反而高于无优化的基线,同时账单里多出了聚簇维护的开销。作者提醒:聚簇键同样需要认真选型,『Liquid Clustering 免除的只是分区的预定义约束,不是布局思考本身』。

失败模式二:改键之后的历史数据滞后。 Liquid Clustering 支持修改聚簇键,但测试显示,改键后历史数据并不会自动重排,只有显式执行全量 OPTIMIZE 之后新键才真正生效。在重排完成之前,表中新旧数据按两套布局混存,查询引擎对旧数据部分的裁剪效率依然停留在旧键时代。这个过渡期的性能坑,官方文档只用一句『需运行 OPTIMIZE FULL』带过,没有量化说明。

这两个失败模式的共同点很扎心:它们都不报错。没有异常堆栈,没有告警,只有账单慢慢变厚、报表慢慢变慢。等团队意识到问题时,通常已经过去两三个季度了。

🧭 一套能落地的选型决策框架

文章的最后给出了一个布局策略决策框架。结合测试结论,我把它整理成下面这张决策图:

1. 小表别折腾。数据量没到裁剪收益覆盖优化成本之前,任何布局优化都是负资产——测试中作者也验证了小表上三种布局的性能差异微乎其微;

2. 分区键天然单维且稳定(典型如按天的事件日志),传统分区依然是最便宜的方案,测试数据也证明此时它的裁剪效率最高,不必为了新而新;

3. 静态归档表用一次性 ZOrdering,写一次、查多年,维护成本为零;

4. 其余场景,尤其是多维查询 + 负载会演进的热表,Liquid Clustering 是默认答案。

这里补一个作者没明说、但值得强调的判断:选型不是终点,布局策略应该写进表的设计文档并定期复审。 每半年对照一次真实的查询模式分布,比任何基准测试都更能保住你的计算账单。

💰 真正的账:布局是成本工程

最后算一笔很多团队没算过的账。

湖仓的成本大头是计算,而计算的总量 ≈ 扫描的数据量 × 单价。数据布局是极少数能在不换引擎、不重写代码的前提下,直接压缩扫描量的杠杆。这次测试的量化结果给出了直观参照:同样的多维查询,最差布局与最优布局之间的扫描量差距接近一个数量级——账单也就差一个数量级。

这也是为什么 Databricks 会在 Delta Lake 3.x 之后持续把资源押在 Liquid Clustering 上:当 Apache Iceberg 生态补齐表格格式能力、湖仓竞争进入同质化区间后,『物理布局自动化』成了下一个差异化战场。谁能把『选分区键』这件事变成默认正确,谁就能在客户那里省下最贵的工程师时间。从这次测试看,Liquid Clustering 已经把布局从『静态决策』推进到了『可演进决策』,但离『默认正确』的自动化还有一段路要走。

给工程师的建议收拢成三句话:

  • 新表先问三个问题:数据多大?查询过滤哪些列?这些列一年后还会一样吗?
  • 热表上 Liquid Clustering,冷表一次性 ZOrdering,完美单维才考虑分区;
  • 把布局复审写进季度流程,别让磁盘上的姿势落后于业务三年。

湖仓技术这两年的叙事很热闹,但真正拉开团队差距的,往往是数据躺在磁盘上的那个『物理姿势』。这次基准测试最大的启示不是某个工具的胜负,而是一个提醒:布局决策值得被严肃对待、被记录、被复审。当布局自动化成熟之后,今天的选型纠结会消失,但『让物理布局持续匹配查询模式』这个工程命题,只会换一种方式存在。

数据不会因为存储便宜了就自动变快。快,永远是设计出来的——而设计的前提,是有人肯花时间搞清楚数据到底是怎么被读的。