跳到主要内容
版本:3.2

中间结果落盘

本文介绍如何将大算子的中间计算结果落盘 (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)算子

开启中间结果落盘

根据以下步骤开启中间结果落盘:

  1. 在 BE 配置文件 be.conf 中指定落盘路径 spill_local_storage_dir,并重启集群使修改生效。

    spill_local_storage_dir=/<dir_1>[;/<dir_2>]

    说明

    • 您可以指定多个落盘路径 spill_local_storage_dir,中间使用分号(;)分隔。
    • 在生产环境中,我们强烈建议您为数据存储和中间结果落盘使用不同的磁盘。当中间结果落盘时,写入负载和磁盘使用量可能会显著增加。如果使用相同的磁盘,这种激增会影响集群中运行的其他查询或任务。
  2. 执行以下语句开启中间结果落盘:

    SET enable_spill = true;
  3. 通过 Session 变量 spill_mode 设定中间结果落盘模式:

    SET spill_mode = { "auto" | "force" };

    说明

    每个涉及中间结果落盘的查询在完成后,StarRocks 会自动清除其产生的落盘数据。如果 BE 在清除数据之前崩溃导致数据残留,StarRocks 会在 BE 重新启动时清除落盘数据。

    变量默认值描述
    enable_spillfalse是否启用中间结果落盘。如果将其设置为 true,StarRocks 会将中间结果落盘,以减少在查询中处理聚合、排序或连接算子时的内存使用量。
    spill_modeauto中间结果落盘的执行方式。有效值:auto:达到内存使用阈值时,会自动触发落盘。force:无论内存使用情况如何,StarRocks 都会强制落盘所有相关算子的中间结果。此变量仅在变量 enable_spill 设置为 true 时生效。

使用限制

  • 中间结果落盘无法解决所有内存不足问题。例如,StarRocks 无法释放用于表达式计算的内存。
  • 通常,涉及中间结果落盘的查询可能表明其查询时间有数量级的增长。建议您通过设置 Session 变量 query_timeout 适当延长这些查询的超时时间。