ディスクへのスピル
このトピックでは、大規模なオペレーターの中間計算結果をディスクにスピルする方法について説明します。
概要
StarRocks のようにクエリ実行にインメモリ計算を依存するデータベースシステムは、大規模なデータセットで集計、ソート、ジョインオペレーターを処理する際に多くのメモリリソースを消費します。メモリ制限に達すると、これらのクエリはメモリ不足(OOM)により強制終了されます。
しかし、マテリアライズドビューの構築や INSERT INTO SELECT を使用した軽量な ETL の実行など、メモリ集約型のタスクを安定して完了させたい場合があります。これらのタスクは簡単にメモリリソースを使い果たし、クラスタ内で他のクエリをブロックする可能性があります。通常、この問題に対処するためには、これらのタスクを個別に微調整し、リソース分離戦略に依存してクエリの同時実行を制御する必要があります。これは特に不便であり、極端なシナリオでは失敗する可能性があります。
StarRocks v3.0.1 から、StarRocks は一部のメモリ集約型オペレーターの中間結果をディスクにスピルすることをサポートしています。この機能を使用すると、パフォーマンスの許容可能な低下と引き換えにメモリ使用量を大幅に削減し、システムの可用性を向上させることができます。
現在、StarRocks のスピル機能は以下のオペレーターをサポートしています:
- 集計オペレーター
- ソートオペレーター
- ハッシュジョイン(LEFT JOIN、RIGHT JOIN、FULL JOIN、OUTER JOIN、SEMI JOIN、INNER JOIN)オペレーター
中間結果のスピルを有効にする
中間結果のスピルを有効にするには、次の手順に従います:
-
スピルされた中間結果を保存するスピルディレクトリ
spill_local_storage_dir
を BE の設定ファイル be.conf に指定し、変更を有効にするためにクラスタを再起動します。spill_local_storage_dir=/<dir_1>[;/<dir_2>]
注意
- 複数の
spill_local_storage_dir
をセミコロン(;
)で区切って指定できます。 - 本番環境では、データストレージとスピルに異なるディスクを使用することを強くお勧めします。中間結果がディスクにスピルされると、書き込み負荷とディスク使用量が大幅に増加する可能性があります。同じディスクを使用すると、この急増がクラスタ内で実行中の他のクエリやタスクに影響を与える可能性があります。
- 複数の
-
次のステートメントを実行して中間結果のスピルを有効にします:
SET enable_spill = true;
-
セッション変数
spill_mode
を使用して中間結果のスピルのモードを設定します:SET spill_mode = { "auto" | "force" };
注意
スピルを伴うクエリが完了するたびに、StarRocks はクエリが生成したスピルデータを自動的にクリアします。BE がデータをクリアする前にクラッシュした場合、StarRocks は BE が再起動したときにそれをクリアします。
変数 デフォルト 説明 enable_spill false 中間結果のスピルを有効にするかどうか。 true
に設定されている場合、StarRocks はクエリ内の集計、ソート、またはジョインオペレーターを処理する際にメモリ使用量を削減するために中間結果をディスクにスピルします。spill_mode auto 中間結果のスピルの実行モード。有効な値: auto
: メモリ使用量のしきい値に達したときに自動的にスピルがトリガーされます。force
: メモリ使用量に関係なく、関連するすべてのオペレーターに対して強制的にスピルを実行します。
enable_spill
がtrue
に設定されている場合にのみ有効です。
制限事項
- すべての OOM 問題がスピルによって解決されるわけではありません。たとえば、StarRocks は式評価に使用されるメモリを解放できません。
- 通常、スピルを伴うクエリはクエリの遅延が10倍に増加することを示します。これらのクエリのためにセッション変数
query_timeout
を設定してクエリのタイムアウトを延長することをお勧めします。