订阅更新

查询还能更快吗?——Z-Ordering和Clustering数据布局优化

数据湖手册 第 18 题 约 9 分钟读完

本文目录
  1. 先说结论
  2. 真实案例:Z-Ordering提升查询性能10倍
  3. Z-Ordering原理详解
  4. Clustering原理详解
  5. 数据跳过率监控
  6. Z-Ordering最佳实践
  7. 面试高频追问
  8. 实战踩坑:Z-Ordering选择不当
  9. 总结

先说结论

数据布局优化是什么:通过调整数据在文件中的排列方式,让查询时跳过不相关数据。包括Z-Ordering多维排序、Clustering聚类、Hilbert曲线等。

Z-Ordering:Delta Lake的多维排序技术,按多列同时排序数据。查询时可以同时跳过多列的数据,大幅减少扫描量。

Clustering:Apache Iceberg的数据聚类技术,按指定列的值范围聚簇数据。支持写入时自动聚类和手动聚类。

最佳实践:高频过滤的列用于Z-Ordering、定期重新Z-Ordering保持优化效果、组合Z-Ordering和分区、监控数据跳过率.

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

这道题面试官问得很多,因为数据布局优化是提升查询性能的高级技巧。我在某出海硬件品牌通过Z-Ordering将查询时间从20分钟降到2分钟。很多人只知道分区裁剪,但说不清楚数据布局优化。面试官想听的是你能说清楚原理和实战经验。

真实案例:Z-Ordering提升查询性能10倍

2023年在某知名出海硬件品牌,我们的用户行为查询非常慢。

-- 查询:某个用户在某个时间段的行为
SELECT * FROM user_behavior
WHERE user_id = 123456
  AND dt BETWEEN '2024-03-01' AND '2024-03-31'
  AND event_type IN ('click', 'view');

这个查询花了20分钟,业务部门无法接受。

问题:数据是随机排列的,即使按dt分区,查询仍需要扫描整个月的所有数据。user_id和event_type没有排序,无法跳过不相关数据。

解决方案:我们用Z-Ordering按user_id和event_type排序数据。

-- OPTIMIZE with Z-Ordering
OPTIMIZE user_behavior ZORDER BY (user_id, event_type);

改进效果:查询时间从20分钟降到2分钟,Z-Ordering跳过了90%的数据。

Z-Ordering原理详解

什么是Z-Ordering:Z-Ordering是一种多维排序技术,通过Z-order曲线将多维数据映射到一维空间。相邻的点在多维空间中也相近,查询时可以跳过大片不相关数据。

Z-Ordering vs 单列排序:单列排序只能按一列优化,Z-Ordering可以同时按多列优化。例如按user_id排序可以加速user_id查询,但Z-Ordering按(user_id, event_type)可以同时加速两列的查询。

数据跳过:Z-Ordering后,每个Parquet文件有min/max统计信息。查询时Spark可以跳过不包含目标值的文件。例如查询user_id=123,只需打开包含user_id=123的文件。

# Z-Ordering前后的数据分布
# Before: 随机排列
File1: user_id=[100,999,500,...], event_type=[view,click,view,...]
File2: user_id=[200,800,123,...], event_type=[click,view,click,...]
# 所有文件都需要扫描
 
# After: Z-Ordering by (user_id, event_type)
File1: user_id=[100-120], event_type=[click]
File2: user_id=[100-120], event_type=[view]
File3: user_id=[121-140], event_type=[click]
# 查询user_id=123 AND event_type=click只需要扫描File3

Z-Ordering代价:Z-Ordering需要重写数据,消耗IO和CPU。首次OPTIMIZE耗时较长,但后续查询性能大幅提升。建议在业务低峰期执行。

Clustering原理详解

什么是Clustering:Apache Iceberg的Clustering技术,按指定列的值范围将数据聚簇在一起。相同的值会在相同的文件中,查询时可以跳过不相关文件。

写入时Clustering:配置write.clustering.mode,写入时自动按指定列聚类。适合固定查询模式的场景。

-- 写入时Clustering
ALTER TABLE user_behavior
SET TBLPROPERTIES (
  'write.clustering.mode' = 'sorted',
  'write.clustering.sort-columns' = 'user_id,event_type'
);

手动Clustering:使用ALTER TABLE ... REWRITE DATA命令手动聚类已有数据。

-- 手动Clustering
ALTER TABLE user_behavior
REWRITE DATA USING CLUSTERING
SORTED BY (user_id, event_type);

Clustering vs Z-Ordering:Clustering是Iceberg的特性,Z-Ordering是Delta Lake的特性。原理相似但实现不同。Clustering更灵活,支持多种聚类策略。

数据跳过率监控

什么是数据跳过率:查询时跳过的数据量占总数据量的比例。跳过率越高,查询性能越好。可以通过Spark SQL的metrics查看。

-- 查看数据跳过率
df.explain()
-- 输出包含:
-- Statistics(sizeInBytes=10GB, rowCount=100M)
-- DataSkipping: number of predicates=3, skippedFiles=90/100

目标跳过率:对于点查询如user_id=123,跳过率应该达到95%以上。对于范围查询如dt BETWEEN ...,跳过率应该达到80%以上。如果跳过率低于50%,需要重新优化。

影响跳过率的因素:Z-Ordering列的选择、文件大小、数据分布。如果数据分布均匀,Z-Ordering效果更好。如果数据倾斜,跳过率会下降。

Z-Ordering最佳实践

实践说明示例
选择高基数的列低基数列效果差user_id而不是country
选择高频过滤的列WHERE条件中经常出现的列user_id, event_type, dt
限制列数量2-4列最佳(user_id, event_type)而不是(user_id, event_type, dt, country, status)
定期重新Z-Ordering新数据会破坏优化每周OPTIMIZE一次
配合分区使用分区+Z-Ordering效果更好dt分区+user_id Z-Ordering

面试高频追问

追问一:Z-Ordering和索引有什么区别?

Z-Ordering不是索引,是数据布局优化。索引需要额外的存储空间,Z-Ordering不需要。索引需要维护,Z-Ordering是写入时确定的。索引适合点查询,Z-Ordering适合范围查询。数据湖一般不用索引,用Z-Ordering就够了。

追问二:多久需要重新Z-Ordering?

根据写入频率决定。每天写入新数据的表建议每周OPTIMIZE一次。Z-Ordering只影响OPTIMIZE后的数据,新数据需要重新OPTIMIZE。监控数据跳过率,当下降到阈值以下时触发OPTIMIZE。

追问三:哪些列适合Z-Ordering?

高频过滤的列、高基数的列、组合查询的列。例如查询WHERE user_id=123 AND event_type='click',则user_id和event_type适合Z-Ordering。低基数列如country只有几个值,Z-Ordering效果不好,应该用分区。

实战踩坑:Z-Ordering选择不当

2023年在某出海硬件品牌,我们Z-Ordering选择了错误的列,导致性能反而下降。

我们对user_behavior表按country和status做Z-Ordering。

问题:country只有5个值,status只有3个值,都是低基数列。Z-Ordering后数据跳过率只有10%,查询反而更慢了。

原因:低基数列Z-Ordering效果差。每个文件都包含所有country和status值,无法有效跳过数据。

解决方案:我们改成按user_id和event_type做Z-Ordering,都是高基数列。

-- 错误:低基数列Z-Ordering
OPTIMIZE user_behavior ZORDER BY (country, status);
 
-- 正确:高基数列Z-Ordering
OPTIMIZE user_behavior ZORDER BY (user_id, event_type);

改进效果:数据跳过率从10%提升到95%,查询性能提升5倍。

总结

数据布局优化是提升查询性能的高级技巧。Z-Ordering是Delta Lake的多维排序技术,可以同时按多列优化数据布局。Clustering是Iceberg的聚类技术,功能类似。最佳实践是:选择高频过滤的高基数列、限制Z-Ordering列数量、定期重新OPTIMIZE、配合分区使用。监控数据跳过率,目标95%以上。面试时能说清楚Z-Ordering的原理、与索引的区别、最佳实践,就很稳.

下一篇聊一个运维必备话题:数据湖怎么监控?——关键指标和告警

你们生产环境用过Z-Ordering吗?效果如何?评论区聊聊~

关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长

刷题进度保存在当前浏览器