跳到主要内容
版本: 最新版本-3.5

溢写到磁盘

本文介绍如何将大型算子的中间计算结果溢出到本地磁盘和对象存储。

概述

对于依赖内存计算进行查询执行的数据库系统(如 StarRocks),在处理大数据集上的聚合、排序和连接算子的查询时,会消耗大量的内存资源。当达到内存限制时,这些查询会因内存不足 (OOM) 而被强制终止。

但是,您仍然可能希望某些内存密集型任务能够稳定完成,而性能不是您的首要考虑因素,例如构建物化视图,或使用 INSERT INTO SELECT 执行轻量级 ETL。这些任务很容易耗尽您的内存资源,从而阻塞集群中运行的其他查询。通常,要解决此问题,您只能单独微调这些任务,并依靠您的资源隔离策略来控制查询并发。在某些极端情况下,这可能特别不方便,并且很可能失败。

从 StarRocks v3.0.1 开始,StarRocks 支持将一些内存密集型算子的中间结果溢出到磁盘。借助此功能,您可以通过牺牲可容忍的性能下降来显着减少内存使用量,从而提高系统可用性。

目前,StarRocks 的溢出功能支持以下算子

  • 聚合算子
  • 排序算子
  • 哈希连接(LEFT JOIN、RIGHT JOIN、FULL JOIN、OUTER JOIN、SEMI JOIN 和 INNER JOIN)算子
  • CTE 算子(从 v3.3.4 开始支持)

启用中间结果溢出

按照以下步骤启用中间结果溢出

  1. 在 BE 配置文件 **be.conf** 或 CN 配置文件 **cn.conf** 中指定本地溢出目录 spill_local_storage_dir,该目录存储本地磁盘上溢出的中间结果,并重启集群以使修改生效。

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

    注意

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

    SET enable_spill = true;
  3. 使用会话变量 spill_mode 配置中间结果溢出的模式

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

    注意

    每次完成溢出的查询时,StarRocks 会自动清除查询产生的溢出数据。如果在清除数据之前 BE 崩溃,StarRocks 会在 BE 重新启动时清除数据。

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

[预览] 将中间结果溢出到对象存储

从 v3.3.0 开始,StarRocks 支持将中间结果溢出到对象存储。

提示

在启用溢出到对象存储之前,您必须创建一个存储卷来定义您要使用的对象存储。有关创建存储卷的详细说明,请参阅 CREATE STORAGE VOLUME

在您完成上一步启用溢出之后,您可以进一步设置这些系统变量,以允许将中间结果溢出到对象存储

SET enable_spill_to_remote_storage = true;

-- Replace <storage_volume_name> with the name of the storage volume which you want to use.
SET spill_storage_volume = '<storage_volume_name>';

启用溢出到对象存储后,触发溢出的查询的中间结果将首先存储在 BE 或 CN 节点的本地磁盘中,如果达到本地磁盘的容量限制,则存储在对象存储中。

请注意,如果您为 spill_storage_volume 指定的存储卷不存在,则不会启用溢出到对象存储。

局限性

  • 并非所有 OOM 问题都可以通过溢出来解决。例如,StarRocks 无法释放用于表达式计算的内存。
  • 通常,涉及溢出的查询的查询延迟会增加十倍。我们建议您通过设置会话变量 query_timeout 来延长这些查询的查询超时。
  • 与溢出到本地磁盘相比,溢出到对象存储的性能显着下降。
  • 每个 BE 或 CN 节点的 spill_local_storage_dir 在节点上运行的所有查询之间共享。目前,StarRocks 不支持单独为每个查询设置溢出数据到本地磁盘的大小限制。因此,涉及溢出的并发查询可能会相互影响。