ディスクへのスピル
このトピックでは、大規模なオペレーターの中間計算結果をローカルディスクとオブジェクトストレージにスピルする方法について説明します。
概要
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
: メモリ使用量に関係なく、関連するすべてのオペレーターに対して StarRocks が強制的にスピルを実行します。
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 は各クエリごとにローカルディスクへのスピルデータのサイズ制限を個別に設定することをサポートしていません。したがって、スピルを伴う同時クエリは互いに影響を与える可能性があります。