コンディションキャッシュ
Introduction
大規模な分析ワークロードにおいて、クエリはしばしば**繰り返しフィルタリング条件(Conditions)**を含みます。例えば:
SELECT * FROM orders WHERE region = 'ASIA';
SELECT count(*) FROM orders WHERE region = 'ASIA';
このようなクエリは、同一のデータセグメントに対して同じフィルタリングロジックを繰り返し実行するため、冗長なCPUとI/Oオーバーヘッドを引き起こします。
これを解決するため、Apache DorisはCondition Cacheメカニズムを導入しています。 特定の条件による特定のセグメントでのフィルタリング結果をキャッシュし、後続のクエリがそれらの結果を直接再利用できるようにすることで、不要なスキャンとフィルタリング処理を削減し、クエリレイテンシを大幅に低減します。
動作原理
Condition Cacheの核となる概念は以下の通りです:
- 同じフィルタリング条件は、同じデータセグメントで同じ結果を生成する。
- Dorisは「条件式 + キー範囲」の組み合わせから64bitダイジェストを生成し、これが一意のキャッシュ識別子として機能します。
- 各セグメントは、このダイジェストを使用してキャッシュ内の既存のフィルタリング結果を検索できます。
キャッシュされた結果は、圧縮された**bitベクトル(std::vector<bool>)**として保存されます:
- 0は、その行範囲が条件を満たさず、直接スキップできることを示します;
- 1は、その範囲がマッチするデータを含む可能性があり、さらなるスキャンが必要であることを示します。
このメカニズムにより、Dorisは粗い粒度で無関係なデータブロックを迅速に除外し、必要な場合のみ細かい粒度でのフィルタリングを実行できます。
適用シナリオ
Condition Cacheは以下の場合に最も効果的です:
- 繰り返し条件:同一または類似のフィルタ条件が頻繁に使用される。
- 比較的安定したデータ:セグメント内のデータは通常不変である(INSERT/Compaction後に新しいセグメントが生成され、古いキャッシュは自然に無効化される)。
- 高い選択性:フィルタが少数の行のサブセットのみを残す場合、スキャン削減効果が最大化される。
以下の状況では、Condition Cacheは使用されません:
- delete predicatesを含むクエリ(正確性を保証するため、キャッシュは無効になります)。
- 実行時に生成されるTopN runtime filters(現在はサポートされていません)。
設定と管理
有効化または無効化
SET enable_condition_cache = true;
Memory Management
- Condition CacheはLRU policyを使用してキャッシュの削除を行います。
condition_cache_limitを超えた場合、最も最近使用されていないエントリが自動的にクリアされます。
be.confでメモリ制限を変更できます:
condition_cache_limit = 1024 # Unit: MB
- セグメント圧縮後、古いキャッシュエントリはLRU削除によって自然に無効化されます。
キャッシュ統計
DorisはCondition Cacheの効果を監視するためのユーザー向け包括的なメトリクスを提供します:
- プロファイルレベルメトリクス(クエリ実行計画で表示)
ConditionCacheSegmentHit: キャッシュにヒットしたセグメント数ConditionCacheFilteredRows: キャッシュされた結果によって直接スキップされた行数
- システムメトリクス(監視システムまたは
/metrics経由で表示可能)condition_cache_search_count: 総キャッシュ検索回数condition_cache_hit_count: 成功したキャッシュヒット数
これらのメトリクスはキャッシュの効果とヒット率を評価するのに役立ちます。
使用例
典型的なシナリオ
以下のクエリを考えてみます:
SELECT order_id, amount
FROM orders
WHERE region = 'ASIA' AND order_date >= '2023-01-01';
- 初回実行: クエリはフルスキャンを実行してフィルタを評価し、Condition CacheがLRUキャッシュに結果を格納します。
- 後続の同一クエリ: キャッシュされた結果を再利用し、関連性のない行範囲の大部分をスキップして、潜在的な一致のみをスキャンします。
複数のクエリが同じフィルタリング条件(例: region = 'ASIA' AND order_date >= '2023-01-01')を共有する場合、それらは互いのCondition Cacheエントリを再利用でき、全体的なワークロードを削減します。
注釈
- キャッシュは永続化されません: Condition CacheはDorisの再起動時にクリアされます。
- 削除操作はキャッシュを無効化します: 削除マーカーを持つセグメントは厳密な整合性が必要なため、キャッシュを使用しません。
要約
Condition CacheはDorisにおける繰り返し条件クエリ向けに設計された最適化メカニズムです。その利点には以下があります:
- 冗長な計算を回避し、CPU/I/Oオーバーヘッドを削減
- ユーザーの介入なしに自動的かつ透過的に効果を発揮
- メモリ消費量が軽量で、ヒット率とフィルタ率が高い場合に非常に効率的
Condition Cacheを効果的に活用することで、ユーザーは高頻度OLAPクエリシナリオにおいて大幅に高速な応答時間を実現できます。