ディスクへのスピル
このトピックでは、大規模なオペレーターの中間計算結果をローカルディスクとオブジェクトストレージにスピルする方法について説明します。
概要
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 以降でサポート)
中間結果のスピルを有効にする
中間結果のスピルを有効にするには、次の手順に従います:
-
ローカルディスクにスピルされた中間結果を保存するローカルスピルディレクトリ
spill_local_storage_dir
を BE 設定ファイル be.conf または CN 設定ファイル cn.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
に設定されている場合にのみ有効です。
[プレビュー] 中間結果をオブジェクトストレージにスピル
v3.3.0 以降、StarRocks は中間結果をオブジェクトストレージにスピルすることをサポートしています。
オブジェクトストレージへのスピルを有効にする前に、使用したいオブジェクトストレージを定義するためのストレージボリュームを作成する必要があります。ストレージボリュームの作成に関する詳細な手順については、CREATE STORAGE VOLUME を参照してください。
前のステップでスピルを有効にした後、次のシステム変数を設定して、中間結果をオブジェクトストレージにスピルできるようにします:
SET enable_spill_to_remote_storage = true;
-- 使用したいストレージボリュームの名前で <storage_volume_name> を置き換えます。
SET spill_storage_volume = '<storage_volume_name>';
オブジェクトストレージへのスピルが有効になると、スピルをトリガーしたクエリの中間結果は、まず BE または CN ノードのローカルディスクに保存され、ローカルディスクの容量制限に達した場合にオブジェクトストレージに保存されます。
指定した spill_storage_volume
のストレージボリュームが存在しない場合、オブジェクトストレージへのスピルは有効になりませんのでご注意ください。
制限事項
- すべての OOM 問題がスピルによって解決されるわけではありません。たとえば、StarRocks は式評価に使用されるメモリを解放できません。
- 通常、スピルを伴うクエリはクエリ遅延が10倍に増加することを示します。これらのクエリのクエリタイムアウトをセッション変数
query_timeout
を設定して延長することをお勧めします。 - オブジェクトストレージへのスピルは、ローカルディスクへのスピルと比較して大幅なパフォーマンス低下があります。
- 各 BE または CN ノードの
spill_local_storage_dir
は、そのノードで実行されるすべてのクエリで共有されます。現在、StarRocks は各クエリごとにローカルディスクにスピルされたデータのサイズ制限を個別に設定することをサポートしていません。そのため、スピルを伴う同時クエリは互いに影響を与える可能性があります。