ファイルキャッシュ内部構造
基本概念
(1) キャッシュスライシングとプリフェッチメカニズム
Dorisは、データキャッシュ管理と読み取り効率を最適化するために、キャッシュスライシングとプリフェッチメカニズムを採用しています。具体的には、対象ファイルを1MBアライメントでスライシングし、各スライスは完全にダウンロードされた後、ローカルファイルシステムに独立したBlockファイルとして保存されます。このスライシング方式により、キャッシュの粒度を効果的に削減し、キャッシュの柔軟性と容量利用率を向上させます。Dorisは必要なデータ部分のみをキャッシュでき、大容量ファイル全体をキャッシュすることによる容量の無駄を回避します。より小さなキャッシュブロックは管理と削除も容易にし、より精密なホットスポットデータアクセスを可能にします。
(2) ローカルファイルディレクトリ構成
キャッシュデータをより適切に管理するため、Dorisは特定のローカルファイルディレクトリ構造を採用しています。キャッシュは複数のディスクの複数のディレクトリに分散される場合があります。ディレクトリ間での均等な分散を実現するため、Dorisは対象ファイルパスからハッシュ値を計算し、このハッシュをBlockファイル保存の最下位レベルディレクトリとして使用します。各Blockファイルは、対象ファイル内でのオフセット位置に基づいて命名されます。
例えば、対象ファイルパスが/remote/data/datafile1で、ハッシュ値が12345の場合、キャッシュされたBlockファイルは/cache/123/12345/offset1に保存される可能性があります。ここでoffset1は元ファイル内のブロックのオフセット位置を表します。
(3) マルチキューメカニズム
Dorisのファイルキャッシュは、マルチキューメカニズムを使用して異なるデータタイプを分離し、キャッシュ汚染を防止してヒット率を向上させます。キャッシュデータは以下のタイプに分類され、それぞれが重要度に応じて優先順位付けされた別々のキューに保存されます:
- TTL Queue:TTL(Time-To-Live)属性を持つデータを保存します。このデータは指定されたTTL期間中キャッシュに残り、その期間中は最高の優先度を持ちます。キャッシュ容量が不足した場合、システムはTTLデータを保護するため、他のキューからデータを優先的に削除します。TTLはテーブル属性です。例えば、3600に設定すると、このテーブルにインポートされたデータはインポート後1時間ファイルキャッシュに残るべきことを意味します。使用例:長いTTL値を持つ常駐テーブルなど、ローカル永続化が必要な小規模テーブルに適しています。
- Index Queue:主にクエリフィルタリング操作を高速化するために使用されるインデックスデータを保存し、通常は高いアクセス頻度を持ちます。注意:転置インデックスファイルは「インデックス」でありながら、通常サイズが大きいため、通常のキャッシュデータとして扱われます。
- Normal Queue:TTL属性を持たない通常データを保存します。ほとんどのデータがこのカテゴリに該当します。
- Disposable Queue:コンパクション読み取りなどの一時的なデータを保存します。このデータは通常使用後に削除され、最低の優先度を持ちます。
このマルチキューメカニズムにより、Dorisは異なるデータ特性と使用シナリオに基づいてキャッシュ容量を合理的に割り当て、キャッシュリソースの利用率を最大化できます。
(4) 削除メカニズム
キャッシュ削除メカニズムは、ファイルキャッシュ管理において重要であり、容量が制限されている場合にどのデータを削除対象として選択するかを決定します。Dorisの削除メカニズムには以下のトリガーと選択戦略が含まれます:
削除トリガー:
- 容量制約による受動的削除:
- ローカルディスク容量またはinode数が不足した場合、Dorisは受動的削除をトリガーして容量を解放します。
- キャッシュ容量制限に達した場合:ディスク容量が残っていても、キャッシュ使用量が事前定義されたしきい値に達すると削除が開始されます。
- 能動的早期削除:新しいデータが古いデータの削除を待つ必要がある同期削除とは異なり(クエリ性能に影響)、Dorisは使用量がハイウォーターマークに達した際に古いキャッシュを非同期でクリーンアップします。
- 能動的ガベージコレクション:LRUは未使用データを削除できますが、Dorisはコンパクション/Schema Change元データ、失敗したインポートロールバックデータ、削除されたテーブル/パーティションデータなどのガベージデータを積極的にクリーンアップします。
- TTL期限切れ:TTLデータに固有です。TTLが期限切れになると、データは通常キャッシュに降格され、通常の削除に参加します。
削除対象選択:
- 削除比率:キューは個別の比率制限でディスク容量を共有します。容量が豊富な場合(他のキューが比率に達していない)、キューは残り容量をすべて使用できます。例えば、通常キャッシュは総容量の40%に制限される可能性がありますが、他のデータが存在しない場合は利用可能な容量をすべて使用できます。他のキューデータが入ると、比率は徐々に事前設定値に近づきます。
- 削除順序:書き込みキャッシュ容量が不足した場合、Dorisは以下の順序でデータを削除します:Disposable → Normal → Index → TTL。他のキューデータを削除してもまだ十分な容量が解放されない場合、同じキュータイプ内でLRU削除が発生します。
削除回避の推奨事項:
- 十分なディスク容量:キャッシュデータを収容するのに十分な容量を確保し、容量制約による頻繁な削除を回避します。キャッシュクリーンアップには遅延があるため、ある程度のバッファを維持してください。経験上、ファイルキャッシュ容量は最適なヒット率を得るためにクエリホットデータサイズの約1.5倍であるべきです。
- 大規模クエリの分離:大規模クエリを別のクラスターにルーティングし、キャッシュ容量を占有して他のクエリのヒット率に影響することを防ぎます。
(5) ウォームアップメカニズム
キャッシュウォームアップは、後続のクエリを高速化するためにデータを事前にキャッシュにロードします。Dorisは複数のウォームアップアプローチを提供します:
- 手動ウォームアップ:ユーザーは特定のテーブル/パーティションの現在のクラスターキャッシュをウォームアップしたり、別のクラスターを参照してそのキャッシュされたテーブル/パーティションをウォームアップしたりできます。ウォームアップは常にリモートストレージからダウンロードします(他のクラスター/BEからではありません)。実行後、対象(テーブル/パーティションまたは参照クラスター)はBEダウンロード用のタブレットセットに変換されます。BEダウンロードロジックは、すべてのタブレットデータファイルの順次読み取りを実行してローカルにキャッシュすることが本質です。ウォームアップデータ量は大きくなる可能性があるため、Dorisはタスクを最大20GBのバッチに分割し、中断後の復旧用チェックポイントを設けます。BEが深刻な問題(クラッシュなど)に遭遇したり、ユーザーがウォームアップをキャンセルしたりすると、すべてのBEがダウンロードを停止します。ユーザーは
SHOW WARM UP JOBを介してジョブステータス(FINISHED、CANCELLED、RUNNING)を確認でき、実行中のジョブの進捗も含まれます。同じテーブル/パーティションの繰り返しウォームアップでは、既存データは再ダウンロードされず、増分更新のみが実行されます。 - ロードバランシングトリガーウォームアップ:タブレット分散が不均衡になった場合(特にノード障害やスケーリング時)、タブレットは新しいBEに移行します。対象BEは、ソースBE(利用可能な場合)のメタデータを使用してキャッシュデータをダウンロードし、新しいノードでのクエリキャッシュヒットを確保します。ソースBEキャッシュデータは、クリーンアップ中に積極的に削除されます。注意:移行と完全ダウンロードの間にタイムウィンドウがあり、キャッシュミスが発生する可能性があります。
- クロスクラスター自動ウォームアップ(v3.1+):コンピュート-ストレージ分離シナリオでは、ユーザーはコンピュートクラスター間の自動キャッシュ同期を望む場合があります(例:インポートはクラスターAで発生するが、クエリはクラスターBで実行)。Dorisは2つの自動同期方法を提供します:
- 定期的ウォームアップ:非リアルタイム要件の場合、
WARM UPSQLに同期間隔を追加します。1回限りの実行ではなく、タスクは定期的に指定されたテーブル/パーティションを一つのクラスターから別のクラスターに増分同期します。 - インポート/コンパクショントリガーウォームアップ:リアルタイム要件の場合、インポート完了イベントを使用してウォームアップをトリガーします。タブレットはクラスター間で異なって分散される可能性があるため、FEはソースクラスターに対象クラスタータブレット分散について通知します。ソースクラスターインポートコミットフェーズ中に、対象クラスターBEに新しくインポートされたリモートストレージデータのダウンロードを通知します。コンパクションもウォームアップ用の類似通知パスに従います。
- 定期的ウォームアップ:非リアルタイム要件の場合、
シナリオ分析
(1) クエリ処理におけるファイルキャッシュ
クエリ実行中、ファイルキャッシュはリモートストレージアクセスを削減し、データ取得を高速化します:
- Scannerによるデータファイル読み取り:クエリが到着すると、Scannerは必要なデータファイルの読み取りを試行します。
- ローカルキャッシュチェック:リモートストレージにアクセスする前に、Scannerは最初にローカルファイルキャッシュをチェックします。
- キャッシュヒット:キャッシュメタデータに要求されたファイルパスとオフセットが含まれている場合、ScannerがBlockFileハンドルを直接読み取るために返し、リモートダウンロードを回避して遅延を削減します。
- キャッシュミス:部分的または完全にキャッシュされていない範囲については、Scannerはリモートストレージから不足データをダウンロードします。ダウンロードされたデータは、削除ポリシーに従いながら、将来のクエリのためにファイルキャッシュに入ります。
(2) データロードにおけるファイルキャッシュ
インポート中、ファイルキャッシュは後続のクエリ用にデータを準備します:
- リモートストレージへのデータアップロード:インポートされたデータは最初にリモートストレージに移動します。
- 非同期ローカルキャッシュ書き込み:Dorisは非同期でこのデータをローカルディスクキャッシュに書き込み、インポート後のクエリで即座にキャッシュヒットを可能にします。
- キャッシュタイプ:データタイプと属性(TTLなど)に基づいて、インポートされたデータは対応するキュー(TTL、Index、またはNormal)に入ります。
(3) コンパクションにおけるファイルキャッシュ
コンパクションは、小さなファイルをマージすることでストレージとクエリ性能を最適化します。Dorisには2つのタイプがあります:
- Cumulative Compaction:増分データバージョンをマージ
- Base Compaction:ベースラインデータ(バージョン0)と増分バージョンをマージ
コンパクション中のキャッシュ処理:
- Cumulative Compaction:新しくマージされたデータは、リモートストレージアップロード後、インポートと同様にファイルキャッシュに入り、後続のクエリを高速化します。
- Base Compaction:Base Compactionは通常大きなコールドデータを含むため、新しいデータは容量が許可する場合のみキャッシュに入ります。ユーザーはBE config
enable_file_cache_keep_base_compaction_output = trueを介してキャッシュ挿入を強制できますが、これは他のホットデータを削除する可能性があります。将来のバージョンでは、履歴クエリ統計を使用してキャッシュ挿入を決定する適応戦略を計画しています。
(4) 再起動後のキャッシュロード
再起動後のキャッシュロードは、キャッシュ状態の復旧と迅速なクエリ応答にとって重要です。v3.1以前では、保存されていないLRU情報により、一貫性のないキュー順序が発生し、ヒット率に影響していました。
v3.1では、LRU永続化を導入:
- 定期的ダンプ:DorisはLRUキュー順序情報を定期的にディスクにダンプします。
- 再起動後のロード:ノードはダンプされたLRU情報を再ロードしてキュー状態を復元します。
- 全ディスクスキャン:定期的ダンプによる潜在的なメタデータ-ファイル不整合に対処するため、DorisはLRUロード後に全ディスクスキャンを実行して完全性を確保します。
- クエリトリガー非同期ロード:スキャンには時間がかかるため、BEはプロセス中にクエリを提供できます。クエリがスキャンされていないデータにアクセスする場合、遅延を最小化するために早期ロードが発生します。
(5) スケーリング中のキャッシュ処理
スケーリング操作は、クラスター管理において一般的です。Dorisはスケーリング中のファイルキャッシュを以下のように処理します:
- 水平スケールアウト:新しいBEへのタブレット移行中、対象BEはソースBEのメタデータを使用してキャッシュデータをダウンロードし、新しいノードでのキャッシュヒットを確保します。
- 水平スケールイン:スケールアウトと同様ですが、削減されたクラスターキャッシュ容量が実際のキャッシュサイズを下回る場合、標準メカニズムに従って削除が発生します。
- 垂直スケールアウト:
- ディスク追加:Dorisはディスク間でリハッシュやバランシングを行わないため、推奨されません。キャッシュディレクトリの変更により検索失敗が発生する可能性があります。必要な場合は、キャッシュをクリアして必要に応じてウォームアップしてください。
- ディスク容量増加:同じディスク数での容量拡張の場合、
curl http://BE_IP:WEB_PORT/api/file_cache?op=reset&capacity=123456を使用してBEに通知します。
- 垂直スケールイン:
- ディスク容量削減:
reset操作も必要です。新しい容量がキャッシュサイズを下回る場合、標準メカニズムに従って削除が発生します。
- ディスク容量削減:
- スケーリング後のウォームアップ注意事項:水平スケーリングにはタブレットリバランシングが含まれるため、効果的にするためにウォームアップ前に安定化を待ちます。
doris_fe_tablet_numメトリクスを監視し、カーブが安定した時点でウォームアップが完了します。