中间结果落盘
本文介绍如何将大算子的中间计算结果落盘 (Spill to disk)。
概述
对于依靠内存计算处理查询的数据库系统,例如 StarRocks,它们在大数据集上处理聚合、排序以及连接等运算时,会消耗大量内存资源。当达到内存限制时,这些查询将被强制终止。
但在某些场景下,您可能希望使用有限的内存资源稳定地完成某些任务,甚至愿意为此牺牲部分性能,例如,构建物化视图或使用 INSERT INTO SELECT 执行轻量级 ETL。这类任务会大量消耗内存资源,进而阻塞集群中运行的其他查询。通常,您需要通过手动调整参数解决这个问题,并且依靠集群资源隔离策略来控制查询并发。这种方式不仅较为不便,并且在极端情况下,可能依然会失败。
从 v3.0.1 开始,StarRocks 支持将一些大算子的中间结果落盘。 使用此功能,您可以在牺牲一部分性能的前提下,大幅降低大规模数据查询上的内存消耗,进而提高整个系统的可用性。
目前,StarRocks 支持将以下算子的中间结果落盘:
- 聚合算子
- 排序算子
- Hash join(LEFT JOIN、RIGHT JOIN、FULL JOIN、OUTER JOIN、SEMI JOIN 以及 INNER JOIN)算子
开启中间结果落盘
根据以下步骤开启中间结果落盘:
-
在 BE 配置文件 be.conf 中指定落盘路径
spill_local_storage_dir
,并重启集群使修改生效。spill_local_storage_dir=/<dir_1>[;/<dir_2>]
说明
- 您可以指定多个落盘路径
spill_local_storage_dir
,中间使用分号(;
)分隔。 - 在生产环境中,我们强烈建议您为数据存储和中间结果落盘使用不同的磁盘。当中间结果落盘时,写入负载和磁盘使用量可能会显著增加。如果使用相同的磁盘,这种激增会影响集群中运行的其他查询或任务。
- 您可以指定多个落盘路径
-
执行以下语句开启中间结果落盘:
SET enable_spill = true;
-
通过 Session 变量
spill_mode
设定中间结果落盘模式:SET spill_mode = { "auto" | "force" };
说明
每个涉及中间结果落盘的查询在完成后,StarRocks 会自动清除其产生的落盘数据。如果 BE 在清除数据之前崩溃导致数据残留,StarRocks 会在 BE 重新启动时清除落盘数据。
变量 默认值 描述 enable_spill false 是否启用中间结果落盘。如果将其设置为 true
,StarRocks 会将中间结果落盘,以减少在查询中处理聚合、排序或连接算子时的内存使用量。spill_mode auto 中间结果落盘的执行方式。有效值: auto
:达到内存使用阈值时,会自动触发落盘。force
:无论内存使用情况如何,StarRocks 都会强制落盘所有相关算子的中间结果。此变量仅在变量enable_spill
设置为true
时生效。
使用限制
- 中间结果落盘无法解决所有内存不足问题。例如,StarRocks 无法释放用于表达式计算的内存。
- 通常,涉及中间结果落盘的查询可能表明其查询时间有数量级的增长。建议您通过设置 Session 变量
query_timeout
适当延长这些查询的超时时间。