在大数据的世界里,优化查询性能至关重要。Delta Lake,一个开源的存储层,提供了两种主要的数据组织方法:动态聚类和Z序分区。这篇文章将帮助您在选择这两种方法时做出决定。
了解基础知识Delta Lake中的数据聚类根据经常访问的列来组织数据,从而提高查询速度,类似于关系数据库中的索引功能。简单来说,区别在于聚类会实际地排序表中的数据,而不会单独建立索引结构。
液体质点聚类与分区Z曲线表
液滴聚类流体聚类是一种较新的用于 Delta Lake 表的算法,具有多种优点。
- 灵活性:您可以随时调整聚簇列。
- 无需分区的表优化:无需分区即可正常工作。
- 效率:除非明确指示,否则不会重新聚类之前已聚类的文件。
液态聚集使用乐观并发控制(OCC)来解决同一张表中同时进行的多个写操作时的冲突。
分区 Z-顺序表(Z-order table)结合分区和Z顺序排列是一种传统的方法。
- 控制:可以更好地控制数据组织。
- 并行写入:更高效地支持并行写入。
- 细粒度优化:实现特定分区的优化。
不过,数据工程师们需要提前了解查询模式和习惯,从而选择合适的分区列。
决策树 考虑因素在决定是使用液体集群还是分区Z顺序索引表时,需要考虑以下因素。
表单大小- 小型表(< 10 GB):液态聚类通常足够。
- 中型表(10 GB–10 TB):两种方法都可以适用。
- 大型表(> 10 TB):分区并采用Z排序通常更被推荐。
如果你的表需要多个进程同时写入,特别是对于更新操作,建议使用分区。它可以更有效地管理并发写入和更新操作。追加操作则不太会引发担忧,因为多个写入者可以同时访问同一个表而不会产生冲突。
查询模式和示例- 一致使用分区列:非常有效。
- 灵活的集群:这样的查询模式可能更合适。
- 基于日期的数据:通常可以从分区中获益更多。
- 没有明确的分区策略时:可能更适合使用动态分组。
- 目标是分区值少于10,000个。
- 分区大小:每个分区应至少包含1 GB的数据,更多更好。
考虑一个使用亚马逊用户点击记录的场景,例如:
- 数据跨度:涵盖10个国家的3年数据。
- 按点击日期进行分区:结果大约产生1,000个分区。
- 总分区数:10,000(符合推荐数量范围)。
结构:
- 分区依据:click_date,country。
- Z-Order 顺序:merchant_id,advertiser_id。
对于分区表来说,每天为最新的分区执行优化任务,以确保良好的性能,特别是在日期范围的查询和Z排序列的查找方面。
OPTIMIZE table_name
WHERE click_date = 'ANY_DATE' AND country = '加拿大'
ZORDER BY (merchant_id, advertiser_id)
注意:流式表和分区表在优化方面有不同的能力。分区表在优化过程中可以利用WHERE子句,但这个功能仅限于分区列上的WHERE子句。相比之下,流式表根本不支持使用WHERE子句来进行优化。然而,这种区别并不必然使一种方法优于另一种。流式表的一个固有的优势在于,它们已经知道哪些数据需要聚簇,因此不需要通过WHERE子句来进行显式的筛选。
平行写入的考虑当你需要并行写入来自多个来源的数据,例如同时处理来自多个国家的数据时,分区变得尤为重要。
- 美国数据:来自美国的Kafka主题数据。
- 加拿大数据:来自加拿大的Kafka主题数据。
这两个流都需要实时并行地写入同一个表。分区让这些写入操作不会产生冲突,尤其是更新或合并操作时更是如此。
乐观并发控制Delta Lake 使用乐观并发控制来处理并行写入。
- 版本检查:作者检查当前 Delta 表的版本(例如,版本 100)。
- 尝试写入:他们试图写入一个新的 JSON 文件(例如,
101.json
)。 - 冲突解决:只有一个人能够成功创建这个文件。
- 冲突处理:失败的作者会检查与之前写入的内容是否存在冲突。
- 重试:如果没有冲突,他们将创建下一个版本(例如,
102.json
)。
这种方法在追加操作时效果很好,但在更新时可能会比较棘手,尤其是当多个写入者试图修改同一文件时。
潜在的坑和最佳做法这里有一些需要注意的要点和要避免的常见错误。
过度分割(将整体分成太多部分)创建过多的分区可能会导致开销。尽量不要让分区数量超过10,000。比如,按click_date
对三年的每日点击数据进行分区,会产生大约1,000个分区——这完全符合建议。
在选择分区列的时候,
- 选择不可变列:例如,
click_date
,sale_date
。 - 避免高基数列:例如像时间戳这样的列。
- 使用派生列:对于时间戳数据,可以创建一个用于分区的派生日期列。
避免在高基数列(如时间戳)上进行分区,这会导致分区过多,进而影响性能。相反,应该在日期列上进行分区,确保每个分区中有足够数据。
分区尺寸确保每个分区至少包含1GB的数据,以避免因小分区导致的性能问题。
时间安排调整定期执行 OPTIMIZE
命令。
- 分区表:确保新分区是集群化的并按照Z顺序排列,以实现高效的查询。包含
WHERE
子句这一点很重要,因为Z顺序算法有一个局限性:它无法对之前已集群化的文件进行重新集群。 - 流式集群表:定期执行
OPTIMIZE
。除非明确说明,否则它不会对之前已经集群化的文件进行重新集群。
除了使用Z序进行液体的聚类和分区之外,Databricks还提供了一个名为预测性I/O优化的功能。这个自动优化器利用机器学习来预测并优化根据查询模式的数据布局。
I/O预测优化的好处
- 自动化:消除手动优化任务的需求。
- 自适应学习:从查询负载中不断学习,以提升性能。
- 无缝集成:在后台运行,不影响现有的工作流程。
如果要融入您的策略: 如果有以下情况,预测I/O优化技术可能是个很好的选择:
- 你希望减少管理数据优化的操作负担。
- 你的查询模式复杂多变。
- 你正在寻找一个能够自动适应变化工作量的工具或服务。
如需更多详情,可以查看 Databricks 预测 I/O 优化文档.
结论选择流式聚类还是分区Z-Order表取决于多种因素,比如表的大小、写入方式和查询要求。
如果你需要以下情况,液体聚类是正确选择:
- 你的表是小到中等规模(小于10 TB)。
- 你的并发写入者较少,或者你需要一个更简单的方案。
- 用户并不总是使用分区列进行查询。
Z-Order排列更好,如果需要减少I/O操作:
- 你的表非常大(超过10太字节)。
- 你有多个并行写操作或复杂的写入需求。
- 用户经常通过分区列进行查询。
始终要考虑你的具体使用情况,并准备好测试这两种方式,以找到最适合你的数据和查询模式的方式。正确选择将显著提升你的查询性能和整体数据管理效率。
本文观点仅代表我个人意见,不代表 Databricks 的官方立场。
怎么办呢如果你正在寻找一种更简单的方式来优化你的Delta Lake表,而无需自己做出复杂的分区和聚集决策?Databricks的预测优化功能可能正是你需要的。这个智能系统会自动分析你的查询模式和数据特征,应用最适合的优化,从而节省你的时间和精力,提升性能。了解更多关于预测优化如何简化你的数据管理,请查看Databricks关于此强大功能的文档。不要让手动优化的复杂性阻碍了你前进的步伐——发现预测优化如何让你的Delta Lake性能更上一层楼,而你只需付出最小的努力。
让这篇帖子一直容易被找到:你的参与真的很重要哦!你的参与对我们来说非常重要!如果没有点赞、评论或分享,这篇有价值的内容可能会被淹没在这海量的信息中。像谷歌这样的搜索引擎会依靠用户的参与度来确定网页的相关性和重要性。如果你觉得这些信息有用,请花点时间点赞、评论或转发。你的支持不仅能让更多人发现这篇文章,也确保你将来需要时能再次找到它。不要让它在搜索结果中消失——用你的支持来保持优质内容的可访问性!
参考资料如下: