これは、 Apache Dorisのワークロード分離機能の詳細な紹介です。しかし、まず、ワークロード分離はなぜ、いつ必要なのでしょうか。次のいずれかの状況に当てはまる場合は、読み進めていただくと、最終的に解決策がわかります。
異なるビジネス部門またはテナントが同じクラスターを共有しており、ワークロードの干渉を防ぐ必要があります。
さまざまな優先度レベルのクエリ タスクがあり、リソースと実行の観点から、重要なタスク (リアルタイム データ分析やオンライン トランザクションなど) を優先したいと考えています。
ワークロードの分離が必要ですが、高いコスト効率とリソース使用率も求められます。
Apache Doris は、リソース タグとワークロード グループに基づくワークロード分離をサポートしています。リソース タグは、バックエンド ノードのレベルでさまざまなワークロードの CPU およびメモリ リソースを分離し、ワークロード グループ メカニズムは、バックエンド ノード内のリソースをさらに分割して、リソース使用率を高めることができます。
まず、Apache Doris のアーキテクチャから始めましょう。Doris には、フロントエンド (FE) とバックエンド (BE) の 2種類のノードがあります。FE ノードはメタデータを格納し、クラスターを管理し、ユーザー リクエストを処理し、クエリ プランを解析します。一方、BE ノードは計算とデータ ストレージを担当します。したがって、BE ノードは主要なリソース コンシューマーです。
リソース タグ ベースの分離ソリューションの主なアイデアは、クラスター内の BE ノードにタグを割り当てることでコンピューティング リソースをグループに分割することです。同じタグの BE ノードはリソース グループを構成します。リソース グループは、データ ストレージとコンピューティングの単位と見なすことができます。Doris に取り込まれたデータについては、システムは構成に従ってデータ レプリカを異なるリソース グループに書き込みます。クエリも、実行のために対応するリソース グループに割り当てられます。
たとえば、3 BE クラスターで読み取りワークロードと書き込みワークロードを分離する場合は、次の手順に従います。
BE ノードにリソース タグを割り当てます。2 つの BE を「読み取り」タグにバインドし、1 つの BE を「書き込み」タグにバインドします。
データ レプリカにリソース タグを割り当てます。テーブル 1 に 3 つのレプリカがあると仮定すると、そのうち 2 つを「読み取り」タグにバインドし、1 つを「書き込み」タグにバインドします。レプリカ 3 に書き込まれたデータはレプリカ 1 およびレプリカ 2 と同期され、データ同期プロセスでは BE 1 および BE2 のリソースがほとんど消費されません。
ワークロード グループをリソース タグに割り当てます。SQL に「読み取り」タグが含まれるクエリは、「読み取り」タグが付けられたノード (この場合は BE 1 と BE 2) に自動的にルーティングされます。データ書き込みタスクの場合は、対応するノード (BE 3) にルーティングできるように、「書き込み」タグを割り当てる必要もあります。このようにすると、レプリカ 3 からレプリカ 1 および 2 へのデータ同期オーバーヘッドを除き、読み取りワークロードと書き込みワークロードの間でリソースの競合は発生しません。
リソース タグは、Apache Doris でのマルチテナントも可能にします。たとえば、「ユーザー A」のタグが付けられたコンピューティング リソースとストレージ リソースはユーザー A 専用ですが、「ユーザー B」のタグが付けられたコンピューティング リソースとストレージ リソースはユーザー B 専用です。これは、Doris が BE 側でリソース タグを使用してマルチテナント リソース分離を実装する方法です。
BE ノードをグループに分割すると、高いレベルの分離が保証されます。
異なるテナントの CPU、メモリ、I/O は物理的に分離されています。
あるテナントが別のテナントの障害 (プロセス クラッシュなど) の影響を受けることはありません。
しかし、欠点もいくつかあります。
読み取り/書き込み分離では、データの書き込みが停止すると、「書き込み」タグが付けられた BE ノードがアイドル状態になります。これにより、クラスター全体の使用率が低下します。
マルチテナントでは、同じテナントの異なるワークロードをそれぞれに個別の BE ノードを割り当てることでさらに分離したい場合、多大なコストと低いリソース使用率に耐える必要があります。
テナントの数は、データ レプリカの数と関連しています。したがって、テナントが 5 つある場合は、データ レプリカも 5 つ必要になります。これは、ストレージの冗長性が非常に高いことを意味します。
これを改善するために、Apache Doris 2.0.0 ではワークロード グループに基づくワークロード分離ソリューションを提供し、 Apache Doris 2.1.0ではこれを強化しました。
ワークロード グループベースのソリューションは、より細分化されたリソース分割を実現します。さらに、BE ノードのプロセス内で CPU とメモリ リソースを分割するため、1 つの BE ノード内のクエリをある程度互いに分離できます。これにより、BE プロセス内でのリソースの競合が回避され、リソースの使用率が最適化されます。
ユーザーはクエリをワークロード グループに関連付けて、クエリが使用できる CPU およびメモリ リソースの割合を制限できます。クラスターの負荷が高い場合、Doris はワークロード グループ内で最もリソースを消費するクエリを自動的に強制終了できます。クラスターの負荷が低い場合、Doris は複数のワークロード グループでアイドル リソースを共有できます。
Doris は、CPU ソフト リミットと CPU ハード リミットの両方をサポートしています。ソフト リミットを使用すると、ワークロード グループはリミットを破ってアイドル リソースを活用できるため、より効率的にリソースを利用できます。ハード リミットは、ワークロード グループの相互影響を防ぐため、安定したパフォーマンスを厳密に保証します。
(CPU ソフト制限と CPU ハード制限は互いに矛盾しています。独自のユースケースに基づいてどちらかを選択できます。)
リソース タグ ベースのソリューションとの違いは次のとおりです。
ワークロード グループはプロセス内で形成されます。複数のワークロード グループが同じ BE ノード内のリソースを競合します。
ワークロード グループはリソース管理の手段にすぎないため、データ レプリカの配布は考慮されません。
CPU ソフト制限はcpu_share
パラメータによって実装されます。これは概念的には重みに似ています。cpu_share cpu_share
高いワークロード グループには、タイム スロット中により多くの CPU 時間が割り当てられます。
たとえば、グループ A のcpu_share
が 1 に設定され、グループ B の cpu_share が 9 に設定されているとします。10 秒のタイム スロットで、グループ A とグループ B の両方が完全にロードされている場合、グループ A とグループ B はそれぞれ 1 秒と 9 秒の CPU 時間を消費できます。
実際のケースでは、クラスター内のすべてのワークロードがフル稼働するわけではありません。ソフト制限では、グループ B のワークロードが低いかゼロの場合、グループ A は 10 秒の CPU 時間をすべて使用できるため、クラスター全体の CPU 使用率が向上します。
ソフト制限により柔軟性が高まり、リソース使用率が向上します。その反面、パフォーマンスの変動を引き起こす可能性があります。
Apache Doris 2.1.0 の CPU ハード制限は、安定したパフォーマンスを必要とするユーザー向けに設計されています。簡単に言えば、CPU ハード制限は、アイドル状態の CPU リソースがあるかどうかに関係なく、ワークロード グループがその制限を超える CPU リソースを使用できないことを定義します。
仕組みは以下のとおりです:
グループ A がcpu_hard_limit=10%
に設定され、グループ B がcpu_hard_limit=90%
に設定されているとします。グループ A とグループ B の両方がフル ロードで実行されている場合、グループ A とグループ B はそれぞれ全体の CPU 時間の 10% と 90% を使用します。違いは、グループ B のワークロードが減少するタイミングにあります。このような場合、グループ A のクエリ負荷がどれほど高くても、割り当てられた 10% を超える CPU リソースは使用しないはずです。
ソフト制限とは対照的に、ハード制限は柔軟性とリソース使用率の向上の可能性を犠牲にして、安定したシステム パフォーマンスを保証します。
BE ノードのメモリは次の部分で構成されます。
オペレーティング システム用に予約されたメモリ。
クエリ以外で消費されるメモリ。ワークロード グループのメモリ統計では考慮されません。
メモリは、データの書き込みを含むクエリによって消費されます。これは、ワークロード グループによって追跡および制御できます。
memory_limit
パラメータは、BE プロセス内のワークロード グループで使用可能な最大メモリ (%) を定義します。また、リソース グループの優先順位にも影響します。
初期状態では、優先度の高いリソース グループにより多くのメモリが割り当てられます。enable_memory_overcommit enable_memory_overcommit
設定すると、アイドル スペースがある場合にリソース グループが制限を超えるメモリを占有できるようにすることができます。メモリが不足している場合、Doris はタスクをキャンセルして、コミットしたメモリ リソースを再利用します。この場合、システムは優先度の高いリソース グループ用に可能な限り多くのメモリ リソースを保持します。
クラスターが処理できる以上の負荷を負っている場合があります。この場合、新しいクエリ要求を送信しても無駄になるだけでなく、進行中のクエリが中断されることになります。
これを改善するために、Apache Doris はクエリ キューメカニズムを提供します。ユーザーは、クラスター内で同時に実行できるクエリの数に制限を設定できます。クエリ キューがいっぱいになった場合、または待機タイムアウトが経過すると、クエリは拒否されるため、高負荷時のシステムの安定性が確保されます。
クエリ キュー メカニズムには、 max_concurrency
、 max_queue_size
、 queue_timeout
3 つのパラメーターが含まれます。
CPU ソフト制限とハード制限の有効性を実証するために、いくつかのテストを行いました。
環境: 単一マシン、16 コア、64GB
配置: FE 1 名 + BE 1 名
データセット: ClickBench、TPC-H
負荷テストツール: Apache JMeter
2 つのクライアントを起動し、それぞれワークロード グループを使用した場合と使用しない場合で、クエリを継続的に送信します (ClickBench Q23)。テスト結果に影響を与えないように、ページ キャッシュを無効にする必要があることに注意してください。
両方のテストで 2 つのクライアントのスループットを比較すると、次のことがわかります。
ワークロード グループを構成しないと、2 つのクライアントが CPU リソースを均等に消費します。
ワークロード グループを構成し、 cpu_share
2:1 に設定すると、2 つのクライアントのスループット比は 2:1 になります。 cpu_share
が高いほど、クライアント 1 に提供される CPU リソースの割合が高くなり、スループットが高くなります。
クライアントを起動し、ワークロード グループのcpu_hard_limit=50%
を設定し、同時実行レベルをそれぞれ 1、2、4 にして ClickBench Q23 を 5 分間実行します。
クエリの同時実行性が増すと、CPU 使用率は 800% 前後で推移し、8 つのコアが使用されることになります。16 コアのマシンでは50% の使用率となり、これは予想どおりです。また、CPU のハード制限が課せられているため、同時実行性が増すと TP99 レイテンシが増加するのもまた予想どおりの結果です。
実際の使用では、レイテンシはユーザー エクスペリエンスでより容易に認識できるため、ユーザーはクエリ スループットだけでなくクエリ レイテンシを特に懸念します。そのため、シミュレートされた運用環境でワークロード グループの有効性を検証することにしました。
単一テーブルの集計や結合クエリなど、1 秒以内に完了するクエリ (ClickBench Q15、Q17、Q23、TPC-H Q3、Q7、Q19) で構成される SQL セットを選択しました。TPC-H データセットのサイズは 100 GB です。
同様に、ワークロード グループを構成する場合と構成しない場合のテストも実行します。
結果は次の通りです:
ワークロード グループなし(テスト 1 と 2 の比較): クライアント 2 の同時実行性を高めると、両方のクライアントでクエリの待機時間が 2 ~ 3 倍に増加します。
ワークロード グループの構成(テスト 3 と 4 の比較): クライアント 2 の同時実行性が高まるにつれて、クライアント 1 のパフォーマンス変動が大幅に小さくなります。これは、ワークロードの分離によってクライアント 1 が効果的に保護されていることを示しています。
リソース タグ ベースのソリューションは、徹底したワークロード分離計画です。ワークロード グループ ベースのソリューションは、リソースの分離と使用率のより適切なバランスを実現し、安定性を保証するクエリ キュー メカニズムによって補完されます。
では、あなたのユースケースではどちらを選択すべきでしょうか? 私たちの推奨事項は次のとおりです:
リソース タグ: 部門の異なるビジネス ラインが同じクラスターを共有するユース ケースで、リソースとデータはテナントごとに物理的に分離されます。
ワークロード グループ: 柔軟なリソース割り当てのために 1 つのクラスターがさまざまなクエリ ワークロードを実行するユースケース向け。
今後のリリースでは、ワークロード グループとクエリ キュー機能のユーザー エクスペリエンスを継続的に改善していきます。
クエリをキャンセルしてメモリ領域を解放するのは、残酷な方法です。これをディスクスピルによって実装し、クエリパフォーマンスの安定性を高める予定です。
BE 内の非クエリによって消費されるメモリはワークロード グループのメモリ統計に含まれないため、ユーザーは BE プロセスのメモリ使用量とワークロード グループのメモリ使用量の間に不一致に気付く可能性があります。混乱を避けるために、この問題に対処する予定です。
クエリ キュー メカニズムでは、最大クエリ同時実行数を設定することでクラスター負荷が制御されます。BE でのリソースの可用性に基づいて、動的な最大クエリ同時実行数を有効にする予定です。これにより、クライアント側にバックプレッシャーが作成され、クライアントが高負荷を送信し続ける場合に Doris の可用性が向上します。
リソース タグの主なアイデアは BE ノードをグループ化することであり、ワークロード グループのアイデアは単一の BE ノードのリソースをさらに分割することです。これらのアイデアを理解するには、ユーザーはまず Doris の BE ノードの概念について学習する必要があります。ただし、運用の観点からは、ユーザーは各ワークロードのリソース消費率と、クラスター負荷が飽和したときにどの優先順位を設定するかを理解するだけで十分です。したがって、BE ノードの概念をブラック ボックスのままにするなど、ユーザーの学習曲線を平坦化する方法を見つけようとします。
Apache Doris でのワークロード分離に関するさらなるサポートについては、 Apache Doris コミュニティに参加してください。